mirror of
https://github.com/kanaka/mal.git
synced 2024-09-11 13:55:55 +03:00
Move test of eval builtin to step6. Fix nim implementation.
The test makes more sense in step6. Thanks to kanaka for the read-string suggestion. Introduction of tail call optimization in step5 was making let* affect the parent environment. This was partially fixed in later steps. Introduction of macros in step8 was breaking the evaluation of an empty list. This was fixed by step 9 but never backported.
This commit is contained in:
parent
d12bf4787c
commit
fc7f8a4b00
@ -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
|
||||
|
||||
proc eval_ast(ast: MalType, env: var Env): MalType =
|
||||
case ast.kind
|
||||
@ -19,8 +19,9 @@ proc eval_ast(ast: MalType, env: var Env): MalType =
|
||||
else:
|
||||
result = ast
|
||||
|
||||
proc eval(ast: MalType, env: var Env): MalType =
|
||||
proc eval(ast: MalType, env: Env): MalType =
|
||||
var ast = ast
|
||||
var env = env
|
||||
|
||||
template defaultApply =
|
||||
let el = ast.eval_ast(env)
|
||||
@ -50,7 +51,7 @@ proc eval(ast: MalType, env: var Env): MalType =
|
||||
let
|
||||
a1 = ast.list[1]
|
||||
a2 = ast.list[2]
|
||||
var let_env = env
|
||||
var let_env = initEnv(env)
|
||||
case a1.kind
|
||||
of List, Vector:
|
||||
for i in countup(0, a1.list.high, 2):
|
||||
|
@ -2,7 +2,7 @@ import rdstdin, tables, sequtils, os, 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
|
||||
|
||||
proc eval_ast(ast: MalType, env: var Env): MalType =
|
||||
case ast.kind
|
||||
@ -19,8 +19,9 @@ proc eval_ast(ast: MalType, env: var Env): MalType =
|
||||
else:
|
||||
result = ast
|
||||
|
||||
proc eval(ast: MalType, env: var Env): MalType =
|
||||
proc eval(ast: MalType, env: Env): MalType =
|
||||
var ast = ast
|
||||
var env = env
|
||||
|
||||
template defaultApply =
|
||||
let el = ast.eval_ast(env)
|
||||
@ -50,7 +51,7 @@ proc eval(ast: MalType, env: var Env): MalType =
|
||||
let
|
||||
a1 = ast.list[1]
|
||||
a2 = ast.list[2]
|
||||
var let_env = env
|
||||
var let_env = initEnv(env)
|
||||
case a1.kind
|
||||
of List, Vector:
|
||||
for i in countup(0, a1.list.high, 2):
|
||||
|
@ -16,7 +16,7 @@ proc quasiquote(ast: MalType): MalType =
|
||||
else:
|
||||
return list(symbol "cons", quasiquote(ast.list[0]), quasiquote(list(ast.list[1 .. ^1])))
|
||||
|
||||
proc eval(ast: MalType, env: var Env): MalType
|
||||
proc eval(ast: MalType, env: Env): MalType
|
||||
|
||||
proc eval_ast(ast: MalType, env: var Env): MalType =
|
||||
case ast.kind
|
||||
@ -33,8 +33,9 @@ proc eval_ast(ast: MalType, env: var Env): MalType =
|
||||
else:
|
||||
result = ast
|
||||
|
||||
proc eval(ast: MalType, env: var Env): MalType =
|
||||
proc eval(ast: MalType, env: Env): MalType =
|
||||
var ast = ast
|
||||
var env = env
|
||||
|
||||
template defaultApply =
|
||||
let el = ast.eval_ast(env)
|
||||
@ -64,7 +65,7 @@ proc eval(ast: MalType, env: var Env): MalType =
|
||||
let
|
||||
a1 = ast.list[1]
|
||||
a2 = ast.list[2]
|
||||
var let_env = env
|
||||
var let_env = initEnv(env)
|
||||
case a1.kind
|
||||
of List, Vector:
|
||||
for i in countup(0, a1.list.high, 2):
|
||||
|
@ -17,7 +17,7 @@ proc quasiquote(ast: MalType): MalType =
|
||||
return list(symbol "cons", quasiquote(ast.list[0]), quasiquote(list(ast.list[1 .. ^1])))
|
||||
|
||||
proc is_macro_call(ast: MalType, env: Env): bool =
|
||||
ast.kind == List and ast.list[0].kind == Symbol and
|
||||
ast.kind == List and ast.list.len > 0 and ast.list[0].kind == Symbol and
|
||||
env.find(ast.list[0].str) != nil and env.get(ast.list[0].str).fun_is_macro
|
||||
|
||||
proc macroexpand(ast: MalType, env: Env): MalType =
|
||||
@ -78,7 +78,7 @@ proc eval(ast: MalType, env: Env): MalType =
|
||||
let
|
||||
a1 = ast.list[1]
|
||||
a2 = ast.list[2]
|
||||
var let_env = env
|
||||
var let_env = initEnv(env)
|
||||
case a1.kind
|
||||
of List, Vector:
|
||||
for i in countup(0, a1.list.high, 2):
|
||||
|
@ -79,7 +79,7 @@ proc eval(ast: MalType, env: Env): MalType =
|
||||
let
|
||||
a1 = ast.list[1]
|
||||
a2 = ast.list[2]
|
||||
var let_env = env
|
||||
var let_env = initEnv(env)
|
||||
case a1.kind
|
||||
of List, Vector:
|
||||
for i in countup(0, a1.list.high, 2):
|
||||
|
@ -79,7 +79,7 @@ proc eval(ast: MalType, env: Env): MalType =
|
||||
let
|
||||
a1 = ast.list[1]
|
||||
a2 = ast.list[2]
|
||||
var let_env = env
|
||||
var let_env = initEnv(env)
|
||||
case a1.kind
|
||||
of List, Vector:
|
||||
for i in countup(0, a1.list.high, 2):
|
||||
|
@ -125,3 +125,8 @@ mymap
|
||||
(g 3)
|
||||
;=>81
|
||||
|
||||
;; Checking that eval does not use local environments.
|
||||
(def! a 1)
|
||||
;=>1
|
||||
(let* (a 2) (eval (read-string "a")))
|
||||
;=>1
|
||||
|
@ -181,9 +181,3 @@ b
|
||||
;;; TODO: fix this
|
||||
;;;;=>[1 1 "b" "d" 3]
|
||||
|
||||
;; Checking that eval does not use local environments.
|
||||
;; Test step6, but requires a quote.
|
||||
(def! a 1)
|
||||
;=>1
|
||||
(let* (a 2) (eval 'a))
|
||||
;=>1
|
||||
|
Loading…
Reference in New Issue
Block a user