Macros actually working
This commit is contained in:
@@ -1,3 +1,139 @@
|
||||
* Issues
|
||||
** DONE #001
|
||||
CLOSED: [2018-10-26 Fr 22:36]
|
||||
|
||||
#+begin_src lisp
|
||||
(define seq (list 1 2 3))
|
||||
(when 1 (printf seq))
|
||||
#+end_src
|
||||
|
||||
The problem is, that =when= calls =apply= and the params of =apply= are named =fun= and =seq=. So
|
||||
when we refer to seq in =printf= then we are refering to the =apply='s argument names. Maybe a good
|
||||
solution to that is, that a child environment can never look up something in a parent macro
|
||||
environment, but will always pass through
|
||||
|
||||
| stack depth | is macro environment | defined symbols | scope |
|
||||
|-------------+----------------------+--------------------------+---------------------|
|
||||
| 0 | no | seq nil printf apply etc | |
|
||||
| 1 | yes | test body | (when 1 printf seq) |
|
||||
| 2 | yes | fun seq | (apply prog body) |
|
||||
| 3 | no | | (printf seq) |
|
||||
|
||||
** DONE #002
|
||||
CLOSED: [2018-10-27 Sa 13:50]
|
||||
#+begin_src lisp
|
||||
(define l (list 1 2 3))
|
||||
(extend l 4)
|
||||
|
||||
;; === Environment ===
|
||||
;; current: in (apply)
|
||||
;; fun -> prog
|
||||
;; seq -> body
|
||||
;; parent (hidden): in (when)
|
||||
;; test -> (pair? seq)
|
||||
;; body -> ((define e (end seq)) (mutate e (pair (first e) elem)))
|
||||
;; parent: in (extend)
|
||||
;; seq -> (1.000000 2.000000 3.000000)
|
||||
;; elem -> 4.000000
|
||||
;; parent: (top level)
|
||||
;; nil -> nil
|
||||
;; defun -> [macro]
|
||||
;; defmacro -> [macro]
|
||||
;; pe -> [macro]
|
||||
;; nil? -> [lambda]
|
||||
;; number? -> [lambda]
|
||||
;; symbol? -> [lambda]
|
||||
;; keyword? -> [lambda]
|
||||
;; pair? -> [lambda]
|
||||
;; string? -> [lambda]
|
||||
;; dynamic-function? -> [lambda]
|
||||
;; dynamic-macro? -> [lambda]
|
||||
;; built-in-function? -> [lambda]
|
||||
;; apply -> [macro]
|
||||
;; when -> [macro]
|
||||
;; unless -> [macro]
|
||||
;; end -> [lambda]
|
||||
;; last -> [lambda]
|
||||
;; extend -> [lambda]
|
||||
;; append -> [lambda]
|
||||
;; n-times -> [macro]
|
||||
;; range -> [lambda]
|
||||
;; map -> [lambda]
|
||||
;; reduce -> [lambda]
|
||||
;; reduce-binary -> [lambda]
|
||||
;; filter -> [lambda]
|
||||
;; printf-quoted -> [macro]
|
||||
;; printf -> [lambda]
|
||||
;; l -> (1.000000 2.000000 3.000000)
|
||||
|
||||
;; M (apply fun -> prog seq -> body)
|
||||
;; M (when test -> (pair? seq) body -> ((define e (end seq)) (mutate e (pair (first e) elem))))
|
||||
;; (extend seq -> (1.000000 2.000000 3.000000) elem -> 4.000000)
|
||||
#+end_src
|
||||
|
||||
The problem is that a funciton g called by a function f has access to the environment of f. This is
|
||||
a real problem.
|
||||
|
||||
#+begin_src lisp
|
||||
(defun f () 1)
|
||||
(defun g () (f))
|
||||
(defun h (f) (g))
|
||||
(h 4)
|
||||
#+end_src
|
||||
|
||||
What *should* happen:
|
||||
- (h 1) calls (g)
|
||||
- (g) calls (f)
|
||||
- (f) retunrs 1
|
||||
|
||||
What *actually* happens:
|
||||
- (h 1) calls (g)
|
||||
- (g) tries to call (f) but f is not a funciton but =4=
|
||||
|
||||
** DONE #003
|
||||
CLOSED: [2018-10-27 Sa 15:22]
|
||||
#+begin_src lisp
|
||||
(defmacro n-times (times action)
|
||||
(unless (<= (eval times) 0)
|
||||
(breakpoint)
|
||||
(eval action)
|
||||
(macro-define args (pair (pair - (pair (eval times) (pair 1 nil))) (pair action nil)))
|
||||
;; [o|o] --------------------------> [o|o] -> nil
|
||||
;; | |
|
||||
;; V V
|
||||
;; [o|o] -> [o|o] -> [o|o]-> nil action
|
||||
;; | | |
|
||||
;; V V V
|
||||
;; - times 1
|
||||
(eval (pair n-times args))))
|
||||
#+end_src
|
||||
|
||||
- *let* should never have access to parenting macro because =(while 2 test) -> 2.00000=
|
||||
- Should it have access to the grandad macro?
|
||||
- no, =(when 2 (when 3 test)) -> 2=
|
||||
|
||||
- in the example, =n-times= is a macro, that calls =unless=, that itself is a macro that calls the
|
||||
content of =n-times= in a let. So of course the contents of =n-times= wont have acess to the
|
||||
parameters to =n-times=, which is bad.
|
||||
|
||||
So right now the only way I see to fix this is to make maco environments accessable again, but pay
|
||||
attention on how to name macro parameters, to avoid collision, maybe a naming convention would help,
|
||||
maybe prefix with =@=
|
||||
*** Solutions:
|
||||
|
||||
First instinct to prevent that, is that if a parent environment is a function then just pass it and
|
||||
go for their parent etc. Then we need =let= of a way to create environments that are neither macro-
|
||||
nor funciton environmetns. They will be still different though.
|
||||
|
||||
*** Defining
|
||||
In a macro environment define will still behave differently than in a function environment. If you
|
||||
use =define= in a macro environment, it will actually be defined in the closest non-macro
|
||||
environment. If you actually want to define something in a macro environment, then use
|
||||
=macro-define=. However =define= will do the same if you are in a function or let environment.
|
||||
|
||||
*** Looking up
|
||||
If the symbol is found on the active environment then use it. If not: Go up the environments untily
|
||||
ou find a let-environment and recurse on that.
|
||||
* Arguments
|
||||
|
||||
In Emacs lisp, keyword arguments must be passed in the same order as they were
|
||||
@@ -191,13 +327,23 @@ set to see if we are in an errornious state.
|
||||
Ast_Node_array_list body;
|
||||
} lambda;
|
||||
#+end_src
|
||||
* TODO =assert_equal_type= macro in testing
|
||||
* DONE use an enum for builtin identifiers
|
||||
CLOSED: [2018-10-11 Do 17:15]
|
||||
* TODO dont create new nils or builtins, but store one of each globally
|
||||
* TODO source code locations for errors
|
||||
* Build-in forms
|
||||
|
||||
* TODO =assert_equal_type= macro in testing
|
||||
* TODO =t= ast node type, universal source of truth
|
||||
* TODO backquoting
|
||||
* TODO dont create new nils or builtins, but store one of each globally
|
||||
* TODO make keywords unique (binary tree)
|
||||
* TODO store all ast nodes in a huge arena
|
||||
* TODO source code locations for errors
|
||||
* TODO String error messages
|
||||
* TODO Rename macro to =special= or something
|
||||
* Build-in forms [29/30]
|
||||
** TODO info
|
||||
|
||||
** DONE let
|
||||
CLOSED: [2018-10-27 Sa 15:30]
|
||||
** DONE +
|
||||
CLOSED: [2018-09-18 Di 12:14]
|
||||
** DONE -
|
||||
@@ -206,8 +352,14 @@ set to see if we are in an errornious state.
|
||||
CLOSED: [2018-09-18 Di 12:14]
|
||||
** DONE /
|
||||
CLOSED: [2018-09-18 Di 12:14]
|
||||
** TODO >
|
||||
** TODO <
|
||||
** DONE >
|
||||
CLOSED: [2018-10-26 Fr 23:30]
|
||||
** DONE >=
|
||||
CLOSED: [2018-10-26 Fr 23:30]
|
||||
** DONE <
|
||||
CLOSED: [2018-10-26 Fr 23:30]
|
||||
** DONE >=
|
||||
CLOSED: [2018-10-26 Fr 23:30]
|
||||
** DONE =
|
||||
CLOSED: [2018-10-21 So 00:25]
|
||||
** DONE if
|
||||
@@ -239,10 +391,12 @@ set to see if we are in an errornious state.
|
||||
CLOSED: [2018-10-21 So 00:25]
|
||||
** DONE define
|
||||
CLOSED: [2018-10-08 Mo 20:28]
|
||||
** TODO mutateW
|
||||
** DONE mutate
|
||||
CLOSED: [2018-10-25 Do 19:40]
|
||||
** DONE lambda
|
||||
CLOSED: [2018-10-21 So 00:25]
|
||||
** TODO macro
|
||||
** DONE macro
|
||||
CLOSED: [2018-10-25 Do 19:40]
|
||||
** DONE prog
|
||||
CLOSED: [2018-10-21 So 00:25]
|
||||
** DONE eval
|
||||
@@ -279,5 +433,3 @@ set to see if we are in an errornious state.
|
||||
CLOSED: [2018-10-08 Mo 20:28]
|
||||
** DONE type
|
||||
CLOSED: [2018-10-08 Mo 21:30]
|
||||
|
||||
** TODO info
|
||||
|
||||
Reference in New Issue
Block a user