diff --git a/examples/fib.pork b/examples/fib.pork index 5d71a9a..03a6edb 100644 --- a/examples/fib.pork +++ b/examples/fib.pork @@ -5,4 +5,5 @@ fib = { n in then 1 else fib(n - 1) + fib(n - 2) } + main = { in fib(20) } diff --git a/examples/if.pork b/examples/if.pork new file mode 100644 index 0000000..fc7fe83 --- /dev/null +++ b/examples/if.pork @@ -0,0 +1,7 @@ +check = { value in + if value then 50 +} + +main = { in + value = check(100) +} diff --git a/examples/syntax.pork b/examples/syntax.pork index 17a264c..d7bc9ae 100644 --- a/examples/syntax.pork +++ b/examples/syntax.pork @@ -18,12 +18,17 @@ main = { in trueValue = true falseValue = false + check = { in + if true then false else true + } + [ calculateSimpleResult, calculateComplexResult, multiplyResult, list, trueValue, - falseValue + falseValue, + check() ] } diff --git a/src/main/kotlin/gay/pizza/pork/ast/If.kt b/src/main/kotlin/gay/pizza/pork/ast/If.kt index 3ecaf27..3648561 100644 --- a/src/main/kotlin/gay/pizza/pork/ast/If.kt +++ b/src/main/kotlin/gay/pizza/pork/ast/If.kt @@ -3,7 +3,7 @@ package gay.pizza.pork.ast class If( val condition: Expression, val thenExpression: Expression, - val elseExpression: Expression + val elseExpression: Expression? = null ) : Expression { override val type: NodeType = NodeType.If } diff --git a/src/main/kotlin/gay/pizza/pork/ast/Printer.kt b/src/main/kotlin/gay/pizza/pork/ast/Printer.kt index ffe96a4..cfdf3e6 100644 --- a/src/main/kotlin/gay/pizza/pork/ast/Printer.kt +++ b/src/main/kotlin/gay/pizza/pork/ast/Printer.kt @@ -44,8 +44,10 @@ class Printer(private val buffer: StringBuilder) : Visitor { visit(node.condition) append(" then ") visit(node.thenExpression) - append(" else ") - visit(node.elseExpression) + if (node.elseExpression != null) { + append(" else ") + visit(node.elseExpression) + } } override fun visitSymbol(node: Symbol) { diff --git a/src/main/kotlin/gay/pizza/pork/eval/None.kt b/src/main/kotlin/gay/pizza/pork/eval/None.kt new file mode 100644 index 0000000..6d86fd0 --- /dev/null +++ b/src/main/kotlin/gay/pizza/pork/eval/None.kt @@ -0,0 +1,3 @@ +package gay.pizza.pork.eval + +data object None diff --git a/src/main/kotlin/gay/pizza/pork/eval/PorkEvaluator.kt b/src/main/kotlin/gay/pizza/pork/eval/PorkEvaluator.kt index 00c9893..a86f03e 100644 --- a/src/main/kotlin/gay/pizza/pork/eval/PorkEvaluator.kt +++ b/src/main/kotlin/gay/pizza/pork/eval/PorkEvaluator.kt @@ -24,12 +24,16 @@ class PorkEvaluator(root: Scope) : Visitor { return if (condition == true) { visit(node.thenExpression) } else { - visit(node.elseExpression) + if (node.elseExpression != null) { + visit(node.elseExpression) + } else { + None + } } } override fun visitSymbol(node: Symbol): Any { - return Unit + return None } override fun visitLambda(node: Lambda): CallableFunction { @@ -43,7 +47,7 @@ class PorkEvaluator(root: Scope) : Visitor { for (expression in node.expressions) { value = visit(expression) } - value ?: Unit + value ?: None } finally { currentScope = currentScope.leave() } @@ -88,6 +92,6 @@ class PorkEvaluator(root: Scope) : Visitor { for (expression in node.expressions) { value = visit(expression) } - return value ?: Unit + return value ?: None } } diff --git a/src/main/kotlin/gay/pizza/pork/parse/PorkParser.kt b/src/main/kotlin/gay/pizza/pork/parse/PorkParser.kt index c90b0d9..382b2b9 100644 --- a/src/main/kotlin/gay/pizza/pork/parse/PorkParser.kt +++ b/src/main/kotlin/gay/pizza/pork/parse/PorkParser.kt @@ -18,8 +18,11 @@ class PorkParser(val source: PeekableSource) { val condition = readExpression() expect(TokenType.Then) val thenExpression = readExpression() - expect(TokenType.Else) - val elseExpression = readExpression() + var elseExpression: Expression? = null + if (peekType(TokenType.Else)) { + expect(TokenType.Else) + elseExpression = readExpression() + } return If(condition, thenExpression, elseExpression) }