mirror of
https://github.com/GayPizzaSpecifications/pork.git
synced 2025-08-03 21:21:33 +00:00
language: add unary plus & minus, post increment & decrement operators, non-newline print builtin. fix block comments (#4)
This commit is contained in:
@ -71,9 +71,65 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
|
||||
}
|
||||
!value
|
||||
}
|
||||
PrefixOperator.UnaryPlus, PrefixOperator.UnaryMinus -> {
|
||||
if (value !is Number) {
|
||||
throw RuntimeException("Numeric unary '${node.op.token}' illegal on non-numeric type '${value.javaClass.simpleName}'")
|
||||
}
|
||||
unaryNumericOperation(node, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun unaryNumericOperation(node: PrefixOperation, value: Number) = when (value) {
|
||||
is Double -> {
|
||||
unaryNumericOperation(
|
||||
node.op,
|
||||
value,
|
||||
convert = { it.toDouble() },
|
||||
plus = { +it },
|
||||
minus = { -it }
|
||||
)
|
||||
}
|
||||
is Float -> {
|
||||
unaryNumericOperation(
|
||||
node.op,
|
||||
value,
|
||||
convert = { it.toFloat() },
|
||||
plus = { +it },
|
||||
minus = { -it }
|
||||
)
|
||||
}
|
||||
is Long -> {
|
||||
unaryNumericOperation(
|
||||
node.op,
|
||||
value,
|
||||
convert = { it.toLong() },
|
||||
plus = { +it },
|
||||
minus = { -it }
|
||||
)
|
||||
}
|
||||
is Int -> {
|
||||
unaryNumericOperation(
|
||||
node.op,
|
||||
value,
|
||||
convert = { it.toInt() },
|
||||
plus = { +it },
|
||||
minus = { -it }
|
||||
)
|
||||
}
|
||||
else -> throw RuntimeException("Unknown numeric type: ${value.javaClass.name}")
|
||||
}
|
||||
|
||||
override fun visitSuffixOperation(node: SuffixOperation): Any {
|
||||
val previousValue = currentScope.value(node.reference.symbol.id)
|
||||
val infix = visitInfixOperation(InfixOperation(node.reference, when (node.op) {
|
||||
SuffixOperator.Increment -> InfixOperator.Plus
|
||||
SuffixOperator.Decrement -> InfixOperator.Minus
|
||||
}, IntegerLiteral(1)))
|
||||
currentScope.set(node.reference.symbol.id, infix)
|
||||
return previousValue
|
||||
}
|
||||
|
||||
override fun visitSetAssignment(node: SetAssignment): Any {
|
||||
val value = node.value.visit(this)
|
||||
currentScope.set(node.symbol.id, value)
|
||||
@ -219,6 +275,20 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun <T: Number> unaryNumericOperation(
|
||||
op: PrefixOperator,
|
||||
value: Number,
|
||||
convert: (Number) -> T,
|
||||
plus: (T) -> T,
|
||||
minus: (T) -> T
|
||||
): Any {
|
||||
return when (op) {
|
||||
PrefixOperator.UnaryPlus -> plus(convert(value))
|
||||
PrefixOperator.UnaryMinus -> minus(convert(value))
|
||||
else -> throw RuntimeException("Unable to handle operation $op")
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitBlock(node: Block): BlockFunction = BlockFunction {
|
||||
var value: Any? = null
|
||||
for (expression in node.expressions) {
|
||||
|
@ -2,6 +2,7 @@ package gay.pizza.pork.evaluator
|
||||
|
||||
class InternalNativeProvider(val quiet: Boolean = false) : NativeProvider {
|
||||
private val functions = mutableMapOf(
|
||||
"print" to CallableFunction(::printValues),
|
||||
"println" to CallableFunction(::printLine)
|
||||
)
|
||||
|
||||
@ -9,15 +10,15 @@ class InternalNativeProvider(val quiet: Boolean = false) : NativeProvider {
|
||||
return functions[definition] ?: throw RuntimeException("Unknown Internal Function: $definition")
|
||||
}
|
||||
|
||||
private fun printValues(arguments: Arguments): Any {
|
||||
if (quiet || arguments.values.isEmpty()) return None
|
||||
print(arguments.values.joinToString(" "))
|
||||
return None
|
||||
}
|
||||
|
||||
private fun printLine(arguments: Arguments): Any {
|
||||
if (quiet) {
|
||||
return None
|
||||
}
|
||||
when (arguments.values.count()) {
|
||||
0 -> println()
|
||||
1 -> println(arguments.values[0])
|
||||
else -> println(arguments.values.joinToString(" "))
|
||||
}
|
||||
if (quiet) return None
|
||||
println(arguments.values.joinToString(" "))
|
||||
return None
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user