mirror of
https://github.com/GayPizzaSpecifications/pork.git
synced 2025-08-03 21:21:33 +00:00
<WIP> language: preliminary support for separation of statements
This commit is contained in:
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
Reference in New Issue
Block a user