diff options
| author | 2024-06-21 22:45:46 -0400 | |
|---|---|---|
| committer | 2024-06-21 22:45:46 -0400 | |
| commit | 413b9614d2f82b784cb9da239878ff9565529491 (patch) | |
| tree | 5a7b7cc95d458530e83a6d7d6de78244ce4bdafd /prelude.scm | |
| parent | tokenizer: fix number tokenizer eating non-number characters (diff) | |
improper lists, floats
Diffstat (limited to 'prelude.scm')
| -rw-r--r-- | prelude.scm | 73 |
1 files changed, 49 insertions, 24 deletions
diff --git a/prelude.scm b/prelude.scm index 097ca64..cb22b18 100644 --- a/prelude.scm +++ b/prelude.scm @@ -34,8 +34,10 @@ ; ; Others: ; __uniapply: Apply function to single argument -; __null: A value that can only be passed to __unilambda. It cannot be -; bound to a top-level, or "set!", or added to a list. +; <undefined>: A value that can only be passed to __unilambda. It cannot +; be bound to a top-level, or "set!", or added to a list. +; It can also be the parameter of a __unilambda, although +; it still cannot be used. ; ; Macros are functions that return an sexpr. @@ -48,7 +50,7 @@ ; (cdr (car (car args))) = (a) `((__unilambda ,(car (car (car args))) (let ,(cdr (car args)) ,@body)) - ,(car (cdr (car (car args)))) + . ,(car (cdr (car (car args)))) ) ) ) @@ -56,6 +58,20 @@ (__define-macro let* let) +; if and __unilambda only execute one statement. This uses Flatrate's +; evaluation order (arguments first) and tail-call optimization to simulate +; multiple statements. +(__define-macro begin body + (let ((first (car body)) + (rest (cdr body)) + ) + (if (null? rest) + first + `((__unilambda <undefined> (begin ,@rest)) . ,first) + ) + ) +) + (__define-macro __bindlambda (__unilambda l (let ((larg (car l)) @@ -66,7 +82,7 @@ `(__unilambda larg (if (not (null? larg)) (raise "incorrect number of arguments") - ,body + (begin ,@body) ) ) (let* ((argval (cons args)) @@ -90,12 +106,12 @@ ) (if (symbol? args) `(__unilambda ,args ,@body) - (let ((larg (gensym))) - (if (null? args) - `(__unilambda ,larg ,@body) - `(__bindlambda ,larg . body) - ) - ) + (if (null? args) + `(__unilambda <undefined> (begin ,@body)) + (let ((larg (gensym))) + `(__bindlambda ,larg ,@body) + ) + ) ) ) ) @@ -110,23 +126,12 @@ (tmpname (gensym)) ) `(__define-macro ,name - (lambda ,args ,body) + (lambda ,args ,@body) ) ) ) ) -(define-macro (define name . body) - (if (symbol? name) - `(__define ,name ,@body) - `(__define ,(car name) (lambda ,(cdr name) ,@body)) - ) -) - -(define-macro (begin . body) - `((lambda () ,@body)) -) - (define-macro (and . body) (if (null? body) 1 @@ -157,13 +162,33 @@ (val (car (cdr argval))) (rest (cdr args)) ) - `(let ((,arg __null)) - (letrec ,rest (set! ,arg ,val) ,@body) + `(let ((,arg <undefined>)) + (letrec ,rest (begin (set! ,arg ,val) ,@body)) ) ) ) ) +(define-macro (define name . body) + (if (symbol? name) + `(__define ,name ,@body) + (let ((fname (car name)) + (args (cdr name)) + (tmparg (gensym)) + ) + `(__define ,fname + (lambda ,tmparg + (letrec ((,fname (lambda ,args ,@body))) + (,fname . ,tmparg) + ) + ) + ) + ) + ) +) + +;;;;;;;;;;;;;; Standard Library ;;;;;;;;;;;;;;;;;;; + ;; for a list of (v1 v2 ... vn) ;; runs (f vn (... (f v2 (f v1 start)))) (define (foldl f start l) |
