language: var, reassign, comparison operators

This commit is contained in:
2023-09-10 04:34:50 -04:00
parent f433ba2776
commit 71999032ac
20 changed files with 262 additions and 26 deletions

View File

@ -5,5 +5,6 @@ import gay.pizza.pork.ast.Node
object DiscardNodeAttribution : NodeAttribution {
override fun enter() {}
override fun push(token: Token) {}
override fun <T : Node> adopt(node: T) {}
override fun <T : Node> exit(node: T): T = node
}

View File

@ -5,5 +5,6 @@ import gay.pizza.pork.ast.Node
interface NodeAttribution {
fun enter()
fun push(token: Token)
fun <T: Node> adopt(node: T)
fun <T: Node> exit(node: T): T
}

View File

@ -45,6 +45,14 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
LetAssignment(symbol, value)
}
private fun readVarAssignment(): VarAssignment = within {
expect(TokenType.Var)
val symbol = readSymbolRaw()
expect(TokenType.Equals)
val value = readExpression()
VarAssignment(symbol, value)
}
private fun readSymbolRaw(): Symbol = within {
expect(TokenType.Symbol) { Symbol(it.text) }
}
@ -123,6 +131,10 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
readLetAssignment()
}
TokenType.Var -> {
readVarAssignment()
}
TokenType.Symbol -> {
readSymbolCases()
}
@ -161,6 +173,15 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
}
}
if (expression is SymbolReference && peek(TokenType.Equals)) {
return within {
attribution.adopt(expression)
expect(TokenType.Equals)
val value = readExpression()
SetAssignment(expression.symbol, value)
}
}
return if (peek(
TokenType.Plus,
TokenType.Minus,
@ -169,7 +190,11 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
TokenType.Equality,
TokenType.Inequality,
TokenType.Mod,
TokenType.Rem
TokenType.Rem,
TokenType.Lesser,
TokenType.Greater,
TokenType.LesserEqual,
TokenType.GreaterEqual
)
) {
within {
@ -268,6 +293,10 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
TokenType.Inequality -> InfixOperator.NotEquals
TokenType.Mod -> InfixOperator.EuclideanModulo
TokenType.Rem -> InfixOperator.Remainder
TokenType.Lesser -> InfixOperator.Lesser
TokenType.Greater -> InfixOperator.Greater
TokenType.LesserEqual -> InfixOperator.LesserEqual
TokenType.GreaterEqual -> InfixOperator.GreaterEqual
else -> throw RuntimeException("Unknown Infix Operator")
}

View File

@ -95,6 +95,13 @@ class Printer(buffer: StringBuilder) : NodeVisitor<Unit> {
visit(node.symbol)
}
override fun visitVarAssignment(node: VarAssignment) {
append("var ")
visit(node.symbol)
append(" = ")
visit(node.value)
}
override fun visitWhile(node: While) {
append("while ")
visit(node.condition)
@ -113,6 +120,12 @@ class Printer(buffer: StringBuilder) : NodeVisitor<Unit> {
visit(node.expression)
}
override fun visitSetAssignment(node: SetAssignment) {
visit(node.symbol)
append(" = ")
visit(node.value)
}
override fun visitIf(node: If) {
append("if ")
visit(node.condition)

View File

@ -22,6 +22,15 @@ class TokenNodeAttribution : NodeAttribution {
store.add(token)
}
override fun <T : Node> adopt(node: T) {
val tokens = nodes.remove(node)
if (tokens != null) {
for (token in tokens) {
push(token)
}
}
}
override fun <T: Node> exit(node: T): T {
val store = stack.removeLast()
nodes[node] = store

View File

@ -19,6 +19,10 @@ enum class TokenType(vararg properties: TokenTypeProperty) {
Minus(SingleChar('-'), OperatorFamily),
Multiply(SingleChar('*'), OperatorFamily),
Divide(SingleChar('/'), OperatorFamily),
LesserEqual(OperatorFamily),
GreaterEqual(OperatorFamily),
Lesser(SingleChar('<'), OperatorFamily, Promotion('=', LesserEqual)),
Greater(SingleChar('>'), OperatorFamily, Promotion('=', GreaterEqual)),
LeftCurly(SingleChar('{')),
RightCurly(SingleChar('}')),
LeftBracket(SingleChar('[')),
@ -42,6 +46,7 @@ enum class TokenType(vararg properties: TokenTypeProperty) {
Func(Keyword("func"), KeywordFamily),
Native(Keyword("native"), KeywordFamily),
Let(Keyword("let"), KeywordFamily),
Var(Keyword("var"), KeywordFamily),
Whitespace(CharConsumer { it == ' ' || it == '\r' || it == '\n' || it == '\t' }),
BlockComment(CommentFamily),
LineComment(CommentFamily),