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:
@ -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")
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,5 @@
|
||||
package gay.pizza.pork.evaluator
|
||||
|
||||
class ValueStore(var value: Any, val type: ValueStoreType) {
|
||||
override fun toString(): String = "${type.name}: $value"
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package gay.pizza.pork.evaluator
|
||||
|
||||
enum class ValueStoreType {
|
||||
Let,
|
||||
Var
|
||||
}
|
Reference in New Issue
Block a user