Support if without else.

This commit is contained in:
Alex Zenla 2023-08-19 20:59:14 -07:00
parent cccea9c2ca
commit 903f730d51
Signed by: alex
GPG Key ID: C0780728420EBFE5
8 changed files with 35 additions and 10 deletions

View File

@ -5,4 +5,5 @@ fib = { n in
then 1 then 1
else fib(n - 1) + fib(n - 2) else fib(n - 1) + fib(n - 2)
} }
main = { in fib(20) } main = { in fib(20) }

7
examples/if.pork Normal file
View File

@ -0,0 +1,7 @@
check = { value in
if value then 50
}
main = { in
value = check(100)
}

View File

@ -18,12 +18,17 @@ main = { in
trueValue = true trueValue = true
falseValue = false falseValue = false
check = { in
if true then false else true
}
[ [
calculateSimpleResult, calculateSimpleResult,
calculateComplexResult, calculateComplexResult,
multiplyResult, multiplyResult,
list, list,
trueValue, trueValue,
falseValue falseValue,
check()
] ]
} }

View File

@ -3,7 +3,7 @@ package gay.pizza.pork.ast
class If( class If(
val condition: Expression, val condition: Expression,
val thenExpression: Expression, val thenExpression: Expression,
val elseExpression: Expression val elseExpression: Expression? = null
) : Expression { ) : Expression {
override val type: NodeType = NodeType.If override val type: NodeType = NodeType.If
} }

View File

@ -44,9 +44,11 @@ class Printer(private val buffer: StringBuilder) : Visitor<Unit> {
visit(node.condition) visit(node.condition)
append(" then ") append(" then ")
visit(node.thenExpression) visit(node.thenExpression)
if (node.elseExpression != null) {
append(" else ") append(" else ")
visit(node.elseExpression) visit(node.elseExpression)
} }
}
override fun visitSymbol(node: Symbol) { override fun visitSymbol(node: Symbol) {
append(node.id) append(node.id)

View File

@ -0,0 +1,3 @@
package gay.pizza.pork.eval
data object None

View File

@ -24,12 +24,16 @@ class PorkEvaluator(root: Scope) : Visitor<Any> {
return if (condition == true) { return if (condition == true) {
visit(node.thenExpression) visit(node.thenExpression)
} else { } else {
if (node.elseExpression != null) {
visit(node.elseExpression) visit(node.elseExpression)
} else {
None
}
} }
} }
override fun visitSymbol(node: Symbol): Any { override fun visitSymbol(node: Symbol): Any {
return Unit return None
} }
override fun visitLambda(node: Lambda): CallableFunction { override fun visitLambda(node: Lambda): CallableFunction {
@ -43,7 +47,7 @@ class PorkEvaluator(root: Scope) : Visitor<Any> {
for (expression in node.expressions) { for (expression in node.expressions) {
value = visit(expression) value = visit(expression)
} }
value ?: Unit value ?: None
} finally { } finally {
currentScope = currentScope.leave() currentScope = currentScope.leave()
} }
@ -88,6 +92,6 @@ class PorkEvaluator(root: Scope) : Visitor<Any> {
for (expression in node.expressions) { for (expression in node.expressions) {
value = visit(expression) value = visit(expression)
} }
return value ?: Unit return value ?: None
} }
} }

View File

@ -18,8 +18,11 @@ class PorkParser(val source: PeekableSource<Token>) {
val condition = readExpression() val condition = readExpression()
expect(TokenType.Then) expect(TokenType.Then)
val thenExpression = readExpression() val thenExpression = readExpression()
var elseExpression: Expression? = null
if (peekType(TokenType.Else)) {
expect(TokenType.Else) expect(TokenType.Else)
val elseExpression = readExpression() elseExpression = readExpression()
}
return If(condition, thenExpression, elseExpression) return If(condition, thenExpression, elseExpression)
} }