sclass SimpleInterpreter { sclass State { new LinkedHashMap vars; new L stack; selfType set(S var, O value) { vars.put(var, value); this; } O eval(Instruction i) { i.run(this); ret pop(); } O get(S var) { ret mapGet(vars, var); } void push(O value) { stack.add(value); } O pop() { ret popLast(stack); } } asclass Instruction { abstract void run(State state); } sinterface Evaluable { A get(State state); } /*srecord Const(O value) > Instruction { void run(State state) { state.push(value); } }*/ srecord Const(A value) implements Evaluable { A get(State state) { ret value; } } srecord Sequence(L l) > Instruction { Sequence(Instruction... l) { this.l = asList(l); } void run(State state) { fOr ping (Instruction i : l) i.run(state); } } srecord GetVar(Evaluable var) > Instruction { void run(State state) { state.push(state.get(var.get(state))); } } srecord CallF(Evaluable f, Evaluable... args) > Instruction { void run(State state) { O realF = f.eval(state); O[] realArgs = map(args, a -> a.eval(state)); state.push(safeCallF(realF, realArgs)); } } State newState() { ret new State; } }