- fn*
- if available use function closures to return a new
native function that calls EVAL(a2, Env(env, a1, fargs))
+ - otherwise, store exp, params and env in a structure
- core.EXT
- create ns object to hold core namespace
- move numeric operators here
- - add compison operators
- - add list, list?, empty?, count, not
+ - add comparison operators
+ - add list, list?, empty?, count
- run make test^EXT^step4
- implement equal?/equal_Q in types.EXT and refer in core.ns
- implement not as rep("(def! not (fn* (a) (if a false true)))")
- step5_tco
- types module:
- mal function type:
- - stores: func, exp, env, params
- - func is EVAL in native mal case, otherwise reference to
- platform function
+ - stores: eval, exp, env, params
+ - eval is EVAL in native mal case (needed for map function
+ later), otherwise reference to platform function
- if metadata support, then store exp, env, params as
metadata
- printer
- cases where we directly return result of EVAL, instead set
ast and env to what would be put in the EVAL, then loop.
- do, if, "apply"
- - for "apply" case, set env to new Env based on properties
- on the function
+ - "apply"
+ - if mal function type
+ - set env to new Env based on properties on the function
+ - if native function, same as before
+ - Details:
+ - types.EXT
+ - create Mal function type to store eval, exp, env, params
+ - cp step4_if_fn_do.EXT to step5_tco.EXT
+ - wrap EVAL in infinite while loop
+ - in let*, do, and if:
+ - set ast and env and loop (no return)
+ - in fn* create Mal function type
+ - if compiled, update Makefile
+ - in apply, test if Mal function type:
+ - if so, generate new env from stored env, args and callee
+ params
+ - set ast to stored ast
+
- step6_file
- core module:
- set *ARGV*
- if files on command line, use load-file to run first argument
using rest as arguments
+ - Details:
+ - cp step5_tco.EXT to step6_file.EXT
+ - if compiled update Makefile
+ - add eval to repl_env
+ - if no (or limited closures) may have to add an "eval"
+ case to EVAL and use function which gets root of
+ environment to env.EXT (see rust).
+ - add empty *ARGV* list to repl_env
+ - in core.ns:
+ - wrap printer.read-str as read-string
+ - implement slurp
+ - implement load-file using rep
+ - test:
+ (load-file "../tests/inc.mal")
+ (inc3 10)
+ - implement command line execution
+ - test:
+ ./step6_file ../tests/incA.mal
+ =>9
+ - implement comments in reader.EXT (ignore in tokenize)
- step7_quote
- add is_pair and quasiquote functions
- reader module:
- add reader macros to read_form for quote, unquote,
splice-unquote and quasiquote
+ - Details:
+ - cp step6_file.EXT to step6_quote.EXT
+ - if compiled update Makefile
+ - implement reader macros (', `, ~, ~@) in reader
+ - retest make test^go^step1
+ - add is_pair and quasiquote
+ - add quote and quasiquote cases to EVAL
+ - implement cons and concat in core.EXT
+ - retest test^go^step7
- step8_macros
- types
- EVAL:
- add 'defmacro!' and 'macroexpand'
- set ismacro property on function
+ - Details:
+ - cp step7_quote.EXT to step8_macros.EXT
+ - if compiled update Makefile
+ - add isMacro property to Mal Function type
+ - may need to go back and adjust step5-7
+ - implement is_macro_call and macroexpand
+ - call macroexpand on ast before apply in EVAL
+ - add defmacro! and macroexpand to EVAL switch
+ - make test^go^step8 should pass some basic macros
+ - add nth, first, and rest to core.ns
+ - make test^go^step8 should now pass
-- step9_interop
- - convert returned data to mal data
- - recursive, similar to pr_str
-
-- stepA_more
+- step9_try
- core module:
- throw function
- apply, map functions: should not directly call EVAL, which
otherwise extracts full value
- set and print *host-language*
- define cond and or macros using REP/RE
+ - Details:
+ - cp step8_macros.EXT to stepA_try.EXT
+ - if compiled update Makefile
+ - core.ns implement nil?, true?, false?, symbol?, sequential?,
+ vector, vector?
+ - add mal error type which wraps normal mal type
+ - in core.ns add throw which wraps type in mal error type
+ and throws/raises/sets exception
+ - add try*/catch* support to EVAL
+ - if mal error type, bind to catch* bind symbol
+ - otherwise, bind string of error to catch* bind symbol
+ - implement apply, map in core.ns
+ - make test^go^stepA
+ - implement readline.EXT
+ - provide option (e.g. commented out) to link with GNU
+ readline (GPL) or libedit (BSD)
+ - add hash-map functions: hash-map, map?, assoc, dissoc, get,
+ contains?, keys, vals
+ - add metadata support to List, Vector, HashMap, and Functions
+ - add reader macro
+ - may need to box HashMap and native functions
+ - add atom type, reader macro and functions: with_meta, meta
+ - get `make test^go^stepA` to fully pass
+ - get `./stepA_try ../mal/step1_read_print` to pass
+ - continue for each mal step until ../mal/stepA_try
+ - Now self-hosting!
+
- Extra defintions needed for self-hosting
- core module:
- vector, vector?
-- Other misc:
- - conj function
-
- atoms
- reader module:
- @a reader macro -> (deref a)
- clone/copy of collections
- core module:
- add with-meta, meta functions
+
+- Other misc:
+ - conj function
+
+- stepA_mal
+ - convert returned data to mal data
+ - recursive, similar to pr_str
+ - Details:
+