Upgraded streams.

This commit is contained in:
Andrew Lalis 2023-06-27 06:21:13 +02:00
parent b82bfae676
commit 175039a639
5 changed files with 56 additions and 14 deletions

View File

@ -7,6 +7,6 @@
"license": "MIT", "license": "MIT",
"name": "compiler", "name": "compiler",
"dependencies": { "dependencies": {
"streams": "~>3.4.3" "streams": "~>3.5.0"
} }
} }

View File

@ -1,6 +1,6 @@
{ {
"fileVersion": 1, "fileVersion": 1,
"versions": { "versions": {
"streams": "3.4.3" "streams": "3.5.0"
} }
} }

View File

@ -2,6 +2,7 @@ import std.stdio;
import std.string; import std.string;
import nimpc; import nimpc;
import streams; import streams;
import streams.types.mapping;
int main(string[] args) { int main(string[] args) {
if (args.length < 2) { if (args.length < 2) {
@ -12,7 +13,8 @@ int main(string[] args) {
writefln!"Compiling %s"(files); writefln!"Compiling %s"(files);
foreach (filename; files) { foreach (filename; files) {
auto sIn = FileInputStream(toStringz(filename)); auto sIn = FileInputStream(toStringz(filename));
auto tokens = tokenize(sIn); auto tokens = tokenize(mappingInputStreamFor!((ubyte b) => cast(char) b)(sIn));
writeln(tokens);
} }
return 0; return 0;
} }

View File

@ -4,6 +4,9 @@ import streams;
import std.stdio; import std.stdio;
import std.regex; import std.regex;
import std.array; import std.array;
import std.typecons;
import std.uni;
import std.string;
enum TokenType { enum TokenType {
KEYWORD, KEYWORD,
@ -12,10 +15,12 @@ enum TokenType {
LITERAL_INTEGER, LITERAL_INTEGER,
LITERAL_FLOAT, LITERAL_FLOAT,
LITERAL_BOOLEAN, LITERAL_BOOLEAN,
LITERAL_STRING LITERAL_STRING,
COMMENT_INLINE,
SYMBOL
} }
struct Token { immutable struct Token {
TokenType type; TokenType type;
string content; string content;
uint line; uint line;
@ -33,6 +38,12 @@ class LexerException : Exception {
} }
} }
class StreamEndException : Exception {
this() {
super("Stream ended.");
}
}
/** /**
* Parses a list of tokens from an input stream of lines of code. * Parses a list of tokens from an input stream of lines of code.
* Params: * Params:
@ -41,22 +52,51 @@ class LexerException : Exception {
*/ */
Token[] tokenize(S)(S inputStream) if (isInputStream!(S, char)) { Token[] tokenize(S)(S inputStream) if (isInputStream!(S, char)) {
Appender!(Token[]) tokenApp; Appender!(Token[]) tokenApp;
bool streamEnded = false;
uint line = 0; uint line = 0;
uint col = 0; uint col = 0;
try {
while (true) { while (true) {
// Trim whitespace from the start of each line.
char c = readChar(inputStream, line, col); char c = readChar(inputStream, line, col);
writeln(c); while (isWhite(c)) {
c = readChar(inputStream, line, col);
}
// Inline comment from here to newline.
if (c == '#') {
const commentStartCol = col;
c = readChar(inputStream, line, col);
char[] commentText;
while (c != '\n') {
commentText ~= c;
c = readChar(inputStream, line, col);
}
tokenApp ~= Token(
TokenType.COMMENT_INLINE,
strip(cast(string) commentText),
line,
commentStartCol
);
}
}
} catch (StreamEndException e) {
// This is expected!
} }
return tokenApp[]; return tokenApp[];
} }
private char readChar(S)(S stream, uint line, uint col) if (isInputStream!(S, char)) { private char readChar(S)(S stream, ref uint line, ref uint col) if (isInputStream!(S, char)) {
auto result = readOne(stream); char[1] buffer;
StreamResult result = stream.readFromStream(buffer);
if (result.hasError) { if (result.hasError) {
throw new LexerException("Failed to read one more char from stream.", line, col); throw new LexerException("Failed to read one more char from stream.", line, col);
} }
return result.element; if (result.count == 0) throw new StreamEndException();
col++;
if (buffer[0] == '\n') {
line++;
col = 0;
}
return buffer[0];
} }

View File

@ -3,7 +3,7 @@
define x as integer with value of 42. define x as integer with value of 42.
define b as boolean. define b as boolean. # another comment.
assign true to b. assign true to b.
define bString as string of b. define bString as string of b.