<WIP> language: preliminary support for separation of statements

This commit is contained in:
a dinosaur 2023-09-11 16:24:36 +10:00
parent 2ee1565fb5
commit 0881924c65
2 changed files with 29 additions and 12 deletions

View File

@ -346,6 +346,8 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
private fun <T> collect( private fun <T> collect(
peeking: TokenType, peeking: TokenType,
consuming: TokenType? = null, consuming: TokenType? = null,
expecting: Array<TokenType>? = null,
expectingIgnoreType: IgnoreType = IgnoreType.Default,
read: () -> T read: () -> T
): List<T> { ): List<T> {
val items = mutableListOf<T>() val items = mutableListOf<T>()
@ -354,6 +356,9 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
if (consuming != null) { if (consuming != null) {
next(consuming) next(consuming)
} }
if (expecting != null) {
expect(expectingIgnoreType, *expecting)
}
items.add(item) items.add(item)
} }
return items return items
@ -381,8 +386,8 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
} else false } else false
} }
private fun expect(vararg types: TokenType): Token { private fun expect(ignoreType: IgnoreType, vararg types: TokenType): Token {
val token = next() val token = next(ignoreType)
if (!types.contains(token.type)) { if (!types.contains(token.type)) {
throw RuntimeException( throw RuntimeException(
"Expected one of ${types.joinToString(", ")}" + "Expected one of ${types.joinToString(", ")}" +
@ -392,24 +397,26 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
return token return token
} }
private fun expect(vararg types: TokenType): Token = expect(IgnoreType.Default, *types)
private fun <T: Node> expect(vararg types: TokenType, consume: (Token) -> T): T = private fun <T: Node> expect(vararg types: TokenType, consume: (Token) -> T): T =
consume(expect(*types)) consume(expect(*types))
private fun next(): Token { private fun next(ignoreType: IgnoreType = IgnoreType.Default): Token {
while (true) { while (true) {
val token = unsanitizedSource.next() val token = unsanitizedSource.next()
attribution.push(token) attribution.push(token)
if (ignoredByParser(token.type)) { if (ignoredByParser(ignoreType, token.type)) {
continue continue
} }
return token return token
} }
} }
private fun peek(): Token { private fun peek(ignoreType: IgnoreType = IgnoreType.Default): Token {
while (true) { while (true) {
val token = unsanitizedSource.peek() val token = unsanitizedSource.peek()
if (ignoredByParser(token.type)) { if (ignoredByParser(ignoreType, token.type)) {
attribution.push(token) attribution.push(token)
unsanitizedSource.next() unsanitizedSource.next()
continue continue
@ -423,10 +430,18 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
return attribution.exit(block()) return attribution.exit(block())
} }
private fun ignoredByParser(type: TokenType): Boolean = when (type) { private fun ignoredByParser(ignoreType: IgnoreType, type: TokenType): Boolean = ignoreType.ignored(type)
TokenType.BlockComment -> true
TokenType.LineComment -> true private enum class IgnoreType {
TokenType.Whitespace -> true ExpressionList, Default;
else -> false
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
}
} }
} }

View File

@ -51,7 +51,9 @@ enum class TokenType(vararg properties: TokenTypeProperty) {
Native(ManyChars("native"), KeywordFamily), Native(ManyChars("native"), KeywordFamily),
Let(ManyChars("let"), KeywordFamily), Let(ManyChars("let"), KeywordFamily),
Var(ManyChars("var"), 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), BlockComment(CommentFamily),
LineComment(CommentFamily), LineComment(CommentFamily),
EndOfFile; EndOfFile;