1
1
mirror of https://github.com/kanaka/mal.git synced 2024-09-20 01:57:09 +03:00

vimscript: Remove calls to ObjValue

This commit is contained in:
Dov Murik 2016-10-26 06:46:20 +00:00
parent 43d175390a
commit 82641edb65
13 changed files with 233 additions and 237 deletions

View File

@ -1,14 +1,14 @@
" core module
function MalAssoc(args)
let hash = copy(ObjValue(a:args[0]))
let hash = copy(a:args[0].val)
let new_elements = HashBuild(a:args[1:])
call extend(hash, ObjValue(new_elements))
call extend(hash, new_elements.val)
return HashNew(hash)
endfunction
function MalDissoc(args)
let hash = copy(ObjValue(a:args[0]))
let hash = copy(a:args[0].val)
for keyobj in a:args[1:]
let key = HashMakeKey(keyobj)
if has_key(hash, key)
@ -22,7 +22,7 @@ function MalGet(args)
if !HashQ(a:args[0])
return g:MalNil
endif
let hash = ObjValue(a:args[0])
let hash = a:args[0].val
let key = HashMakeKey(a:args[1])
return get(hash, key, g:MalNil)
endfunction
@ -31,14 +31,14 @@ function MalContainsQ(args)
if !HashQ(a:args[0])
return FalseNew()
endif
let hash = ObjValue(a:args[0])
let hash = a:args[0].val
let key = HashMakeKey(a:args[1])
return BoolNew(has_key(hash, key))
endfunction
function MalKeys(args)
let listobjs = []
for keyname in keys(ObjValue(a:args[0]))
for keyname in keys(a:args[0].val)
let keyobj = HashParseKey(keyname)
call add(listobjs, keyobj)
endfor
@ -46,12 +46,12 @@ function MalKeys(args)
endfunction
function MalReadLine(args)
let [eof, line] = Readline(ObjValue(a:args[0]))
let [eof, line] = Readline(a:args[0].val)
return eof ? g:MalNil : StringNew(line)
endfunction
function MalCons(args)
let items = copy(ObjValue(a:args[1]))
let items = copy(a:args[1].val)
call insert(items, a:args[0])
return ListNew(items)
endfunction
@ -59,7 +59,7 @@ endfunction
function MalConcat(args)
let res = []
for list in a:args
let res = res + ObjValue(list)
let res = res + list.val
endfor
return ListNew(res)
endfunction
@ -70,9 +70,9 @@ function MalApply(args)
if len(rest) == 0
let funcargs = []
elseif len(rest) == 1
let funcargs = ObjValue(rest[-1])
let funcargs = rest[-1].val
else
let funcargs = rest[:-2] + ObjValue(rest[-1])
let funcargs = rest[:-2] + rest[-1].val
endif
if NativeFunctionQ(funcobj)
return NativeFuncInvoke(funcobj, ListNew(funcargs))
@ -86,7 +86,7 @@ endfunction
function MalMap(args)
let funcobj = a:args[0]
let res = []
for item in ObjValue(a:args[1])
for item in a:args[1].val
unlet! mappeditem
if NativeFunctionQ(funcobj)
let mappeditem = NativeFuncInvoke(funcobj, ListNew([item]))
@ -115,7 +115,7 @@ function ConjList(list, elements)
endfunction
function ConjVector(vector, elements)
let items = copy(ObjValue(a:vector))
let items = copy(a:vector.val)
for e in a:elements
call add(items, e)
endfor
@ -137,9 +137,9 @@ function MalSeq(args)
elseif ListQ(obj)
return obj
elseif VectorQ(obj)
return ListNew(ObjValue(obj))
return ListNew(obj.val)
elseif StringQ(obj)
return ListNew(map(split(ObjValue(obj), '\zs'), {_, c -> StringNew(c)}))
return ListNew(map(split(obj.val, '\zs'), {_, c -> StringNew(c)}))
endif
throw "seq requires string or list or vector or nil"
endfunction
@ -171,22 +171,22 @@ endfunction
let CoreNs = {
\ "=": NewNativeFnLambda({a -> BoolNew(EqualQ(a[0], a[1]))}),
\ "<": NewNativeFnLambda({a -> BoolNew(ObjValue(a[0]) < ObjValue(a[1]))}),
\ "<=": NewNativeFnLambda({a -> BoolNew(ObjValue(a[0]) <= ObjValue(a[1]))}),
\ ">": NewNativeFnLambda({a -> BoolNew(ObjValue(a[0]) > ObjValue(a[1]))}),
\ ">=": NewNativeFnLambda({a -> BoolNew(ObjValue(a[0]) >= ObjValue(a[1]))}),
\ "+": NewNativeFnLambda({a -> IntegerNew(ObjValue(a[0]) + ObjValue(a[1]))}),
\ "-": NewNativeFnLambda({a -> IntegerNew(ObjValue(a[0]) - ObjValue(a[1]))}),
\ "*": NewNativeFnLambda({a -> IntegerNew(ObjValue(a[0]) * ObjValue(a[1]))}),
\ "/": NewNativeFnLambda({a -> IntegerNew(ObjValue(a[0]) / ObjValue(a[1]))}),
\ "<": NewNativeFnLambda({a -> BoolNew(a[0].val < a[1].val)}),
\ "<=": NewNativeFnLambda({a -> BoolNew(a[0].val <= a[1].val)}),
\ ">": NewNativeFnLambda({a -> BoolNew(a[0].val > a[1].val)}),
\ ">=": NewNativeFnLambda({a -> BoolNew(a[0].val >= a[1].val)}),
\ "+": NewNativeFnLambda({a -> IntegerNew(a[0].val + a[1].val)}),
\ "-": NewNativeFnLambda({a -> IntegerNew(a[0].val - a[1].val)}),
\ "*": NewNativeFnLambda({a -> IntegerNew(a[0].val * a[1].val)}),
\ "/": NewNativeFnLambda({a -> IntegerNew(a[0].val / a[1].val)}),
\ "time-ms": NewNativeFnLambda({a -> IntegerNew(libcallnr("libvimextras.so", "vimtimems", 0))}),
\ "nil?": NewNativeFnLambda({a -> BoolNew(NilQ(a[0]))}),
\ "true?": NewNativeFnLambda({a -> BoolNew(TrueQ(a[0]))}),
\ "false?": NewNativeFnLambda({a -> BoolNew(FalseQ(a[0]))}),
\ "symbol": NewNativeFnLambda({a -> SymbolNew(ObjValue(a[0]))}),
\ "symbol": NewNativeFnLambda({a -> SymbolNew(a[0].val)}),
\ "symbol?": NewNativeFnLambda({a -> BoolNew(SymbolQ(a[0]))}),
\ "string?": NewNativeFnLambda({a -> BoolNew(StringQ(a[0]))}),
\ "keyword": NewNativeFnLambda({a -> KeywordNew(ObjValue(a[0]))}),
\ "keyword": NewNativeFnLambda({a -> KeywordNew(a[0].val)}),
\ "keyword?": NewNativeFnLambda({a -> BoolNew(KeywordQ(a[0]))}),
\ "list": NewNativeFnLambda({a -> ListNew(a)}),
\ "list?": NewNativeFnLambda({a -> BoolNew(ListQ(a[0]))}),
@ -202,18 +202,18 @@ let CoreNs = {
\ "get": NewNativeFn("MalGet"),
\ "contains?": NewNativeFn("MalContainsQ"),
\ "keys": NewNativeFn("MalKeys"),
\ "vals": NewNativeFnLambda({a -> ListNew(values(ObjValue(a[0])))}),
\ "vals": NewNativeFnLambda({a -> ListNew(values(a[0].val))}),
\ "pr-str": NewNativeFnLambda({a -> StringNew(join(map(copy(a), {_, e -> PrStr(e, 1)}), " "))}),
\ "str": NewNativeFnLambda({a -> StringNew(join(map(copy(a), {_, e -> PrStr(e, 0)}), ""))}),
\ "prn": NewNativeFnLambda({a -> [PrintLn(join(map(copy(a), {_, e -> PrStr(e, 1)}), " ")), g:MalNil][1]}),
\ "println": NewNativeFnLambda({a -> [PrintLn(join(map(copy(a), {_, e -> PrStr(e, 0)}), " ")), g:MalNil][1]}),
\ "read-string": NewNativeFnLambda({a -> ReadStr(ObjValue(a[0]))}),
\ "read-string": NewNativeFnLambda({a -> ReadStr(a[0].val)}),
\ "readline": NewNativeFn("MalReadLine"),
\ "slurp": NewNativeFnLambda({a -> StringNew(join(readfile(ObjValue(a[0]), "b"), "\n"))}),
\ "slurp": NewNativeFnLambda({a -> StringNew(join(readfile(a[0].val, "b"), "\n"))}),
\ "cons": NewNativeFn("MalCons"),
\ "concat": NewNativeFn("MalConcat"),
\ "first": NewNativeFnLambda({a -> NilQ(a[0]) ? g:MalNil : ListFirst(a[0])}),
\ "nth": NewNativeFnLambda({a -> ListNth(a[0], ObjValue(a[1]))}),
\ "nth": NewNativeFnLambda({a -> ListNth(a[0], a[1].val)}),
\ "rest": NewNativeFnLambda({a -> NilQ(a[0]) ? ListNew([]) : ListRest(a[0])}),
\ "apply": NewNativeFn("MalApply"),
\ "map": NewNativeFn("MalMap"),
@ -221,11 +221,11 @@ let CoreNs = {
\ "conj": NewNativeFn("MalConj"),
\ "seq": NewNativeFn("MalSeq"),
\ "meta": NewNativeFnLambda({a -> ObjMeta(a[0])}),
\ "with-meta": NewNativeFnLambda({a -> ObjNewWithMeta(ObjType(a[0]), copy(ObjValue(a[0])), a[1])}),
\ "with-meta": NewNativeFnLambda({a -> ObjNewWithMeta(ObjType(a[0]), copy(a[0].val), a[1])}),
\ "atom": NewNativeFnLambda({a -> AtomNew(a[0])}),
\ "atom?": NewNativeFnLambda({a -> BoolNew(AtomQ(a[0]))}),
\ "deref": NewNativeFnLambda({a -> ObjValue(a[0])}),
\ "deref": NewNativeFnLambda({a -> a[0].val}),
\ "reset!": NewNativeFnLambda({a -> ObjSetValue(a[0], a[1])}),
\ "swap!": NewNativeFnLambda({a -> ObjSetValue(a[0], MalApply([a[1], ListNew([ObjValue(a[0])] + a[2:])]))}),
\ "vim*": NewNativeFnLambda({a -> VimToMal(eval(ObjValue(a[0])))})
\ "swap!": NewNativeFnLambda({a -> ObjSetValue(a[0], MalApply([a[1], ListNew([a[0].val] + a[2:])]))}),
\ "vim*": NewNativeFnLambda({a -> VimToMal(eval(a[0].val))})
\ }

View File

@ -13,10 +13,10 @@ function NewEnvWithBinds(outer, binds, exprs)
let env = NewEnv(a:outer)
let i = 0
while i < ListCount(a:binds)
let varname = ObjValue(ListNth(a:binds, i))
let varname = ListNth(a:binds, i).val
if varname == "&"
" TODO
let restvarname = ObjValue(ListNth(a:binds, i + 1))
let restvarname = ListNth(a:binds, i + 1).val
let restvarvalues = ListDrop(a:exprs, i)
call env.set(restvarname, restvarvalues)
break

View File

@ -5,46 +5,46 @@ function PrStr(ast, readable)
let r = a:readable
if ListQ(obj)
let ret = []
for e in ObjValue(obj)
for e in obj.val
call add(ret, PrStr(e, r))
endfor
return "(" . join(ret, " ") . ")"
elseif VectorQ(obj)
let ret = []
for e in ObjValue(obj)
for e in obj.val
call add(ret, PrStr(e, r))
endfor
return "[" . join(ret, " ") . "]"
elseif HashQ(obj)
let ret = []
for [k, v] in items(ObjValue(obj))
for [k, v] in items(obj.val)
let keyobj = HashParseKey(k)
call add(ret, PrStr(keyobj, r))
call add(ret, PrStr(v, r))
endfor
return "{" . join(ret, " ") . "}"
elseif MacroQ(obj)
let numargs = ListCount(ObjValue(obj).params)
let numargs = ListCount(obj.val.params)
return "<Macro:" . numargs . "-arguments>"
elseif FunctionQ(obj)
let numargs = ListCount(ObjValue(obj).params)
let numargs = ListCount(obj.val.params)
return "<Function:" . numargs . "-arguments>"
elseif NativeFunctionQ(obj)
let funcname = ObjValue(obj).name
let funcname = obj.val.name
return "<NativeFunction:" . funcname . ">"
elseif AtomQ(obj)
return "(atom " . PrStr(ObjValue(obj), 1) . ")"
return "(atom " . PrStr(obj.val, 1) . ")"
elseif KeywordQ(obj)
return ':' . ObjValue(obj)
return ':' . obj.val
elseif StringQ(obj)
if r
let str = ObjValue(obj)
let str = obj.val
let str = substitute(str, '\\', '\\\\', "g")
let str = substitute(str, '"', '\\"', "g")
let str = substitute(str, "\n", '\\n', "g")
return '"' . str . '"'
else
return ObjValue(obj)
return obj.val
endif
elseif NilQ(obj)
return "nil"
@ -53,8 +53,8 @@ function PrStr(ast, readable)
elseif FalseQ(obj)
return "false"
elseif IntegerQ(obj) || FloatQ(obj)
return string(ObjValue(obj))
return string(obj.val)
else
return ObjValue(obj)
return obj.val
end
endfunction

View File

@ -9,26 +9,26 @@ endfunction
function EvalAst(ast, env)
if SymbolQ(a:ast)
let varname = ObjValue(a:ast)
let varname = a:ast.val
if !has_key(a:env, varname)
throw "'" . varname . "' not found"
end
return a:env[varname]
elseif ListQ(a:ast)
let ret = []
for e in ObjValue(a:ast)
for e in a:ast.val
call add(ret, EVAL(e, a:env))
endfor
return ListNew(ret)
elseif VectorQ(a:ast)
let ret = []
for e in ObjValue(a:ast)
for e in a:ast.val
call add(ret, EVAL(e, a:env))
endfor
return VectorNew(ret)
elseif HashQ(a:ast)
let ret = {}
for [k,v] in items(ObjValue(a:ast))
for [k,v] in items(a:ast.val)
let keyobj = HashParseKey(k)
let newkey = EVAL(keyobj, a:env)
let newval = EVAL(v, a:env)
@ -52,8 +52,8 @@ function EVAL(ast, env)
" apply list
let el = EvalAst(a:ast, a:env)
let Fn = ObjValue(el)[0]
return Fn(ObjValue(el)[1:-1])
let Fn = el.val[0]
return Fn(el.val[1:-1])
endfunction
function PRINT(exp)

View File

@ -10,23 +10,23 @@ endfunction
function EvalAst(ast, env)
if SymbolQ(a:ast)
let varname = ObjValue(a:ast)
let varname = a:ast.val
return a:env.get(varname)
elseif ListQ(a:ast)
let ret = []
for e in ObjValue(a:ast)
for e in a:ast.val
call add(ret, EVAL(e, a:env))
endfor
return ListNew(ret)
elseif VectorQ(a:ast)
let ret = []
for e in ObjValue(a:ast)
for e in a:ast.val
call add(ret, EVAL(e, a:env))
endfor
return VectorNew(ret)
elseif HashQ(a:ast)
let ret = {}
for [k,v] in items(ObjValue(a:ast))
for [k,v] in items(a:ast.val)
let keyobj = HashParseKey(k)
let newkey = EVAL(keyobj, a:env)
let newval = EVAL(v, a:env)
@ -47,27 +47,27 @@ function EVAL(ast, env)
return a:ast
endif
let first_symbol = ObjValue(ObjValue(a:ast)[0])
let first_symbol = a:ast.val[0].val
if first_symbol == "def!"
let a1 = ObjValue(a:ast)[1]
let a2 = ObjValue(a:ast)[2]
return a:env.set(ObjValue(a1), EVAL(a2, a:env))
let a1 = a:ast.val[1]
let a2 = a:ast.val[2]
return a:env.set(a1.val, EVAL(a2, a:env))
elseif first_symbol == "let*"
let a1 = ObjValue(a:ast)[1]
let a2 = ObjValue(a:ast)[2]
let a1 = a:ast.val[1]
let a2 = a:ast.val[2]
let let_env = NewEnv(a:env)
let let_binds = ObjValue(a1)
let let_binds = a1.val
let i = 0
while i < len(let_binds)
call let_env.set(ObjValue(let_binds[i]), EVAL(let_binds[i+1], let_env))
call let_env.set(let_binds[i].val, EVAL(let_binds[i+1], let_env))
let i = i + 2
endwhile
return EVAL(a2, let_env)
else
" apply list
let el = EvalAst(a:ast, a:env)
let Fn = ObjValue(el)[0]
return Fn(ObjValue(el)[1:-1])
let Fn = el.val[0]
return Fn(el.val[1:-1])
endif
endfunction

View File

@ -11,23 +11,23 @@ endfunction
function EvalAst(ast, env)
if SymbolQ(a:ast)
let varname = ObjValue(a:ast)
let varname = a:ast.val
return a:env.get(varname)
elseif ListQ(a:ast)
let ret = []
for e in ObjValue(a:ast)
for e in a:ast.val
call add(ret, EVAL(e, a:env))
endfor
return ListNew(ret)
elseif VectorQ(a:ast)
let ret = []
for e in ObjValue(a:ast)
for e in a:ast.val
call add(ret, EVAL(e, a:env))
endfor
return VectorNew(ret)
elseif HashQ(a:ast)
let ret = {}
for [k,v] in items(ObjValue(a:ast))
for [k,v] in items(a:ast.val)
let keyobj = HashParseKey(k)
let newkey = EVAL(keyobj, a:env)
let newval = EVAL(v, a:env)
@ -49,37 +49,37 @@ function EVAL(ast, env)
endif
let first = ListFirst(a:ast)
let first_symbol = SymbolQ(first) ? ObjValue(first) : ""
let first_symbol = SymbolQ(first) ? first.val : ""
if first_symbol == "def!"
let a1 = ObjValue(a:ast)[1]
let a2 = ObjValue(a:ast)[2]
let ret = a:env.set(ObjValue(a1), EVAL(a2, a:env))
let a1 = a:ast.val[1]
let a2 = a:ast.val[2]
let ret = a:env.set(a1.val, EVAL(a2, a:env))
return ret
elseif first_symbol == "let*"
let a1 = ObjValue(a:ast)[1]
let a2 = ObjValue(a:ast)[2]
let a1 = a:ast.val[1]
let a2 = a:ast.val[2]
let let_env = NewEnv(a:env)
let let_binds = ObjValue(a1)
let let_binds = a1.val
let i = 0
while i < len(let_binds)
call let_env.set(ObjValue(let_binds[i]), EVAL(let_binds[i+1], let_env))
call let_env.set(let_binds[i].val, EVAL(let_binds[i+1], let_env))
let i = i + 2
endwhile
return EVAL(a2, let_env)
elseif first_symbol == "if"
let condvalue = EVAL(ObjValue(a:ast)[1], a:env)
let condvalue = EVAL(a:ast.val[1], a:env)
if FalseQ(condvalue) || NilQ(condvalue)
if len(ObjValue(a:ast)) < 4
if len(a:ast.val) < 4
return g:MalNil
else
return EVAL(ObjValue(a:ast)[3], a:env)
return EVAL(a:ast.val[3], a:env)
endif
else
return EVAL(ObjValue(a:ast)[2], a:env)
return EVAL(a:ast.val[2], a:env)
endif
elseif first_symbol == "do"
let el = EvalAst(ListRest(a:ast), a:env)
return ObjValue(el)[-1]
return el.val[-1]
elseif first_symbol == "fn*"
let fn = NewFn(ListNth(a:ast, 2), a:env, ListNth(a:ast, 1))
return fn

View File

@ -11,23 +11,23 @@ endfunction
function EvalAst(ast, env)
if SymbolQ(a:ast)
let varname = ObjValue(a:ast)
let varname = a:ast.val
return a:env.get(varname)
elseif ListQ(a:ast)
let ret = []
for e in ObjValue(a:ast)
for e in a:ast.val
call add(ret, EVAL(e, a:env))
endfor
return ListNew(ret)
elseif VectorQ(a:ast)
let ret = []
for e in ObjValue(a:ast)
for e in a:ast.val
call add(ret, EVAL(e, a:env))
endfor
return VectorNew(ret)
elseif HashQ(a:ast)
let ret = {}
for [k,v] in items(ObjValue(a:ast))
for [k,v] in items(a:ast.val)
let keyobj = HashParseKey(k)
let newkey = EVAL(keyobj, a:env)
let newval = EVAL(v, a:env)
@ -53,38 +53,38 @@ function EVAL(ast, env)
endif
let first = ListFirst(ast)
let first_symbol = SymbolQ(first) ? ObjValue(first) : ""
let first_symbol = SymbolQ(first) ? first.val : ""
if first_symbol == "def!"
let a1 = ObjValue(ast)[1]
let a2 = ObjValue(ast)[2]
let ret = env.set(ObjValue(a1), EVAL(a2, env))
let a1 = ast.val[1]
let a2 = ast.val[2]
let ret = env.set(a1.val, EVAL(a2, env))
return ret
elseif first_symbol == "let*"
let a1 = ObjValue(ast)[1]
let a2 = ObjValue(ast)[2]
let a1 = ast.val[1]
let a2 = ast.val[2]
let env = NewEnv(env)
let let_binds = ObjValue(a1)
let let_binds = a1.val
let i = 0
while i < len(let_binds)
call env.set(ObjValue(let_binds[i]), EVAL(let_binds[i+1], env))
call env.set(let_binds[i].val, EVAL(let_binds[i+1], env))
let i = i + 2
endwhile
let ast = a2
" TCO
elseif first_symbol == "if"
let condvalue = EVAL(ObjValue(ast)[1], env)
let condvalue = EVAL(ast.val[1], env)
if FalseQ(condvalue) || NilQ(condvalue)
if len(ObjValue(ast)) < 4
if len(ast.val) < 4
return g:MalNil
else
let ast = ObjValue(ast)[3]
let ast = ast.val[3]
endif
else
let ast = ObjValue(ast)[2]
let ast = ast.val[2]
endif
" TCO
elseif first_symbol == "do"
let astlist = ObjValue(ast)
let astlist = ast.val
call EvalAst(ListNew(astlist[1:-2]), env)
let ast = astlist[-1]
" TCO
@ -99,7 +99,7 @@ function EVAL(ast, env)
if NativeFunctionQ(funcobj)
return NativeFuncInvoke(funcobj, args)
elseif FunctionQ(funcobj)
let fn = ObjValue(funcobj)
let fn = funcobj.val
let ast = fn.ast
let env = NewEnvWithBinds(fn.env, fn.params, args)
" TCO

View File

@ -11,23 +11,23 @@ endfunction
function EvalAst(ast, env)
if SymbolQ(a:ast)
let varname = ObjValue(a:ast)
let varname = a:ast.val
return a:env.get(varname)
elseif ListQ(a:ast)
let ret = []
for e in ObjValue(a:ast)
for e in a:ast.val
call add(ret, EVAL(e, a:env))
endfor
return ListNew(ret)
elseif VectorQ(a:ast)
let ret = []
for e in ObjValue(a:ast)
for e in a:ast.val
call add(ret, EVAL(e, a:env))
endfor
return VectorNew(ret)
elseif HashQ(a:ast)
let ret = {}
for [k,v] in items(ObjValue(a:ast))
for [k,v] in items(a:ast.val)
let keyobj = HashParseKey(k)
let newkey = EVAL(keyobj, a:env)
let newval = EVAL(v, a:env)
@ -53,38 +53,38 @@ function EVAL(ast, env)
endif
let first = ListFirst(ast)
let first_symbol = SymbolQ(first) ? ObjValue(first) : ""
let first_symbol = SymbolQ(first) ? first.val : ""
if first_symbol == "def!"
let a1 = ObjValue(ast)[1]
let a2 = ObjValue(ast)[2]
let ret = env.set(ObjValue(a1), EVAL(a2, env))
let a1 = ast.val[1]
let a2 = ast.val[2]
let ret = env.set(a1.val, EVAL(a2, env))
return ret
elseif first_symbol == "let*"
let a1 = ObjValue(ast)[1]
let a2 = ObjValue(ast)[2]
let a1 = ast.val[1]
let a2 = ast.val[2]
let env = NewEnv(env)
let let_binds = ObjValue(a1)
let let_binds = a1.val
let i = 0
while i < len(let_binds)
call env.set(ObjValue(let_binds[i]), EVAL(let_binds[i+1], env))
call env.set(let_binds[i].val, EVAL(let_binds[i+1], env))
let i = i + 2
endwhile
let ast = a2
" TCO
elseif first_symbol == "if"
let condvalue = EVAL(ObjValue(ast)[1], env)
let condvalue = EVAL(ast.val[1], env)
if FalseQ(condvalue) || NilQ(condvalue)
if len(ObjValue(ast)) < 4
if len(ast.val) < 4
return g:MalNil
else
let ast = ObjValue(ast)[3]
let ast = ast.val[3]
endif
else
let ast = ObjValue(ast)[2]
let ast = ast.val[2]
endif
" TCO
elseif first_symbol == "do"
let astlist = ObjValue(ast)
let astlist = ast.val
call EvalAst(ListNew(astlist[1:-2]), env)
let ast = astlist[-1]
" TCO
@ -103,7 +103,7 @@ function EVAL(ast, env)
if NativeFunctionQ(funcobj)
return NativeFuncInvoke(funcobj, args)
elseif FunctionQ(funcobj)
let fn = ObjValue(funcobj)
let fn = funcobj.val
let ast = fn.ast
let env = NewEnvWithBinds(fn.env, fn.params, args)
" TCO

View File

@ -18,9 +18,9 @@ function Quasiquote(ast)
return ListNew([SymbolNew("quote"), a:ast])
endif
let a0 = ListFirst(a:ast)
if SymbolQ(a0) && ObjValue(a0) == "unquote"
if SymbolQ(a0) && a0.val == "unquote"
return ListNth(a:ast, 1)
elseif PairQ(a0) && SymbolQ(ListFirst(a0)) && ObjValue(ListFirst(a0)) == "splice-unquote"
elseif PairQ(a0) && SymbolQ(ListFirst(a0)) && ListFirst(a0).val == "splice-unquote"
return ListNew([SymbolNew("concat"), ListNth(a0, 1), Quasiquote(ListRest(a:ast))])
else
return ListNew([SymbolNew("cons"), Quasiquote(a0), Quasiquote(ListRest(a:ast))])
@ -29,23 +29,23 @@ endfunction
function EvalAst(ast, env)
if SymbolQ(a:ast)
let varname = ObjValue(a:ast)
let varname = a:ast.val
return a:env.get(varname)
elseif ListQ(a:ast)
let ret = []
for e in ObjValue(a:ast)
for e in a:ast.val
call add(ret, EVAL(e, a:env))
endfor
return ListNew(ret)
elseif VectorQ(a:ast)
let ret = []
for e in ObjValue(a:ast)
for e in a:ast.val
call add(ret, EVAL(e, a:env))
endfor
return VectorNew(ret)
elseif HashQ(a:ast)
let ret = {}
for [k,v] in items(ObjValue(a:ast))
for [k,v] in items(a:ast.val)
let keyobj = HashParseKey(k)
let newkey = EVAL(keyobj, a:env)
let newval = EVAL(v, a:env)
@ -71,20 +71,20 @@ function EVAL(ast, env)
endif
let first = ListFirst(ast)
let first_symbol = SymbolQ(first) ? ObjValue(first) : ""
let first_symbol = SymbolQ(first) ? first.val : ""
if first_symbol == "def!"
let a1 = ObjValue(ast)[1]
let a2 = ObjValue(ast)[2]
let ret = env.set(ObjValue(a1), EVAL(a2, env))
let a1 = ast.val[1]
let a2 = ast.val[2]
let ret = env.set(a1.val, EVAL(a2, env))
return ret
elseif first_symbol == "let*"
let a1 = ObjValue(ast)[1]
let a2 = ObjValue(ast)[2]
let a1 = ast.val[1]
let a2 = ast.val[2]
let env = NewEnv(env)
let let_binds = ObjValue(a1)
let let_binds = a1.val
let i = 0
while i < len(let_binds)
call env.set(ObjValue(let_binds[i]), EVAL(let_binds[i+1], env))
call env.set(let_binds[i].val, EVAL(let_binds[i+1], env))
let i = i + 2
endwhile
let ast = a2
@ -95,19 +95,19 @@ function EVAL(ast, env)
let ast = Quasiquote(ListNth(ast, 1))
" TCO
elseif first_symbol == "if"
let condvalue = EVAL(ObjValue(ast)[1], env)
let condvalue = EVAL(ast.val[1], env)
if FalseQ(condvalue) || NilQ(condvalue)
if len(ObjValue(ast)) < 4
if len(ast.val) < 4
return g:MalNil
else
let ast = ObjValue(ast)[3]
let ast = ast.val[3]
endif
else
let ast = ObjValue(ast)[2]
let ast = ast.val[2]
endif
" TCO
elseif first_symbol == "do"
let astlist = ObjValue(ast)
let astlist = ast.val
call EvalAst(ListNew(astlist[1:-2]), env)
let ast = astlist[-1]
" TCO
@ -126,7 +126,7 @@ function EVAL(ast, env)
if NativeFunctionQ(funcobj)
return NativeFuncInvoke(funcobj, args)
elseif FunctionQ(funcobj)
let fn = ObjValue(funcobj)
let fn = funcobj.val
let ast = fn.ast
let env = NewEnvWithBinds(fn.env, fn.params, args)
" TCO

View File

@ -18,9 +18,9 @@ function Quasiquote(ast)
return ListNew([SymbolNew("quote"), a:ast])
endif
let a0 = ListFirst(a:ast)
if SymbolQ(a0) && ObjValue(a0) == "unquote"
if SymbolQ(a0) && a0.val == "unquote"
return ListNth(a:ast, 1)
elseif PairQ(a0) && SymbolQ(ListFirst(a0)) && ObjValue(ListFirst(a0)) == "splice-unquote"
elseif PairQ(a0) && SymbolQ(ListFirst(a0)) && ListFirst(a0).val == "splice-unquote"
return ListNew([SymbolNew("concat"), ListNth(a0, 1), Quasiquote(ListRest(a:ast))])
else
return ListNew([SymbolNew("cons"), Quasiquote(a0), Quasiquote(ListRest(a:ast))])
@ -35,7 +35,7 @@ function IsMacroCall(ast, env)
if !SymbolQ(a0)
return 0
endif
let macroname = ObjValue(a0)
let macroname = a0.val
if empty(a:env.find(macroname))
return 0
endif
@ -45,7 +45,7 @@ endfunction
function MacroExpand(ast, env)
let ast = a:ast
while IsMacroCall(ast, a:env)
let macroobj = a:env.get(ObjValue(ListFirst(ast)))
let macroobj = a:env.get(ListFirst(ast).val)
let macroargs = ListRest(ast)
let ast = FuncInvoke(macroobj, macroargs)
endwhile
@ -54,23 +54,23 @@ endfunction
function EvalAst(ast, env)
if SymbolQ(a:ast)
let varname = ObjValue(a:ast)
let varname = a:ast.val
return a:env.get(varname)
elseif ListQ(a:ast)
let ret = []
for e in ObjValue(a:ast)
for e in a:ast.val
call add(ret, EVAL(e, a:env))
endfor
return ListNew(ret)
elseif VectorQ(a:ast)
let ret = []
for e in ObjValue(a:ast)
for e in a:ast.val
call add(ret, EVAL(e, a:env))
endfor
return VectorNew(ret)
elseif HashQ(a:ast)
let ret = {}
for [k,v] in items(ObjValue(a:ast))
for [k,v] in items(a:ast.val)
let keyobj = HashParseKey(k)
let newkey = EVAL(keyobj, a:env)
let newval = EVAL(v, a:env)
@ -101,19 +101,19 @@ function EVAL(ast, env)
endif
let first = ListFirst(ast)
let first_symbol = SymbolQ(first) ? ObjValue(first) : ""
let first_symbol = SymbolQ(first) ? first.val : ""
if first_symbol == "def!"
let a1 = ObjValue(ast)[1]
let a2 = ObjValue(ast)[2]
return env.set(ObjValue(a1), EVAL(a2, env))
let a1 = ast.val[1]
let a2 = ast.val[2]
return env.set(a1.val, EVAL(a2, env))
elseif first_symbol == "let*"
let a1 = ObjValue(ast)[1]
let a2 = ObjValue(ast)[2]
let a1 = ast.val[1]
let a2 = ast.val[2]
let env = NewEnv(env)
let let_binds = ObjValue(a1)
let let_binds = a1.val
let i = 0
while i < len(let_binds)
call env.set(ObjValue(let_binds[i]), EVAL(let_binds[i+1], env))
call env.set(let_binds[i].val, EVAL(let_binds[i+1], env))
let i = i + 2
endwhile
let ast = a2
@ -127,23 +127,23 @@ function EVAL(ast, env)
let a1 = ListNth(ast, 1)
let a2 = ListNth(ast, 2)
let macro = MarkAsMacro(EVAL(a2, env))
return env.set(ObjValue(a1), macro)
return env.set(a1.val, macro)
elseif first_symbol == "macroexpand"
return MacroExpand(ListNth(ast, 1), env)
elseif first_symbol == "if"
let condvalue = EVAL(ObjValue(ast)[1], env)
let condvalue = EVAL(ast.val[1], env)
if FalseQ(condvalue) || NilQ(condvalue)
if len(ObjValue(ast)) < 4
if len(ast.val) < 4
return g:MalNil
else
let ast = ObjValue(ast)[3]
let ast = ast.val[3]
endif
else
let ast = ObjValue(ast)[2]
let ast = ast.val[2]
endif
" TCO
elseif first_symbol == "do"
let astlist = ObjValue(ast)
let astlist = ast.val
call EvalAst(ListNew(astlist[1:-2]), env)
let ast = astlist[-1]
" TCO
@ -162,7 +162,7 @@ function EVAL(ast, env)
if NativeFunctionQ(funcobj)
return NativeFuncInvoke(funcobj, args)
elseif FunctionQ(funcobj)
let fn = ObjValue(funcobj)
let fn = funcobj.val
let ast = fn.ast
let env = NewEnvWithBinds(fn.env, fn.params, args)
" TCO

View File

@ -20,9 +20,9 @@ function Quasiquote(ast)
return ListNew([SymbolNew("quote"), a:ast])
endif
let a0 = ListFirst(a:ast)
if SymbolQ(a0) && ObjValue(a0) == "unquote"
if SymbolQ(a0) && a0.val == "unquote"
return ListNth(a:ast, 1)
elseif PairQ(a0) && SymbolQ(ListFirst(a0)) && ObjValue(ListFirst(a0)) == "splice-unquote"
elseif PairQ(a0) && SymbolQ(ListFirst(a0)) && ListFirst(a0).val == "splice-unquote"
return ListNew([SymbolNew("concat"), ListNth(a0, 1), Quasiquote(ListRest(a:ast))])
else
return ListNew([SymbolNew("cons"), Quasiquote(a0), Quasiquote(ListRest(a:ast))])
@ -37,7 +37,7 @@ function IsMacroCall(ast, env)
if !SymbolQ(a0)
return 0
endif
let macroname = ObjValue(a0)
let macroname = a0.val
if empty(a:env.find(macroname))
return 0
endif
@ -47,7 +47,7 @@ endfunction
function MacroExpand(ast, env)
let ast = a:ast
while IsMacroCall(ast, a:env)
let macroobj = a:env.get(ObjValue(ListFirst(ast)))
let macroobj = a:env.get(ListFirst(ast).val)
let macroargs = ListRest(ast)
let ast = FuncInvoke(macroobj, macroargs)
endwhile
@ -56,23 +56,23 @@ endfunction
function EvalAst(ast, env)
if SymbolQ(a:ast)
let varname = ObjValue(a:ast)
let varname = a:ast.val
return a:env.get(varname)
elseif ListQ(a:ast)
let ret = []
for e in ObjValue(a:ast)
for e in a:ast.val
call add(ret, EVAL(e, a:env))
endfor
return ListNew(ret)
elseif VectorQ(a:ast)
let ret = []
for e in ObjValue(a:ast)
for e in a:ast.val
call add(ret, EVAL(e, a:env))
endfor
return VectorNew(ret)
elseif HashQ(a:ast)
let ret = {}
for [k,v] in items(ObjValue(a:ast))
for [k,v] in items(a:ast.val)
let keyobj = HashParseKey(k)
let newkey = EVAL(keyobj, a:env)
let newval = EVAL(v, a:env)
@ -115,19 +115,19 @@ function EVAL(ast, env)
endif
let first = ListFirst(ast)
let first_symbol = SymbolQ(first) ? ObjValue(first) : ""
let first_symbol = SymbolQ(first) ? first.val : ""
if first_symbol == "def!"
let a1 = ObjValue(ast)[1]
let a2 = ObjValue(ast)[2]
return env.set(ObjValue(a1), EVAL(a2, env))
let a1 = ast.val[1]
let a2 = ast.val[2]
return env.set(a1.val, EVAL(a2, env))
elseif first_symbol == "let*"
let a1 = ObjValue(ast)[1]
let a2 = ObjValue(ast)[2]
let a1 = ast.val[1]
let a2 = ast.val[2]
let env = NewEnv(env)
let let_binds = ObjValue(a1)
let let_binds = a1.val
let i = 0
while i < len(let_binds)
call env.set(ObjValue(let_binds[i]), EVAL(let_binds[i+1], env))
call env.set(let_binds[i].val, EVAL(let_binds[i+1], env))
let i = i + 2
endwhile
let ast = a2
@ -141,19 +141,19 @@ function EVAL(ast, env)
let a1 = ListNth(ast, 1)
let a2 = ListNth(ast, 2)
let macro = MarkAsMacro(EVAL(a2, env))
return env.set(ObjValue(a1), macro)
return env.set(a1.val, macro)
elseif first_symbol == "macroexpand"
return MacroExpand(ListNth(ast, 1), env)
elseif first_symbol == "if"
let condvalue = EVAL(ObjValue(ast)[1], env)
let condvalue = EVAL(ast.val[1], env)
if FalseQ(condvalue) || NilQ(condvalue)
if len(ObjValue(ast)) < 4
if len(ast.val) < 4
return g:MalNil
else
let ast = ObjValue(ast)[3]
let ast = ast.val[3]
endif
else
let ast = ObjValue(ast)[2]
let ast = ast.val[2]
endif
" TCO
elseif first_symbol == "try*"
@ -165,7 +165,7 @@ function EVAL(ast, env)
throw v:exception
endif
let exc_var = ObjValue(ListNth(catch_clause, 1))
let exc_var = ListNth(catch_clause, 1).val
if v:exception == "__MalException__"
let exc_value = g:MalExceptionObj
else
@ -175,7 +175,7 @@ function EVAL(ast, env)
return EVAL(ListNth(catch_clause, 2), catch_env)
endtry
elseif first_symbol == "do"
let astlist = ObjValue(ast)
let astlist = ast.val
call EvalAst(ListNew(astlist[1:-2]), env)
let ast = astlist[-1]
" TCO
@ -194,7 +194,7 @@ function EVAL(ast, env)
if NativeFunctionQ(funcobj)
return NativeFuncInvoke(funcobj, args)
elseif FunctionQ(funcobj)
let fn = ObjValue(funcobj)
let fn = funcobj.val
let ast = fn.ast
let env = NewEnvWithBinds(fn.env, fn.params, args)
" TCO

View File

@ -20,9 +20,9 @@ function Quasiquote(ast)
return ListNew([SymbolNew("quote"), a:ast])
endif
let a0 = ListFirst(a:ast)
if SymbolQ(a0) && ObjValue(a0) == "unquote"
if SymbolQ(a0) && a0.val == "unquote"
return ListNth(a:ast, 1)
elseif PairQ(a0) && SymbolQ(ListFirst(a0)) && ObjValue(ListFirst(a0)) == "splice-unquote"
elseif PairQ(a0) && SymbolQ(ListFirst(a0)) && ListFirst(a0).val == "splice-unquote"
return ListNew([SymbolNew("concat"), ListNth(a0, 1), Quasiquote(ListRest(a:ast))])
else
return ListNew([SymbolNew("cons"), Quasiquote(a0), Quasiquote(ListRest(a:ast))])
@ -37,7 +37,7 @@ function IsMacroCall(ast, env)
if !SymbolQ(a0)
return 0
endif
let macroname = ObjValue(a0)
let macroname = a0.val
if empty(a:env.find(macroname))
return 0
endif
@ -47,7 +47,7 @@ endfunction
function MacroExpand(ast, env)
let ast = a:ast
while IsMacroCall(ast, a:env)
let macroobj = a:env.get(ObjValue(ListFirst(ast)))
let macroobj = a:env.get(ListFirst(ast).val)
let macroargs = ListRest(ast)
let ast = FuncInvoke(macroobj, macroargs)
endwhile
@ -56,23 +56,23 @@ endfunction
function EvalAst(ast, env)
if SymbolQ(a:ast)
let varname = ObjValue(a:ast)
let varname = a:ast.val
return a:env.get(varname)
elseif ListQ(a:ast)
let ret = []
for e in ObjValue(a:ast)
for e in a:ast.val
call add(ret, EVAL(e, a:env))
endfor
return ListNew(ret)
elseif VectorQ(a:ast)
let ret = []
for e in ObjValue(a:ast)
for e in a:ast.val
call add(ret, EVAL(e, a:env))
endfor
return VectorNew(ret)
elseif HashQ(a:ast)
let ret = {}
for [k,v] in items(ObjValue(a:ast))
for [k,v] in items(a:ast.val)
let keyobj = HashParseKey(k)
let newkey = EVAL(keyobj, a:env)
let newval = EVAL(v, a:env)
@ -115,19 +115,19 @@ function EVAL(ast, env)
endif
let first = ListFirst(ast)
let first_symbol = SymbolQ(first) ? ObjValue(first) : ""
let first_symbol = SymbolQ(first) ? first.val : ""
if first_symbol == "def!"
let a1 = ObjValue(ast)[1]
let a2 = ObjValue(ast)[2]
return env.set(ObjValue(a1), EVAL(a2, env))
let a1 = ast.val[1]
let a2 = ast.val[2]
return env.set(a1.val, EVAL(a2, env))
elseif first_symbol == "let*"
let a1 = ObjValue(ast)[1]
let a2 = ObjValue(ast)[2]
let a1 = ast.val[1]
let a2 = ast.val[2]
let env = NewEnv(env)
let let_binds = ObjValue(a1)
let let_binds = a1.val
let i = 0
while i < len(let_binds)
call env.set(ObjValue(let_binds[i]), EVAL(let_binds[i+1], env))
call env.set(let_binds[i].val, EVAL(let_binds[i+1], env))
let i = i + 2
endwhile
let ast = a2
@ -141,19 +141,19 @@ function EVAL(ast, env)
let a1 = ListNth(ast, 1)
let a2 = ListNth(ast, 2)
let macro = MarkAsMacro(EVAL(a2, env))
return env.set(ObjValue(a1), macro)
return env.set(a1.val, macro)
elseif first_symbol == "macroexpand"
return MacroExpand(ListNth(ast, 1), env)
elseif first_symbol == "if"
let condvalue = EVAL(ObjValue(ast)[1], env)
let condvalue = EVAL(ast.val[1], env)
if FalseQ(condvalue) || NilQ(condvalue)
if len(ObjValue(ast)) < 4
if len(ast.val) < 4
return g:MalNil
else
let ast = ObjValue(ast)[3]
let ast = ast.val[3]
endif
else
let ast = ObjValue(ast)[2]
let ast = ast.val[2]
endif
" TCO
elseif first_symbol == "try*"
@ -165,7 +165,7 @@ function EVAL(ast, env)
throw v:exception
endif
let exc_var = ObjValue(ListNth(catch_clause, 1))
let exc_var = ListNth(catch_clause, 1).val
if v:exception == "__MalException__"
let exc_value = g:MalExceptionObj
else
@ -175,7 +175,7 @@ function EVAL(ast, env)
return EVAL(ListNth(catch_clause, 2), catch_env)
endtry
elseif first_symbol == "do"
let astlist = ObjValue(ast)
let astlist = ast.val
call EvalAst(ListNew(astlist[1:-2]), env)
let ast = astlist[-1]
" TCO
@ -194,7 +194,7 @@ function EVAL(ast, env)
if NativeFunctionQ(funcobj)
return NativeFuncInvoke(funcobj, args)
elseif FunctionQ(funcobj)
let fn = ObjValue(funcobj)
let fn = funcobj.val
let ast = fn.ast
let env = NewEnvWithBinds(fn.env, fn.params, args)
" TCO

View File

@ -12,10 +12,6 @@ function ObjType(obj)
return a:obj["type"]
endfunction
function ObjValue(obj)
return a:obj["val"]
endfunction
function ObjHasMeta(obj)
return ObjQ(a:obj) && has_key(a:obj, "meta")
endfunction
@ -91,11 +87,11 @@ function HashQ(obj)
endfunction
function FunctionQ(obj)
return ObjQ(a:obj) && ObjType(a:obj) == "function" && !ObjValue(a:obj).is_macro
return ObjQ(a:obj) && ObjType(a:obj) == "function" && !a:obj.val.is_macro
endfunction
function MacroQ(obj)
return ObjQ(a:obj) && ObjType(a:obj) == "function" && ObjValue(a:obj).is_macro
return ObjQ(a:obj) && ObjType(a:obj) == "function" && a:obj.val.is_macro
endfunction
function NativeFunctionQ(obj)
@ -158,7 +154,7 @@ function HashMakeKey(obj)
if !StringQ(a:obj) && !KeywordQ(a:obj)
throw "expected hash-map key string, got: " . ObjType(a:obj));
endif
return ObjType(a:obj) . "#" . ObjValue(a:obj)
return ObjType(a:obj) . "#" . a:obj.val
endfunction
function HashParseKey(str)
@ -186,12 +182,12 @@ function HashBuild(elements)
endfunction
function HashEqualQ(x, y)
if len(ObjValue(a:x)) != len(ObjValue(a:y))
if len(a:x.val) != len(a:y.val)
return 0
endif
for k in keys(ObjValue(a:x))
let vx = ObjValue(a:x)[k]
let vy = ObjValue(a:y)[k]
for k in keys(a:x.val)
let vx = a:x.val[k]
let vy = a:y.val[k]
if empty(vy) || !EqualQ(vx, vy)
return 0
endif
@ -200,13 +196,13 @@ function HashEqualQ(x, y)
endfunction
function SequentialEqualQ(x, y)
if len(ObjValue(a:x)) != len(ObjValue(a:y))
if len(a:x.val) != len(a:y.val)
return 0
endif
let i = 0
while i < len(ObjValue(a:x))
let ex = ObjValue(a:x)[i]
let ey = ObjValue(a:y)[i]
while i < len(a:x.val)
let ex = a:x.val[i]
let ey = a:y.val[i]
if !EqualQ(ex, ey)
return 0
endif
@ -223,31 +219,31 @@ function EqualQ(x, y)
elseif ObjType(a:x) != ObjType(a:y)
return 0
else
return ObjValue(a:x) == ObjValue(a:y)
return a:x.val == a:y.val
endif
endfunction
function EmptyQ(list)
return empty(ObjValue(a:list))
return empty(a:list.val)
endfunction
function ListCount(list)
return len(ObjValue(a:list))
return len(a:list.val)
endfunction
function ListNth(list, index)
if a:index >= len(ObjValue(a:list))
if a:index >= len(a:list.val)
throw "nth: index out of range"
endif
return ObjValue(a:list)[a:index]
return a:list.val[a:index]
endfunction
function ListFirst(list)
return get(ObjValue(a:list), 0, g:MalNil)
return get(a:list.val, 0, g:MalNil)
endfunction
function ListDrop(list, drop_elements)
return ListNew(ObjValue(a:list)[a:drop_elements :])
return ListNew(a:list.val[a:drop_elements :])
endfunction
function ListRest(list)
@ -255,18 +251,18 @@ function ListRest(list)
endfunction
function FuncInvoke(funcobj, args)
let fn = ObjValue(a:funcobj)
let fn = a:funcobj.val
let funcenv = NewEnvWithBinds(fn.env, fn.params, a:args)
return EVAL(fn.ast, funcenv)
endfunction
function NativeFuncInvoke(funcobj, argslist)
let fn = ObjValue(a:funcobj)
return fn.Func(ObjValue(a:argslist))
let fn = a:funcobj.val
return fn.Func(a:argslist.val)
endfunction
function MarkAsMacro(funcobj)
let fn = ObjValue(a:funcobj)
let fn = a:funcobj.val
let fn.is_macro = 1
return a:funcobj
endfunction