Skip to content

Instantly share code, notes, and snippets.

@nobeans
Last active April 26, 2020 08:00
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nobeans/c16a89a10d0abc30f357b07d8ecbb795 to your computer and use it in GitHub Desktop.
Save nobeans/c16a89a10d0abc30f357b07d8ecbb795 to your computer and use it in GitHub Desktop.
// http://blog.64p.org/entry/2016/09/30/014358
//
// orelang を Groovy で実装してみた
//
// "わりとよくある JSON ベースの lisp っぽいインタープリタの実装ですが、コードを見ていてもよくわからなかったので自分で実装しなおしてみました。"
//
class OreLang {
Map<String, Object> vars = [:]
Object eval(List list) {
println "Running: $list"
def result = doRun(list)
println "Result: $list : $result : $vars"
return result
}
Object eval(obj) {
return obj
}
private Object doRun(List list) {
def op = list.head()
def args = list.tail()
switch (op) {
case "set":
vars[args.get(0)] = eval(args.get(1))
return null
case "get":
return vars.get(args.get(0))
case "+":
return eval(args.get(0)) + eval(args.get(1))
case "=":
return eval(args.get(0)) == eval(args.get(1))
case "until":
while (!eval(args.get(0))) {
eval(args.get(1))
}
return null
case "step":
return args.collect { eval(it) }.last()
}
throw new RuntimeException("Unknown operation: " + op)
}
}
String source = """\
|["step",
| ["set", "i", 10],
| ["set", "sum", 0],
| ["until", ["=", ["get", "i"], 0], [
| "step",
| ["set", "sum", ["+", ["get", "sum"], ["get", "i"]]],
| ["set", "i", ["+", ["get", "i"], -1]]
| ]],
| ["get", "sum"]
|]""".stripMargin()
def script = new GroovyShell().evaluate(source)
def result = new OreLang().eval(script)
println "RESULT: $result"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment