From 0881924c652105ebca52c4c9ee78243bcd002937 Mon Sep 17 00:00:00 2001 From: a dinosaur Date: Mon, 11 Sep 2023 16:24:36 +1000 Subject: [PATCH] language: preliminary support for separation of statements --- .../kotlin/gay/pizza/pork/parser/Parser.kt | 37 +++++++++++++------ .../kotlin/gay/pizza/pork/parser/TokenType.kt | 4 +- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/parser/src/main/kotlin/gay/pizza/pork/parser/Parser.kt b/parser/src/main/kotlin/gay/pizza/pork/parser/Parser.kt index 08ac4fe..37aa9dc 100644 --- a/parser/src/main/kotlin/gay/pizza/pork/parser/Parser.kt +++ b/parser/src/main/kotlin/gay/pizza/pork/parser/Parser.kt @@ -346,6 +346,8 @@ class Parser(source: PeekableSource, val attribution: NodeAttribution) { private fun collect( peeking: TokenType, consuming: TokenType? = null, + expecting: Array? = null, + expectingIgnoreType: IgnoreType = IgnoreType.Default, read: () -> T ): List { val items = mutableListOf() @@ -354,6 +356,9 @@ class Parser(source: PeekableSource, val attribution: NodeAttribution) { if (consuming != null) { next(consuming) } + if (expecting != null) { + expect(expectingIgnoreType, *expecting) + } items.add(item) } return items @@ -381,8 +386,8 @@ class Parser(source: PeekableSource, val attribution: NodeAttribution) { } else false } - private fun expect(vararg types: TokenType): Token { - val token = next() + private fun expect(ignoreType: IgnoreType, vararg types: TokenType): Token { + val token = next(ignoreType) if (!types.contains(token.type)) { throw RuntimeException( "Expected one of ${types.joinToString(", ")}" + @@ -392,24 +397,26 @@ class Parser(source: PeekableSource, val attribution: NodeAttribution) { return token } + private fun expect(vararg types: TokenType): Token = expect(IgnoreType.Default, *types) + private fun expect(vararg types: TokenType, consume: (Token) -> T): T = consume(expect(*types)) - private fun next(): Token { + private fun next(ignoreType: IgnoreType = IgnoreType.Default): Token { while (true) { val token = unsanitizedSource.next() attribution.push(token) - if (ignoredByParser(token.type)) { + if (ignoredByParser(ignoreType, token.type)) { continue } return token } } - private fun peek(): Token { + private fun peek(ignoreType: IgnoreType = IgnoreType.Default): Token { while (true) { val token = unsanitizedSource.peek() - if (ignoredByParser(token.type)) { + if (ignoredByParser(ignoreType, token.type)) { attribution.push(token) unsanitizedSource.next() continue @@ -423,10 +430,18 @@ class Parser(source: PeekableSource, val attribution: NodeAttribution) { return attribution.exit(block()) } - private fun ignoredByParser(type: TokenType): Boolean = when (type) { - TokenType.BlockComment -> true - TokenType.LineComment -> true - TokenType.Whitespace -> true - else -> false + private fun ignoredByParser(ignoreType: IgnoreType, type: TokenType): Boolean = ignoreType.ignored(type) + + private enum class IgnoreType { + ExpressionList, Default; + + fun ignored(type: TokenType): Boolean = when { + type == TokenType.BlockComment -> true + type == TokenType.LineComment -> true + type == TokenType.Whitespace -> true + type == TokenType.Semicolon && this == Default -> true + type == TokenType.Line && this == Default -> true + else -> false + } } } diff --git a/parser/src/main/kotlin/gay/pizza/pork/parser/TokenType.kt b/parser/src/main/kotlin/gay/pizza/pork/parser/TokenType.kt index 413a232..8820585 100644 --- a/parser/src/main/kotlin/gay/pizza/pork/parser/TokenType.kt +++ b/parser/src/main/kotlin/gay/pizza/pork/parser/TokenType.kt @@ -51,7 +51,9 @@ enum class TokenType(vararg properties: TokenTypeProperty) { Native(ManyChars("native"), KeywordFamily), Let(ManyChars("let"), KeywordFamily), Var(ManyChars("var"), KeywordFamily), - Whitespace(CharConsumer { it == ' ' || it == '\r' || it == '\n' || it == '\t' }), + Whitespace(CharConsumer { it == ' ' || it == '\t' || it == '\r' }), // JAAJ WAS HERE + Semicolon(SingleChar(';')), + Line(SingleChar('\n')), BlockComment(CommentFamily), LineComment(CommentFamily), EndOfFile;