1
1
mirror of https://github.com/kanaka/mal.git synced 2024-09-21 10:37:58 +03:00
mal/livescript/step2_eval.ls
2017-05-10 17:57:31 +02:00

54 lines
1.4 KiB
Plaintext

readline = require './node_readline'
{id, map, Obj} = require 'prelude-ls'
{read_str} = require './reader'
{pr_str} = require './printer'
repl_env = do
'+':
type: \function
value: (a, b) -> {type: \int, value: a.value + b.value}
'-':
type: \function
value: (a, b) -> {type: \int, value: a.value - b.value}
'*':
type: \function
value: (a, b) -> {type: \int, value: a.value * b.value}
'/':
type: \function
value: (a, b) -> {type: \int, value: parseInt(a.value / b.value)}
eval_ast = (repl_env, {type, value}: ast) -->
switch type
| \symbol =>
result = repl_env[value]
if not result? then throw new Error 'symbol not found: ', value
result
| \list, \vector =>
result = value |> map eval_ast repl_env
if type == \list and result.length != 0
fn = result[0]
if fn.type != \function
throw new Error fn.value, ' is not a function'
fn.value.apply repl_env, result.slice 1
else
{type: type, value: result}
| \map =>
{type: \map, value: value |> Obj.map eval_ast repl_env}
| otherwise =>
ast
rep = (line) ->
line
|> read_str
|> eval_ast repl_env
|> pr_str
loop
line = readline.readline 'user> '
break if not line? or line == ''
try
console.log rep line
catch {message}
console.error message