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

@ -26,13 +26,19 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
override fun visitLetAssignment(node: LetAssignment): Any {
val value = node.value.visit(this)
currentScope.define(node.symbol.id, value)
currentScope.define(node.symbol.id, value, ValueStoreType.Let)
return value
}
override fun visitSymbolReference(node: SymbolReference): Any =
currentScope.value(node.symbol.id)
override fun visitVarAssignment(node: VarAssignment): Any {
val value = node.value.visit(this)
currentScope.define(node.symbol.id, value, type = ValueStoreType.Var)
return value
}
override fun visitWhile(node: While): Any {
val blockFunction = node.block.visit(this) as BlockFunction
var result: Any? = null
@ -68,6 +74,12 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
}
}
override fun visitSetAssignment(node: SetAssignment): Any {
val value = node.value.visit(this)
currentScope.set(node.symbol.id, value)
return value
}
override fun visitIf(node: If): Any {
val condition = node.condition.visit(this)
return if (condition == true) {
@ -108,7 +120,11 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
multiply = { a, b -> a * b },
divide = { a, b -> a / b },
euclideanModulo = { _, _ -> throw RuntimeException("Can't perform integer modulo between floating point types") },
remainder = { _, _ -> throw RuntimeException("Can't perform integer remainder between floating point types") }
remainder = { _, _ -> throw RuntimeException("Can't perform integer remainder between floating point types") },
lesser = { a, b -> a < b },
greater = { a, b -> a > b },
lesserEqual = { a, b -> a <= b },
greaterEqual = { a, b -> a >= b }
)
}
@ -123,7 +139,11 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
multiply = { a, b -> a * b },
divide = { a, b -> a / b },
euclideanModulo = { _, _ -> throw RuntimeException("Can't perform integer modulo between floating point types") },
remainder = { _, _ -> throw RuntimeException("Can't perform integer remainder between floating point types") }
remainder = { _, _ -> throw RuntimeException("Can't perform integer remainder between floating point types") },
lesser = { a, b -> a < b },
greater = { a, b -> a > b },
lesserEqual = { a, b -> a <= b },
greaterEqual = { a, b -> a >= b }
)
}
@ -138,7 +158,11 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
multiply = { a, b -> a * b },
divide = { a, b -> a / b },
euclideanModulo = { x, d -> (x % d).let { q -> if (q < 0) q + abs(d) else q } },
remainder = { x, d -> x % d }
remainder = { x, d -> x % d },
lesser = { a, b -> a < b },
greater = { a, b -> a > b },
lesserEqual = { a, b -> a <= b },
greaterEqual = { a, b -> a >= b }
)
}
@ -153,7 +177,11 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
multiply = { a, b -> a * b },
divide = { a, b -> a / b },
euclideanModulo = { x, d -> (x % d).let { q -> if (q < 0) q + abs(d) else q } },
remainder = { x, d -> x % d }
remainder = { x, d -> x % d },
lesser = { a, b -> a < b },
greater = { a, b -> a > b },
lesserEqual = { a, b -> a <= b },
greaterEqual = { a, b -> a >= b }
)
}
@ -170,8 +198,12 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
multiply: (T, T) -> T,
divide: (T, T) -> T,
euclideanModulo: (T, T) -> T,
remainder: (T, T) -> T
): T {
remainder: (T, T) -> T,
lesser: (T, T) -> Boolean,
greater: (T, T) -> Boolean,
lesserEqual: (T, T) -> Boolean,
greaterEqual: (T, T) -> Boolean
): Any {
return when (op) {
InfixOperator.Plus -> add(convert(left), convert(right))
InfixOperator.Minus -> subtract(convert(left), convert(right))
@ -179,6 +211,10 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
InfixOperator.Divide -> divide(convert(left), convert(right))
InfixOperator.EuclideanModulo -> euclideanModulo(convert(left), convert(right))
InfixOperator.Remainder -> remainder(convert(left), convert(right))
InfixOperator.Lesser -> lesser(convert(left), convert(right))
InfixOperator.Greater -> greater(convert(left), convert(right))
InfixOperator.LesserEqual -> lesserEqual(convert(left), convert(right))
InfixOperator.GreaterEqual -> greaterEqual(convert(left), convert(right))
else -> throw RuntimeException("Unable to handle operation $op")
}
}

View File

@ -6,43 +6,55 @@ class Scope(
val name: String? = null
) {
private val inherited = inherits.toMutableList()
private val variables = mutableMapOf<String, Any>()
private val variables = mutableMapOf<String, ValueStore>()
fun define(name: String, value: Any) {
val previous = variables.put(name, value)
fun define(name: String, value: Any, type: ValueStoreType = ValueStoreType.Let) {
val previous = variables.put(name, ValueStore(value, type))
if (previous != null) {
variables[name] = previous
throw RuntimeException("Variable '${name}' is already defined")
}
}
fun value(name: String): Any {
val value = valueOrNotFound(name)
if (value === NotFound) {
fun set(name: String, value: Any) {
val holder = valueHolderOrNotFound(name)
if (holder.type == ValueStoreType.Let) {
throw RuntimeException("Variable '${name}' is already defined")
}
if (holder === NotFound.Holder) {
throw RuntimeException("Variable '${name}' not defined")
}
return value
holder.value = value
}
private fun valueOrNotFound(name: String): Any {
val value = variables[name]
if (value == null) {
fun value(name: String): Any {
val holder = valueHolderOrNotFound(name)
if (holder === NotFound.Holder) {
throw RuntimeException("Variable '${name}' not defined")
}
return holder.value
}
private fun valueHolderOrNotFound(name: String): ValueStore {
val holder = variables[name]
if (holder == null) {
if (parent != null) {
val parentMaybeFound = parent.valueOrNotFound(name)
if (parentMaybeFound !== NotFound) {
val parentMaybeFound = parent.valueHolderOrNotFound(name)
if (parentMaybeFound !== NotFound.Holder) {
return parentMaybeFound
}
}
for (inherit in inherited) {
val inheritMaybeFound = inherit.valueOrNotFound(name)
if (inheritMaybeFound !== NotFound) {
val inheritMaybeFound = inherit.valueHolderOrNotFound(name)
if (inheritMaybeFound !== NotFound.Holder) {
return inheritMaybeFound
}
}
return NotFound
return NotFound.Holder
}
return value
return holder
}
fun fork(name: String? = null): Scope =
@ -80,5 +92,7 @@ class Scope(
}
}
private object NotFound
private object NotFound {
val Holder = ValueStore(NotFound, ValueStoreType.Let)
}
}

View File

@ -0,0 +1,5 @@
package gay.pizza.pork.evaluator
class ValueStore(var value: Any, val type: ValueStoreType) {
override fun toString(): String = "${type.name}: $value"
}

View File

@ -0,0 +1,6 @@
package gay.pizza.pork.evaluator
enum class ValueStoreType {
Let,
Var
}