mirror of
https://github.com/kanaka/mal.git
synced 2024-10-04 01:17:33 +03:00
nim: mark several variables as immutable
Also apply 2dedaa3919
to step0
This commit is contained in:
parent
7909c8c01e
commit
642bb4c454
@ -11,7 +11,7 @@ proc initEnv*(outer: Env = nil, binds, exprs: MalType = nilObj): Env =
|
||||
else:
|
||||
result.data[e.str] = exprs.list[i]
|
||||
|
||||
proc set*(e: var Env, key: string, value: MalType): MalType {.discardable.} =
|
||||
proc set*(e: Env, key: string, value: MalType): MalType {.discardable.} =
|
||||
e.data[key] = value
|
||||
value
|
||||
|
||||
|
@ -7,5 +7,7 @@ proc eval(ast: string): string = ast
|
||||
proc print(exp: string): string = exp
|
||||
|
||||
while true:
|
||||
try:
|
||||
let line = readLineFromStdin("user> ")
|
||||
echo line.read.eval.print
|
||||
except IOError: quit()
|
||||
|
@ -2,7 +2,7 @@ import rdstdin, tables, sequtils, types, reader, printer, env
|
||||
|
||||
proc read(str: string): MalType = str.read_str
|
||||
|
||||
proc eval(ast: MalType, env: var Env): MalType =
|
||||
proc eval(ast: MalType, env: Env): MalType =
|
||||
|
||||
let dbgeval = env.get("DEBUG-EVAL")
|
||||
if not (dbgeval.isNil or dbgeval.kind in {Nil, False}):
|
||||
@ -30,7 +30,7 @@ proc eval(ast: MalType, env: var Env): MalType =
|
||||
of "def!":
|
||||
result = env.set(a1.str, a2.eval(env))
|
||||
of "let*":
|
||||
var let_env = initEnv(env)
|
||||
let let_env = initEnv(env)
|
||||
case a1.kind
|
||||
of List, Vector:
|
||||
for i in countup(0, a1.list.high, 2):
|
||||
@ -48,7 +48,7 @@ proc print(exp: MalType): string = exp.pr_str
|
||||
template wrapNumberFun(op): untyped =
|
||||
fun proc(xs: varargs[MalType]): MalType = number op(xs[0].number, xs[1].number)
|
||||
|
||||
var repl_env = initEnv()
|
||||
let repl_env = initEnv()
|
||||
|
||||
repl_env.set("+", wrapNumberFun(`+`))
|
||||
repl_env.set("-", wrapNumberFun(`-`))
|
||||
|
@ -2,7 +2,7 @@ import rdstdin, tables, sequtils, types, reader, printer, env, core
|
||||
|
||||
proc read(str: string): MalType = str.read_str
|
||||
|
||||
proc eval(ast: MalType, env: var Env): MalType =
|
||||
proc eval(ast: MalType, env: Env): MalType =
|
||||
|
||||
let dbgeval = env.get("DEBUG-EVAL")
|
||||
if not (dbgeval.isNil or dbgeval.kind in {Nil, False}):
|
||||
@ -35,7 +35,7 @@ proc eval(ast: MalType, env: var Env): MalType =
|
||||
let
|
||||
a1 = ast.list[1]
|
||||
a2 = ast.list[2]
|
||||
var let_env = initEnv(env)
|
||||
let let_env = initEnv(env)
|
||||
case a1.kind
|
||||
of List, Vector:
|
||||
for i in countup(0, a1.list.high, 2):
|
||||
@ -62,10 +62,8 @@ proc eval(ast: MalType, env: var Env): MalType =
|
||||
let
|
||||
a1 = ast.list[1]
|
||||
a2 = ast.list[2]
|
||||
var env2 = env
|
||||
return fun(proc(a: varargs[MalType]): MalType =
|
||||
var newEnv = initEnv(env2, a1, list(a))
|
||||
a2.eval(newEnv))
|
||||
a2.eval(initEnv(env, a1, list(a))))
|
||||
|
||||
let el = ast.list.mapIt(it.eval(env))
|
||||
result = el[0].fun(el[1 .. ^1])
|
||||
@ -75,7 +73,7 @@ proc eval(ast: MalType, env: var Env): MalType =
|
||||
|
||||
proc print(exp: MalType): string = exp.pr_str
|
||||
|
||||
var repl_env = initEnv()
|
||||
let repl_env = initEnv()
|
||||
|
||||
for k, v in ns.items:
|
||||
repl_env.set(k, v)
|
||||
|
@ -44,7 +44,7 @@ proc eval(ast: MalType, env: Env): MalType =
|
||||
let
|
||||
a1 = ast.list[1]
|
||||
a2 = ast.list[2]
|
||||
var let_env = initEnv(env)
|
||||
let let_env = initEnv(env)
|
||||
case a1.kind
|
||||
of List, Vector:
|
||||
for i in countup(0, a1.list.high, 2):
|
||||
@ -80,10 +80,8 @@ proc eval(ast: MalType, env: Env): MalType =
|
||||
let
|
||||
a1 = ast.list[1]
|
||||
a2 = ast.list[2]
|
||||
var env2 = env
|
||||
let fn = proc(a: varargs[MalType]): MalType =
|
||||
var newEnv = initEnv(env2, a1, list(a))
|
||||
a2.eval(newEnv)
|
||||
a2.eval(initEnv(env, a1, list(a)))
|
||||
return malfun(fn, a2, a1, env)
|
||||
|
||||
let f = eval(a0, env)
|
||||
@ -97,7 +95,7 @@ proc eval(ast: MalType, env: Env): MalType =
|
||||
|
||||
proc print(exp: MalType): string = exp.pr_str
|
||||
|
||||
var repl_env = initEnv()
|
||||
let repl_env = initEnv()
|
||||
|
||||
for k, v in ns.items:
|
||||
repl_env.set(k, v)
|
||||
|
@ -44,7 +44,7 @@ proc eval(ast: MalType, env: Env): MalType =
|
||||
let
|
||||
a1 = ast.list[1]
|
||||
a2 = ast.list[2]
|
||||
var let_env = initEnv(env)
|
||||
let let_env = initEnv(env)
|
||||
case a1.kind
|
||||
of List, Vector:
|
||||
for i in countup(0, a1.list.high, 2):
|
||||
@ -80,10 +80,8 @@ proc eval(ast: MalType, env: Env): MalType =
|
||||
let
|
||||
a1 = ast.list[1]
|
||||
a2 = ast.list[2]
|
||||
var env2 = env
|
||||
let fn = proc(a: varargs[MalType]): MalType =
|
||||
var newEnv = initEnv(env2, a1, list(a))
|
||||
a2.eval(newEnv)
|
||||
a2.eval(initEnv(env, a1, list(a)))
|
||||
return malfun(fn, a2, a1, env)
|
||||
|
||||
let f = eval(a0, env)
|
||||
@ -97,12 +95,12 @@ proc eval(ast: MalType, env: Env): MalType =
|
||||
|
||||
proc print(exp: MalType): string = exp.pr_str
|
||||
|
||||
var repl_env = initEnv()
|
||||
let repl_env = initEnv()
|
||||
|
||||
for k, v in ns.items:
|
||||
repl_env.set(k, v)
|
||||
repl_env.set("eval", fun(proc(xs: varargs[MalType]): MalType = eval(xs[0], repl_env)))
|
||||
var ps = commandLineParams()
|
||||
let ps = commandLineParams()
|
||||
repl_env.set("*ARGV*", list((if paramCount() > 1: ps[1..ps.high] else: @[]).map(str)))
|
||||
|
||||
|
||||
|
@ -7,7 +7,7 @@ proc quasiquote(ast: MalType): MalType
|
||||
proc quasiquote_loop(xs: seq[MalType]): MalType =
|
||||
result = list()
|
||||
for i in countdown(xs.high, 0):
|
||||
var elt = xs[i]
|
||||
let elt = xs[i]
|
||||
if elt.kind == List and 0 < elt.list.len and elt.list[0] == symbol "splice-unquote":
|
||||
result = list(symbol "concat", elt.list[1], result)
|
||||
else:
|
||||
@ -72,7 +72,7 @@ proc eval(ast: MalType, env: Env): MalType =
|
||||
let
|
||||
a1 = ast.list[1]
|
||||
a2 = ast.list[2]
|
||||
var let_env = initEnv(env)
|
||||
let let_env = initEnv(env)
|
||||
case a1.kind
|
||||
of List, Vector:
|
||||
for i in countup(0, a1.list.high, 2):
|
||||
@ -115,10 +115,8 @@ proc eval(ast: MalType, env: Env): MalType =
|
||||
let
|
||||
a1 = ast.list[1]
|
||||
a2 = ast.list[2]
|
||||
var env2 = env
|
||||
let fn = proc(a: varargs[MalType]): MalType =
|
||||
var newEnv = initEnv(env2, a1, list(a))
|
||||
a2.eval(newEnv)
|
||||
a2.eval(initEnv(env, a1, list(a)))
|
||||
return malfun(fn, a2, a1, env)
|
||||
|
||||
let f = eval(a0, env)
|
||||
@ -132,12 +130,12 @@ proc eval(ast: MalType, env: Env): MalType =
|
||||
|
||||
proc print(exp: MalType): string = exp.pr_str
|
||||
|
||||
var repl_env = initEnv()
|
||||
let repl_env = initEnv()
|
||||
|
||||
for k, v in ns.items:
|
||||
repl_env.set(k, v)
|
||||
repl_env.set("eval", fun(proc(xs: varargs[MalType]): MalType = eval(xs[0], repl_env)))
|
||||
var ps = commandLineParams()
|
||||
let ps = commandLineParams()
|
||||
repl_env.set("*ARGV*", list((if paramCount() > 1: ps[1..ps.high] else: @[]).map(str)))
|
||||
|
||||
|
||||
|
@ -7,7 +7,7 @@ proc quasiquote(ast: MalType): MalType
|
||||
proc quasiquote_loop(xs: seq[MalType]): MalType =
|
||||
result = list()
|
||||
for i in countdown(xs.high, 0):
|
||||
var elt = xs[i]
|
||||
let elt = xs[i]
|
||||
if elt.kind == List and 0 < elt.list.len and elt.list[0] == symbol "splice-unquote":
|
||||
result = list(symbol "concat", elt.list[1], result)
|
||||
else:
|
||||
@ -72,7 +72,7 @@ proc eval(ast: MalType, env: Env): MalType =
|
||||
let
|
||||
a1 = ast.list[1]
|
||||
a2 = ast.list[2]
|
||||
var let_env = initEnv(env)
|
||||
let let_env = initEnv(env)
|
||||
case a1.kind
|
||||
of List, Vector:
|
||||
for i in countup(0, a1.list.high, 2):
|
||||
@ -90,9 +90,9 @@ proc eval(ast: MalType, env: Env): MalType =
|
||||
continue # TCO
|
||||
|
||||
of "defmacro!":
|
||||
var fun = ast.list[2].eval(env)
|
||||
fun = malfun(fun.malfun.fn, fun.malfun.ast, fun.malfun.params, fun.malfun.env, true)
|
||||
return env.set(ast.list[1].str, fun)
|
||||
let fun = ast.list[2].eval(env)
|
||||
let mac = malfun(fun.malfun.fn, fun.malfun.ast, fun.malfun.params, fun.malfun.env, true)
|
||||
return env.set(ast.list[1].str, mac)
|
||||
|
||||
of "do":
|
||||
let last = ast.list.high
|
||||
@ -120,10 +120,8 @@ proc eval(ast: MalType, env: Env): MalType =
|
||||
let
|
||||
a1 = ast.list[1]
|
||||
a2 = ast.list[2]
|
||||
var env2 = env
|
||||
let fn = proc(a: varargs[MalType]): MalType =
|
||||
var newEnv = initEnv(env2, a1, list(a))
|
||||
a2.eval(newEnv)
|
||||
a2.eval(initEnv(env, a1, list(a)))
|
||||
return malfun(fn, a2, a1, env)
|
||||
|
||||
let f = eval(a0, env)
|
||||
@ -140,12 +138,12 @@ proc eval(ast: MalType, env: Env): MalType =
|
||||
|
||||
proc print(exp: MalType): string = exp.pr_str
|
||||
|
||||
var repl_env = initEnv()
|
||||
let repl_env = initEnv()
|
||||
|
||||
for k, v in ns.items:
|
||||
repl_env.set(k, v)
|
||||
repl_env.set("eval", fun(proc(xs: varargs[MalType]): MalType = eval(xs[0], repl_env)))
|
||||
var ps = commandLineParams()
|
||||
let ps = commandLineParams()
|
||||
repl_env.set("*ARGV*", list((if paramCount() > 1: ps[1..ps.high] else: @[]).map(str)))
|
||||
|
||||
|
||||
|
@ -7,7 +7,7 @@ proc quasiquote(ast: MalType): MalType
|
||||
proc quasiquote_loop(xs: seq[MalType]): MalType =
|
||||
result = list()
|
||||
for i in countdown(xs.high, 0):
|
||||
var elt = xs[i]
|
||||
let elt = xs[i]
|
||||
if elt.kind == List and 0 < elt.list.len and elt.list[0] == symbol "splice-unquote":
|
||||
result = list(symbol "concat", elt.list[1], result)
|
||||
else:
|
||||
@ -73,7 +73,7 @@ proc eval(ast: MalType, env: Env): MalType =
|
||||
let
|
||||
a1 = ast.list[1]
|
||||
a2 = ast.list[2]
|
||||
var let_env = initEnv(env)
|
||||
let let_env = initEnv(env)
|
||||
case a1.kind
|
||||
of List, Vector:
|
||||
for i in countup(0, a1.list.high, 2):
|
||||
@ -91,9 +91,9 @@ proc eval(ast: MalType, env: Env): MalType =
|
||||
continue # TCO
|
||||
|
||||
of "defmacro!":
|
||||
var fun = ast.list[2].eval(env)
|
||||
fun = malfun(fun.malfun.fn, fun.malfun.ast, fun.malfun.params, fun.malfun.env, true)
|
||||
return env.set(ast.list[1].str, fun)
|
||||
let fun = ast.list[2].eval(env)
|
||||
let mac = malfun(fun.malfun.fn, fun.malfun.ast, fun.malfun.params, fun.malfun.env, true)
|
||||
return env.set(ast.list[1].str, mac)
|
||||
|
||||
of "try*":
|
||||
let a1 = ast.list[1]
|
||||
@ -140,10 +140,8 @@ proc eval(ast: MalType, env: Env): MalType =
|
||||
let
|
||||
a1 = ast.list[1]
|
||||
a2 = ast.list[2]
|
||||
var env2 = env
|
||||
let fn = proc(a: varargs[MalType]): MalType =
|
||||
var newEnv = initEnv(env2, a1, list(a))
|
||||
a2.eval(newEnv)
|
||||
a2.eval(initEnv(env, a1, list(a)))
|
||||
return malfun(fn, a2, a1, env)
|
||||
|
||||
let f = eval(a0, env)
|
||||
@ -160,12 +158,12 @@ proc eval(ast: MalType, env: Env): MalType =
|
||||
|
||||
proc print(exp: MalType): string = exp.pr_str
|
||||
|
||||
var repl_env = initEnv()
|
||||
let repl_env = initEnv()
|
||||
|
||||
for k, v in ns.items:
|
||||
repl_env.set(k, v)
|
||||
repl_env.set("eval", fun(proc(xs: varargs[MalType]): MalType = eval(xs[0], repl_env)))
|
||||
var ps = commandLineParams()
|
||||
let ps = commandLineParams()
|
||||
repl_env.set("*ARGV*", list((if paramCount() > 1: ps[1..ps.high] else: @[]).map(str)))
|
||||
|
||||
|
||||
|
@ -7,7 +7,7 @@ proc quasiquote(ast: MalType): MalType
|
||||
proc quasiquote_loop(xs: seq[MalType]): MalType =
|
||||
result = list()
|
||||
for i in countdown(xs.high, 0):
|
||||
var elt = xs[i]
|
||||
let elt = xs[i]
|
||||
if elt.kind == List and 0 < elt.list.len and elt.list[0] == symbol "splice-unquote":
|
||||
result = list(symbol "concat", elt.list[1], result)
|
||||
else:
|
||||
@ -73,7 +73,7 @@ proc eval(ast: MalType, env: Env): MalType =
|
||||
let
|
||||
a1 = ast.list[1]
|
||||
a2 = ast.list[2]
|
||||
var let_env = initEnv(env)
|
||||
let let_env = initEnv(env)
|
||||
case a1.kind
|
||||
of List, Vector:
|
||||
for i in countup(0, a1.list.high, 2):
|
||||
@ -91,9 +91,9 @@ proc eval(ast: MalType, env: Env): MalType =
|
||||
continue # TCO
|
||||
|
||||
of "defmacro!":
|
||||
var fun = ast.list[2].eval(env)
|
||||
fun = malfun(fun.malfun.fn, fun.malfun.ast, fun.malfun.params, fun.malfun.env, true)
|
||||
return env.set(ast.list[1].str, fun)
|
||||
let fun = ast.list[2].eval(env)
|
||||
let mac = malfun(fun.malfun.fn, fun.malfun.ast, fun.malfun.params, fun.malfun.env, true)
|
||||
return env.set(ast.list[1].str, mac)
|
||||
|
||||
of "try*":
|
||||
let a1 = ast.list[1]
|
||||
@ -140,10 +140,8 @@ proc eval(ast: MalType, env: Env): MalType =
|
||||
let
|
||||
a1 = ast.list[1]
|
||||
a2 = ast.list[2]
|
||||
var env2 = env
|
||||
let fn = proc(a: varargs[MalType]): MalType =
|
||||
var newEnv = initEnv(env2, a1, list(a))
|
||||
a2.eval(newEnv)
|
||||
a2.eval(initEnv(env, a1, list(a)))
|
||||
return malfun(fn, a2, a1, env)
|
||||
|
||||
let f = eval(a0, env)
|
||||
@ -160,12 +158,12 @@ proc eval(ast: MalType, env: Env): MalType =
|
||||
|
||||
proc print(exp: MalType): string = exp.pr_str
|
||||
|
||||
var repl_env = initEnv()
|
||||
let repl_env = initEnv()
|
||||
|
||||
for k, v in ns.items:
|
||||
repl_env.set(k, v)
|
||||
repl_env.set("eval", fun(proc(xs: varargs[MalType]): MalType = eval(xs[0], repl_env)))
|
||||
var ps = commandLineParams()
|
||||
let ps = commandLineParams()
|
||||
repl_env.set("*ARGV*", list((if paramCount() > 1: ps[1..ps.high] else: @[]).map(str)))
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user