From 175039a63906ebbcc9dc18daba4cd9184f9faa8b Mon Sep 17 00:00:00 2001 From: Andrew Lalis Date: Tue, 27 Jun 2023 06:21:13 +0200 Subject: [PATCH] Upgraded streams. --- compiler/dub.json | 2 +- compiler/dub.selections.json | 2 +- compiler/source/app.d | 4 ++- compiler/source/nimpc/lexer.d | 60 +++++++++++++++++++++++++++++------ examples/variables.nimp | 2 +- 5 files changed, 56 insertions(+), 14 deletions(-) diff --git a/compiler/dub.json b/compiler/dub.json index 8e5c6ab..2459e50 100644 --- a/compiler/dub.json +++ b/compiler/dub.json @@ -7,6 +7,6 @@ "license": "MIT", "name": "compiler", "dependencies": { - "streams": "~>3.4.3" + "streams": "~>3.5.0" } } \ No newline at end of file diff --git a/compiler/dub.selections.json b/compiler/dub.selections.json index 163bdbb..88fd59c 100644 --- a/compiler/dub.selections.json +++ b/compiler/dub.selections.json @@ -1,6 +1,6 @@ { "fileVersion": 1, "versions": { - "streams": "3.4.3" + "streams": "3.5.0" } } diff --git a/compiler/source/app.d b/compiler/source/app.d index 9256711..15ef846 100644 --- a/compiler/source/app.d +++ b/compiler/source/app.d @@ -2,6 +2,7 @@ import std.stdio; import std.string; import nimpc; import streams; +import streams.types.mapping; int main(string[] args) { if (args.length < 2) { @@ -12,7 +13,8 @@ int main(string[] args) { writefln!"Compiling %s"(files); foreach (filename; files) { auto sIn = FileInputStream(toStringz(filename)); - auto tokens = tokenize(sIn); + auto tokens = tokenize(mappingInputStreamFor!((ubyte b) => cast(char) b)(sIn)); + writeln(tokens); } return 0; } diff --git a/compiler/source/nimpc/lexer.d b/compiler/source/nimpc/lexer.d index 18f279a..2c0dcec 100644 --- a/compiler/source/nimpc/lexer.d +++ b/compiler/source/nimpc/lexer.d @@ -4,6 +4,9 @@ import streams; import std.stdio; import std.regex; import std.array; +import std.typecons; +import std.uni; +import std.string; enum TokenType { KEYWORD, @@ -12,10 +15,12 @@ enum TokenType { LITERAL_INTEGER, LITERAL_FLOAT, LITERAL_BOOLEAN, - LITERAL_STRING + LITERAL_STRING, + COMMENT_INLINE, + SYMBOL } -struct Token { +immutable struct Token { TokenType type; string content; 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. * Params: @@ -41,22 +52,51 @@ class LexerException : Exception { */ Token[] tokenize(S)(S inputStream) if (isInputStream!(S, char)) { Appender!(Token[]) tokenApp; + bool streamEnded = false; uint line = 0; uint col = 0; - while (true) { - char c = readChar(inputStream, line, col); - writeln(c); + try { + while (true) { + // Trim whitespace from the start of each line. + char c = readChar(inputStream, line, col); + 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[]; } -private char readChar(S)(S stream, uint line, uint col) if (isInputStream!(S, char)) { - auto result = readOne(stream); +private char readChar(S)(S stream, ref uint line, ref uint col) if (isInputStream!(S, char)) { + char[1] buffer; + StreamResult result = stream.readFromStream(buffer); if (result.hasError) { 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]; } diff --git a/examples/variables.nimp b/examples/variables.nimp index 3b62cf1..ed4fd65 100644 --- a/examples/variables.nimp +++ b/examples/variables.nimp @@ -3,7 +3,7 @@ define x as integer with value of 42. -define b as boolean. +define b as boolean. # another comment. assign true to b. define bString as string of b.