Last active
April 26, 2020 08:00
-
-
Save nobeans/c16a89a10d0abc30f357b07d8ecbb795 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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