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(); } A eval(Evaluable e) { ret e?.get(this); } 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 { public 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(state.eval(var))); } } srecord CallF(Evaluable f, Evaluable... args) > Instruction { void run(State state) { O realF = state.eval(f); O[] realArgs = mapToArray(args, a -> state.eval(a)); state.push(safeCallF(realF, realArgs)); } } State newState() { ret new State; } }