Created
June 10, 2018 23:40
-
-
Save dglittle/40f77119f017064c49e3fb476cb263fd to your computer and use it in GitHub Desktop.
This file contains 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
var code = '(1 2 (3 4 "h\"i"))' | |
function parse_lisp(code) { | |
var tokens = code.match(/\(|\)|\d+|"[^"]*"/g) | |
var tree = [] | |
function parse_array() { | |
tree = 5 | |
var array = [] | |
while (tokens.length > 0) { | |
var token = tokens.shift() | |
if (token == '(') { | |
array.push(parse_array()) | |
} else if (token == ')') { | |
return array | |
} else if (token.match(/\d+/)) { | |
array.push(1*token) | |
} else if (token.startsWith('"')) { | |
array.push(JSON.parse(token)) | |
} | |
} | |
} | |
if (tokens[0] == '(') { | |
tokens.shift() | |
return parse_array() | |
} | |
} | |
var lisp_variables = [{}] | |
function set_variable(name, val) { | |
for (var i = lisp_variables.length - 1; i >= 0; i--) { | |
var map = lisp_variables[i] | |
if (map.hasOwnProperty(name)) { | |
return map[name] | |
} | |
} | |
lisp_variables[lisp_variables.length - 1][name] = val | |
} | |
function get_variable(name) { | |
for (var i = lisp_variables.length - 1; i >= 0; i--) { | |
var map = lisp_variables[i] | |
if (map.hasOwnProperty(name)) { | |
return map[name] | |
} | |
} | |
} | |
function exec(tree) { | |
if (typeof(tree) == 'object') { | |
if (tree[0] == 'if') { | |
if (exec(tree[1])) { | |
return exec(tree[2]) | |
} else { | |
return exec(tree[3]) | |
} | |
} | |
if (tree[0] == 'while') { | |
while (exec(tree[1])) { | |
exec(tree[2]) | |
} | |
return | |
} | |
if (tree[0] == 'func') { | |
return function (array) { | |
var frame = {} | |
for (var i = 0; i < tree[1].length; i++) { | |
frame[tree[1][i]] = array[i] | |
} | |
lisp_variables.push(frame) | |
var ret = exec(tree[2]) | |
lisp_variables.pop() | |
return ret | |
} | |
} | |
var flattened_array = [] | |
for (var i = 0; i < tree.length; i++) { | |
flattened_array.push(exec(tree[i])) | |
} | |
if (flattened_array[0] == '+') { | |
return flattened_array[1] + flattened_array[2] | |
} else if (typeof(flattened_array[0]) == 'function') { | |
return flattened_array[0](flattened_array.slice(1)) | |
} else if (flattened_array[0] == '*') { | |
return flattened_array[1] * flattened_array[2] | |
} else if (flattened_array[0] == '<') { | |
return flattened_array[1] < flattened_array[2] | |
} else if (flattened_array[0] == 'set') { | |
lisp_variables[flattened_array[1]] = flattened_array[2] | |
} else if (flattened_array[0] == 'get') { | |
return get_variable(flattened_array[1]) | |
} else if (flattened_array[0] == 'do') { | |
} else { | |
console.log('error: undefined function: ' + flattened_array[0]) | |
throw 'bad' | |
} | |
} else { | |
return tree | |
} | |
} | |
var parsed = parse_lisp(code) | |
console.log(parsed) | |
console.log(exec(parsed)) | |
console.log('lisp_variables = ', lisp_variables) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment