diff --git a/ast/src/main/kotlin/gay/pizza/pork/ast/Assignment.kt b/ast/src/main/kotlin/gay/pizza/pork/ast/LetAssignment.kt similarity index 71% rename from ast/src/main/kotlin/gay/pizza/pork/ast/Assignment.kt rename to ast/src/main/kotlin/gay/pizza/pork/ast/LetAssignment.kt index 672a45d..0873984 100644 --- a/ast/src/main/kotlin/gay/pizza/pork/ast/Assignment.kt +++ b/ast/src/main/kotlin/gay/pizza/pork/ast/LetAssignment.kt @@ -4,15 +4,15 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @Serializable -@SerialName("assignment") -class Assignment(val symbol: Symbol, val value: Expression) : Expression() { - override val type: NodeType = NodeType.Assignment +@SerialName("letAssignment") +class LetAssignment(val symbol: Symbol, val value: Expression) : Expression() { + override val type: NodeType = NodeType.LetAssignment override fun visitChildren(visitor: NodeVisitor): List = visitor.visitNodes(symbol, value) override fun equals(other: Any?): Boolean { - if (other !is Assignment) return false + if (other !is LetAssignment) return false return other.symbol == symbol && other.value == value } diff --git a/ast/src/main/kotlin/gay/pizza/pork/ast/NodeCoalescer.kt b/ast/src/main/kotlin/gay/pizza/pork/ast/NodeCoalescer.kt index b7b4c87..ebe2d0a 100644 --- a/ast/src/main/kotlin/gay/pizza/pork/ast/NodeCoalescer.kt +++ b/ast/src/main/kotlin/gay/pizza/pork/ast/NodeCoalescer.kt @@ -7,7 +7,7 @@ class NodeCoalescer(val handler: (Node) -> Unit) : NodeVisitor { override fun visitListLiteral(node: ListLiteral): Unit = handle(node) override fun visitSymbol(node: Symbol): Unit = handle(node) override fun visitFunctionCall(node: FunctionCall): Unit = handle(node) - override fun visitDefine(node: Assignment): Unit = handle(node) + override fun visitLetAssignment(node: LetAssignment): Unit = handle(node) override fun visitSymbolReference(node: SymbolReference): Unit = handle(node) override fun visitLambda(node: Lambda): Unit = handle(node) override fun visitParentheses(node: Parentheses): Unit = handle(node) diff --git a/ast/src/main/kotlin/gay/pizza/pork/ast/NodeType.kt b/ast/src/main/kotlin/gay/pizza/pork/ast/NodeType.kt index 1e115c6..5d9d09a 100644 --- a/ast/src/main/kotlin/gay/pizza/pork/ast/NodeType.kt +++ b/ast/src/main/kotlin/gay/pizza/pork/ast/NodeType.kt @@ -12,7 +12,7 @@ enum class NodeType(val parent: NodeType? = null) { ListLiteral(Expression), StringLiteral(Expression), Parentheses(Expression), - Assignment(Expression), + LetAssignment(Expression), Lambda(Expression), PrefixOperation(Expression), InfixOperation(Expression), diff --git a/ast/src/main/kotlin/gay/pizza/pork/ast/NodeVisitor.kt b/ast/src/main/kotlin/gay/pizza/pork/ast/NodeVisitor.kt index af2b70a..4ad160c 100644 --- a/ast/src/main/kotlin/gay/pizza/pork/ast/NodeVisitor.kt +++ b/ast/src/main/kotlin/gay/pizza/pork/ast/NodeVisitor.kt @@ -7,7 +7,7 @@ interface NodeVisitor { fun visitListLiteral(node: ListLiteral): T fun visitSymbol(node: Symbol): T fun visitFunctionCall(node: FunctionCall): T - fun visitDefine(node: Assignment): T + fun visitLetAssignment(node: LetAssignment): T fun visitSymbolReference(node: SymbolReference): T fun visitLambda(node: Lambda): T fun visitParentheses(node: Parentheses): T @@ -26,7 +26,7 @@ interface NodeVisitor { is BooleanLiteral -> visitBooleanLiteral(node) is ListLiteral -> visitListLiteral(node) is FunctionCall -> visitFunctionCall(node) - is Assignment -> visitDefine(node) + is LetAssignment -> visitLetAssignment(node) is SymbolReference -> visitSymbolReference(node) is Lambda -> visitLambda(node) is Parentheses -> visitParentheses(node) diff --git a/evaluator/src/main/kotlin/gay/pizza/pork/evaluator/EvaluationVisitor.kt b/evaluator/src/main/kotlin/gay/pizza/pork/evaluator/EvaluationVisitor.kt index 19cb526..bf79447 100644 --- a/evaluator/src/main/kotlin/gay/pizza/pork/evaluator/EvaluationVisitor.kt +++ b/evaluator/src/main/kotlin/gay/pizza/pork/evaluator/EvaluationVisitor.kt @@ -17,7 +17,7 @@ class EvaluationVisitor(root: Scope) : NodeVisitor { return currentScope.call(node.symbol.id, Arguments(arguments)) } - override fun visitDefine(node: Assignment): Any { + override fun visitLetAssignment(node: LetAssignment): Any { val value = visit(node.value) currentScope.define(node.symbol.id, value) return value diff --git a/examples/fib.pork b/examples/fib.pork index 2f6c80e..c1dbc98 100644 --- a/examples/fib.pork +++ b/examples/fib.pork @@ -8,6 +8,6 @@ func fib(n) { } export func main() { - result = fib(20) + let result = fib(20) println(result) } diff --git a/examples/syntax.pork b/examples/syntax.pork index 067b3e0..68ac248 100644 --- a/examples/syntax.pork +++ b/examples/syntax.pork @@ -1,41 +1,41 @@ export func main() { - three = 3 - two = 2 + let three = 3 + let two = 2 - calculateSimple = { in + let calculateSimple = { in (50 + three) * two } - calculateComplex = { in + let calculateComplex = { in three + two + 50 } - multiply = { a, b in + let multiply = { a, b in a * b } // calculates the result - calculateSimpleResult = calculateSimple() - calculateComplexResult = calculateComplex() - multiplyResult = multiply(50, 50) + let calculateSimpleResult = calculateSimple() + let calculateComplexResult = calculateComplex() + let multiplyResult = multiply(50, 50) - list = [10, 20, 30] - trueValue = true - falseValue = false + let list = [10, 20, 30] + let trueValue = true + let falseValue = false - invert = { value in + let invert = { value in !value } - notEqual = { a, b in + let notEqual = { a, b in a != b } - equal = { a, b in + let equal = { a, b in a == b } - results = [ + let results = [ calculateSimpleResult, calculateComplexResult, multiplyResult, 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 3bff51d..0f73352 100644 --- a/parser/src/main/kotlin/gay/pizza/pork/parser/Parser.kt +++ b/parser/src/main/kotlin/gay/pizza/pork/parser/Parser.kt @@ -31,6 +31,14 @@ class Parser(source: PeekableSource, val attribution: NodeAttribution) { ListLiteral(items) } + private fun readLetAssignment(): LetAssignment = within { + expect(TokenType.Let) + val symbol = readSymbolRaw() + expect(TokenType.Equals) + val value = readExpression() + LetAssignment(symbol, value) + } + private fun readSymbolRaw(): Symbol = within { expect(TokenType.Symbol) { Symbol(it.text) } } @@ -43,8 +51,6 @@ class Parser(source: PeekableSource, val attribution: NodeAttribution) { } expect(TokenType.RightParentheses) FunctionCall(symbol, arguments) - } else if (next(TokenType.Equals)) { - Assignment(symbol, readExpression()) } else { SymbolReference(symbol) } @@ -114,6 +120,10 @@ class Parser(source: PeekableSource, val attribution: NodeAttribution) { readListLiteral() } + TokenType.Let -> { + readLetAssignment() + } + TokenType.Symbol -> { readSymbolCases() } diff --git a/parser/src/main/kotlin/gay/pizza/pork/parser/Printer.kt b/parser/src/main/kotlin/gay/pizza/pork/parser/Printer.kt index ce5b5f5..93aebee 100644 --- a/parser/src/main/kotlin/gay/pizza/pork/parser/Printer.kt +++ b/parser/src/main/kotlin/gay/pizza/pork/parser/Printer.kt @@ -71,7 +71,8 @@ class Printer(buffer: StringBuilder) : NodeVisitor { append(")") } - override fun visitDefine(node: Assignment) { + override fun visitLetAssignment(node: LetAssignment) { + append("let ") visit(node.symbol) append(" = ") visit(node.value) 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 94e646d..f90c183 100644 --- a/parser/src/main/kotlin/gay/pizza/pork/parser/TokenType.kt +++ b/parser/src/main/kotlin/gay/pizza/pork/parser/TokenType.kt @@ -31,6 +31,7 @@ enum class TokenType(vararg properties: TokenTypeProperty) { Import(Keyword("import"), KeywordFamily), Export(Keyword("export"), KeywordFamily), Func(Keyword("func"), KeywordFamily), + Let(Keyword("let"), KeywordFamily), Whitespace(CharConsumer { it == ' ' || it == '\r' || it == '\n' || it == '\t' }), BlockComment(CommentFamily), LineComment(CommentFamily),