mirror of
https://github.com/GayPizzaSpecifications/pork.git
synced 2025-08-03 13:11:32 +00:00
language: var, reassign, comparison operators
This commit is contained in:
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
|
Reference in New Issue
Block a user