1 REM Step 4 of mal in BBC BASIC
11 repl_env
% = FNalloc_environment(FNnil
)
12 PROCcore_ns
: REM This sets the data pointer
16 PROCenv_set(repl_env
%, FNalloc_symbol(sym
$), FNalloc_corefn(i
%))
20 val$
= FNrep("(def! not (fn* (a) (if a false true)))")
24 REM Catch all errors apart from "Escape".
25 ON ERROR LOCAL
IF ERR
= 17 ON ERROR OFF
: ERROR ERR
, REPORT$
ELSE PRINT REPORT$
36 =FNread_str(FNalloc_string(a
$))
38 DEF
FNEVAL(ast
%, env
%)
41 =FNgc_exit(FNEVAL_(ast
%, env
%))
43 DEF
FNEVAL_(ast
%, env
%)
45 IF NOT FNis_list(ast
%) THEN =FNeval_ast(ast
%, env
%)
46 IF FNis_empty(ast
%) THEN =ast
%
48 IF FNis_symbol(car
%) THEN
49 CASE FNunbox_symbol(car
%) OF
53 val
% = FNEVAL(FNnth(ast
%, 2), env
%)
54 PROCenv_set(env
%, FNnth(ast
%, 1), val
%)
58 env
% = FNalloc_environment(env
%)
59 bindings
% = FNnth(ast
%, 1)
60 WHILE NOT FNis_empty(bindings
%)
61 PROCenv_set(env
%, FNfirst(bindings
%), FNEVAL(FNnth(bindings
%, 1), env
%))
62 bindings
% = FNrest(FNrest(bindings
%))
64 =FNEVAL(FNnth(ast
%, 2), env
%)
67 ast
% = FNeval_ast(FNrest(ast
%), env
%)
71 UNTIL FNis_empty(ast
%)
74 IF FNis_truish(FNEVAL(FNnth(ast
%, 1), env
%)) THEN
75 =FNEVAL(FNnth(ast
%, 2), env
%)
77 IF FNcount(ast
%) = 3 THEN =FNnil
78 =FNEVAL(FNnth(ast
%, 3), env
%)
80 =FNalloc_fn(FNnth(ast
%, 2), FNnth(ast
%, 1), env
%)
83 ast
% = FNeval_ast(ast
%, env
%)
86 env
% = FNnew_env(FNfn_env(car
%), FNfn_params(car
%), FNrest(ast
%))
87 =FNEVAL(FNfn_ast(car
%), env
%)
89 IF FNis_corefn(car
%) THEN
90 =FNcore_call(FNunbox_corefn(car
%), FNrest(ast
%))
92 ERROR &40E80918
, "Not a function"
95 =FNunbox_string(FNpr_str(a
%, TRUE))
98 =FNPRINT(FNEVAL(FNREAD(a
$), repl_env
%))
100 DEF
FNeval_ast(ast
%, env
%)
101 LOCAL val
%, car
%, cdr
%, map
%, keys
%, key$
102 IF FNis_symbol(ast
%) THEN =FNenv_get(env
%, ast
%)
103 IF FNis_seq(ast
%) THEN
104 IF FNis_empty(ast
%) THEN =ast
%
105 car
% = FNEVAL(FNfirst(ast
%), env
%)
106 cdr
% = FNeval_ast(FNrest(ast
%), env
%)
107 IF FNis_vector(ast
%) THEN =FNalloc_vector_pair(car
%, cdr
%)
108 =FNalloc_pair(car
%, cdr
%)
110 IF FNis_hashmap(ast
%) THEN
111 map
% = FNempty_hashmap
112 keys
% = FNhashmap_keys(ast
%)
113 WHILE NOT FNis_empty(keys
%)
114 key$
= FNunbox_string(FNfirst(keys
%))
115 map
% = FNhashmap_set(map
%, key
$, FNEVAL(FNhashmap_get(ast
%, key
$), env
%))
116 keys
% = FNrest(keys
%)
123 REM indent-tabs-mode: nil