diff --git a/src/main/kotlin/no/uio/microobject/runtime/Interpreter.kt b/src/main/kotlin/no/uio/microobject/runtime/Interpreter.kt index cab032d..02c1949 100644 --- a/src/main/kotlin/no/uio/microobject/runtime/Interpreter.kt +++ b/src/main/kotlin/no/uio/microobject/runtime/Interpreter.kt @@ -68,10 +68,21 @@ class Interpreter( // TripleManager used to provide virtual triples etc. val tripleManager : TripleManager = TripleManager(settings, staticInfo, this) - //evaluates a call on cl.nm on thisVar - //Must ONLY be called if nm is checked to have no side-effects (i.e., is rule) - //First return value is the created object, the second the return value - fun evalCall(objName: String, className: String, metName: String): Pair { + /** + * Evaluates a call on a method of a class + * + * This method is used to evaluate a call on a method of a class. It constructs the initial state, adds the + * parameters to the memory, and runs the interpreter until the return value is reached. + * Must ONLY be called if nm is checked to have no side-effects (i.e., is rule) + * + * @param objName the name of the object + * @param className the name of the class + * @param metName the name of the method + * @param params the parameters of the method. It must be structured as "paramName" to "paramValue" as a LiteralExpr as a map + * @return a pair of the created object and the return value + * @throws Exception if an error occurs during the generation of the builtin + */ + fun evalCall(objName: String, className: String, metName: String, params: Map = mapOf()): Pair { //Construct initial state val classStmt = staticInfo.methodTable[className] @@ -84,6 +95,14 @@ class Interpreter( heap.keys.first { it.literal == objName }.tag //retrieve real class, because rule methods can be inheritated ) mem["this"] = obj + + // Add parameters to memory + if (params.isNotEmpty()) { + for ((paramName, paramExpr) in params) { + mem[paramName] = paramExpr + } + } + val myId = Names.getStackId() val se = StackEntry(met.stmt, mem, obj, myId) stack.push(se) diff --git a/src/test/kotlin/no/uio/microobject/test/runtime/Interpreter.kt b/src/test/kotlin/no/uio/microobject/test/runtime/Interpreter.kt index 77a0b36..eade7e3 100644 --- a/src/test/kotlin/no/uio/microobject/test/runtime/Interpreter.kt +++ b/src/test/kotlin/no/uio/microobject/test/runtime/Interpreter.kt @@ -4,6 +4,8 @@ import io.kotest.matchers.shouldBe import no.uio.microobject.ast.expr.LiteralExpr import no.uio.microobject.test.MicroObjectTest import no.uio.microobject.type.* +import org.apache.jena.rdf.model.impl.LiteralImpl +import kotlin.test.assertEquals class Interpreter : MicroObjectTest() { private fun evalTest() { @@ -24,10 +26,23 @@ class Interpreter : MicroObjectTest() { person.size shouldBe 2 } + private fun evalParamsTest() { + val (interpreter, _) = initInterpreter("eval-params", StringLoad.RES) + executeUntilBreak(interpreter) + + interpreter.evalCall(interpreter.getObjectNames("A")[0].toString(), "A", "setX", mapOf("newX" to LiteralExpr("1", INTTYPE))) + val queryRes = interpreter.query("SELECT * WHERE { ?obj a prog:A . ?obj prog:A_x ?x }") + queryRes!!.hasNext() shouldBe true + + val x = queryRes.next() + assertEquals(1, (x["x"] as LiteralImpl).int) + } + init { "eval" { evalTest() getObjectNamesTest() + evalParamsTest() } } } \ No newline at end of file diff --git a/src/test/resources/eval-params.smol b/src/test/resources/eval-params.smol new file mode 100644 index 0000000..0f88cf1 --- /dev/null +++ b/src/test/resources/eval-params.smol @@ -0,0 +1,10 @@ +class A(Int x) + Unit setX(Int newX) + this.x = newX; + end +end + +main + A a = new A(5); + breakpoint; +end \ No newline at end of file