diff --git a/Makefile b/Makefile index ac42587..d6a2acc 100644 --- a/Makefile +++ b/Makefile @@ -2,8 +2,11 @@ all: generate body body: link compile run +stdlib: + csi -s compile-lib.scm programs/stdlib.scm > stdlib.ll + generate: - csi -s compile.scm > body.ll + csi -s compile-program.scm programs/main.scm > body.ll link: cat stdlib-ll/*.ll stdlib.ll body.ll > output.ll diff --git a/compatibility.scm b/compatibility.scm index 14a0a9a..72e91d9 100644 --- a/compatibility.scm +++ b/compatibility.scm @@ -86,9 +86,20 @@ (def any->string ->string) (def fixnum->string number->string) -(defn string-append* (lst) - (if (null? lst) - "" - (string-append (fst lst) (string-append* (rst lst))))) +(defn string-append* (lst) (foldl string-append "" lst)) (defn id (x) x) + +(defn char->string (char) (list->string (list char))) + +(defn filter (pred lst) + (cond ((null? lst) (list)) + ((eq? (pred (fst lst)) #t) + (cons (fst lst) + (filter pred (rst lst)))) + (else (filter pred (rst lst))))) + +(defn member? (var lst) + (cond ((null? lst) #f) + ((eq? var (fst lst)) #t) + (else (member? var (rst lst))))) diff --git a/compile-lib.scm b/compile-lib.scm index b3a48bd..52980fc 100644 --- a/compile-lib.scm +++ b/compile-lib.scm @@ -1,7 +1,7 @@ (include "compile.scm") (defn emit-lib (exprs) - (let ((preprocessed (map (fn (expr) (~> expr syntax-desugar alpha-convert-expr closure-convert)); normalize-term)) + (let ((preprocessed (map (fn (expr) (~> expr desugar alpha-convert-expr closure-convert)); normalize-term)) exprs))) (for-each emit-global-var global-vars) (for-each emit-lambda lambdas) @@ -10,7 +10,7 @@ (defn debug (expr) (print (~> expr)) - (let ((e2 (~> expr syntax-desugar))) + (let ((e2 (~> expr desugar))) (print e2) (let ((e3 (~> e2 alpha-convert-expr))) (print e3) diff --git a/compile-program.scm b/compile-program.scm index 0592241..b2d2ec9 100644 --- a/compile-program.scm +++ b/compile-program.scm @@ -1,7 +1,7 @@ (include "compile.scm") (defn emit-program (exprs) - (let ((preprocessed (map (fn (expr) (~> expr syntax-desugar alpha-convert-expr closure-convert)); normalize-term)) + (let ((preprocessed (map (fn (expr) (~> expr desugar alpha-convert-expr closure-convert)); normalize-term)) exprs))) (for-each emit-global-var global-vars) (for-each (fn (expr) @@ -25,7 +25,7 @@ ; (defn debug (expr) ; (print (~> expr)) -; (let ((e2 (~> expr syntax-desugar))) +; (let ((e2 (~> expr desugar))) ; (print e2) ; (let ((e3 (~> e2 alpha-convert-expr))) ; (print e3) diff --git a/compile.scm b/compile.scm index 0784001..d568016 100644 --- a/compile.scm +++ b/compile.scm @@ -7,7 +7,7 @@ (include "syntax/begin.scm") (include "syntax/let.scm") (include "syntax/string.scm") -(include "preprocessing/syntax-desugar.scm") +(include "preprocessing/desugar.scm") (include "preprocessing/alpha-convert.scm") (include "preprocessing/closure-convert.scm") @@ -78,10 +78,14 @@ (print (string-append* (list "@var_" (escape var) " = weak global i64 0")))) (defn emit-expr (var env expr) + ; (print " ;" var " = " expr) (cond ((immediate? expr) (emit-immediate var expr)) ((string? expr) (emit-string var expr)) - ((tagged-list? expr 'quote) (emit-symbol var (frst expr))) + ((tagged-list? expr 'quote) + (if (eq? (frst expr) '()) + (emit-immediate var '()) + (emit-symbol var (frst expr)))) ((if? expr) (emit-if var env expr)) ((begin? expr) (emit-begin var env expr)) ((let? expr) (emit-let var env expr)) @@ -136,7 +140,9 @@ (print (string-append* (list " " var " = call i64 @" (escape name) "(" (string-join2 vars ", ") ")" ))))))) ((variable? expr) (emit-variable-ref var env expr)) (else - (error "Unknown expression: " expr)))) + (error "Unknown expression: " expr))) + ) + ; (print " ; end of " var " = " expr)) (defn emit-variable-ref (var env expr) ; (print ">>> emit-var-ref " expr) @@ -145,7 +151,8 @@ (if (eq? (string-ref (rst res) 0) #\@) (emit-load var (rst res)) (emit-copy var (rst res))) - (error "can't find " var " in env")))) + ; (emit-load var (string-append "@var_" (escape expr)))))) + (error "can't find " expr " in env")))) (defn emit-symbol (var expr) (let ((tmp (generate-var))) @@ -154,7 +161,7 @@ (defn debug-program (exprs) (let ((preprocessed (map (fn (expr) - (~> expr syntax-desugar alpha-convert-expr closure-convert)) + (~> expr desugar alpha-convert-expr closure-convert)) (append stdlib exprs)))) (print ">>> Global vars") (for-each print global-vars) diff --git a/helper.scm b/helper.scm index d660c3d..4596c0a 100644 --- a/helper.scm +++ b/helper.scm @@ -18,29 +18,26 @@ (string-append "i64, " (arg-str (sub1 arity)))))) +(defn escape-char (char) char + (cond + ((eq? char #\+) "_plus_") + ((eq? char #\>) "_greater_") + ((eq? char #\<) "_less_") + ((eq? char #\=) "_equal_") + ((eq? char #\*) "_times_") + ((eq? char #\/) "_slash_") + ((eq? char #\?) "_questionmark_") + (else (char->string char)))) + (defn escape (str) (~>> str any->string string->list - (map any->string) (map escape-char) (cons "prim_") - string-join)) - -(defn escape-char (str) - (cond - ((equal? str "+") "_plus_") - ((equal? str ">") "_greater_") - ((equal? str "<") "_less_") - ((equal? str "=") "_equal_") - ((equal? str "*") "_times_") - ((equal? str "/") "_slash_") - ((equal? str "?") "_questionmark_") - (else str))) + string-append*)) (defn tagged-list? (expr tag) (and (pair? expr) - (eq? (car expr) tag))) - -(defn string-join (lst) (foldl string-append "" lst)) + (eq? (fst expr) tag))) (defn map-with-index (f start lst) (if (null? lst) @@ -50,9 +47,20 @@ (map-with-index f (add1 start) (rst lst))))) (defn empty-set () (list)) -(defn set (expr) (list expr)) -(defn set-union (a b) (lset-union eq? a b)) -(defn set-subtract (a b) (lset-difference eq? a b)) +(defn singleton-set (expr) (list expr)) + +(defn set-subtract (a b) + (filter (fn (e) (not (member? e b))) + a)) + +(defn set-union (a b) + (cond + ((null? a) b) + ((null? b) a) + ((member? (fst b) a) + (set-union a (rst b))) + (else + (set-union (cons (fst b) a) (rst b))))) (defn set-union* (sets) (cond diff --git a/preprocessing/closure-convert.scm b/preprocessing/closure-convert.scm index cd6f0e3..ecb0601 100644 --- a/preprocessing/closure-convert.scm +++ b/preprocessing/closure-convert.scm @@ -1,8 +1,8 @@ (defn closure-convert-expr (expr) (closure-convert expr)) -(def lambdas '()) -(def global-vars '()) +(def lambdas (list)) +(def global-vars (list)) (defn register-lamdba (name body) (let ((old-lambdas lambdas)) @@ -86,7 +86,7 @@ bindings))))) ; ((and (symbol? expr) (not (primitive? expr))) ((and (symbol? expr) (not (assoc expr (global-var-env)))) - (set expr)) + (singleton-set expr)) ((tagged-list? expr 'quote) (empty-set)) ((list? expr) diff --git a/preprocessing/desugar.scm b/preprocessing/desugar.scm new file mode 100644 index 0000000..cdcaed7 --- /dev/null +++ b/preprocessing/desugar.scm @@ -0,0 +1,166 @@ +(defn desugar (expr) + (cond + ((thread-first? expr) (~> expr thread-first->nested-calls desugar)) + ((thread-last? expr) (~> expr thread-last->nested-calls desugar)) + ((list_? expr) (~> expr list->nested-cons desugar)) + ((let*? expr) (~> expr let*->nested-lets desugar)) + ((cond? expr) (~> expr cond->nested-ifs desugar)) + ((and? expr) (~> expr and->if desugar)) + ((or? expr) (~> expr or->if desugar)) + ((defn? expr) (~> expr defn->def-fn desugar)) + ((quote? expr) (~> expr frst desugar-quote)) + ((quasiquote? expr) (~>> expr frst (desugar-quasiquote 1) desugar)) + ((let? expr) + (let* ((bindings (let-bindings expr)) + (new-bindings + (map (fn (binding) + (list (let-binding-variable binding) + (desugar (let-binding-value binding)))) + bindings))) + (make-let new-bindings + (~> expr + let-body_ + make-sequence + desugar)))) + ((begin? expr) + (let ((expressions (begin-expressions expr))) + (if (null? (rst expressions)) + (fst expressions) + (~>> expressions + (map desugar) + make-begin)))) + ((def? expr) + (make-def (def-name expr) + (desugar (def-value expr)))) + ((defprim? expr) + (make-defprim (defprim-name expr) + (defprim-args expr) + (~> expr + defprim-body_ + make-sequence + desugar))) + ((fn? expr) + (make-fn (fn-params expr) + (~> expr + fn-body_ + make-sequence + desugar))) + ((assignment? expr) + (make-assignment (assignment-name expr) + (desugar (assignment-value expr)))) + ((list? expr) + (map desugar expr)) + ((atomic? expr) expr) + (else + (error "Can not desugar expr: " expr)))) + +(defn desugar-quote (expr) + (cond + ((pair? expr) + `(cons ,(desugar-quote (fst expr)) + ,(desugar-quote (rst expr)))) + ((null? expr) '()) + ((immediate? expr) expr) + ((symbol? expr) `(quote ,expr)) + (else + (error "Strange value in quote: " expr)))) + +(defn desugar-quasiquote (level expr) + (cond + ((unquote? expr) + (if (eq? level 1) + (desugar (frst expr)) + (list 'list ''unquote + (desugar-quasiquote (sub1 level) (frst expr))))) + ((quasiquote? expr) + `(list 'quasiquote ,(desugar-quasiquote (add1 level) + (frst expr)))) + ((and (pair? expr) (unquote-splicing? (fst expr))) + (if (eq? level 1) + `(append ,(frfst expr) ,(desugar-quasiquote level (rst expr))) + (cons (list 'unquote-splicing + (desugar-quasiquote (sub1 level) (frfst expr))) + (desugar-quasiquote level (frst expr))))) + ((pair? expr) + `(cons ,(desugar-quasiquote level (fst expr)) + ,(desugar-quasiquote level (rst expr)))) + (else (desugar-quote expr)))) + +(defn let*->nested-lets (expr) + (let* ((bindings (let-bindings expr)) + (body (make-sequence (let-body_ expr)))) + (if (null? bindings) + body + (make-let (list (fst bindings)) + (~> bindings + rst + (make-let* body) + let*->nested-lets))))) + +(defn defn->def-fn (expr) + (make-def (defn-name expr) + (make-fn (defn-args expr) + (make-sequence (defn-body_ expr))))) + +(defn list->nested-cons (expr) (list->nested-cons_ (rst expr))) +(defn list->nested-cons_ (elems) + (if (null? elems) + '() + (list 'cons (fst elems) + (list->nested-cons_ (rst elems))))) + +(defn thread-first->nested-calls (expr) (thread-first->nested-calls_ (frst expr) (rrst expr))) +(defn thread-first->nested-calls_ (var fns) + (if (null? fns) + var + (thread-first->nested-calls_ + (let ((fn (fst fns))) + (if (list? fn) + (cons (fst fn) + (cons var + (rst fn))) + (list fn var))) + (rst fns)))) + +(defn thread-last->nested-calls (expr) (thread-last->nested-calls_ (frst expr) (rrst expr))) +(defn thread-last->nested-calls_ (var fns) + (if (null? fns) + var + (thread-last->nested-calls_ + (let ((fn (fst fns))) + (if (list? fn) + (append fn (list var)) + (list fn var))) + (rst fns)))) + +(defn cond->nested-ifs (expr) (cond->nested-ifs_ (cond-clauses expr))) +(defn cond->nested-ifs_ (clauses) + (cond + ((null? clauses) (error "Empty cond: " expr)) + ((null? (rst clauses)) (error "cond must have at least 2 branches: " expr)) + ((null? (rrst clauses)) + (let ((first-clause (fst clauses)) + (second-clause (frst clauses))) + (if (eq? 'else (cond-clause-test second-clause)) + (make-if (cond-clause-test first-clause) + (make-sequence (cond-clause-action_ first-clause)) + (make-sequence (cond-clause-action_ second-clause))) + (error "Last clause of cond must be else: " expr)))) + (else + (let ((first-clause (fst clauses)) + (rest-clauses (rst clauses))) + (make-if (cond-clause-test first-clause) + (make-sequence (cond-clause-action_ first-clause)) + (cond->nested-ifs_ rest-clauses)))))) + +(defn or->if (expr) (or->if_ (or-arguments expr))) +(defn or->if_ (expr) + (if (null? expr) + #f + `(if ,(fst expr) #t ,(or->if_ (rst expr))))) + +(defn and->if (expr) (and->if_ (and-arguments expr))) +(defn and->if_ (expr) + (if (null? expr) + #t + `(if ,(fst expr) ,(and->if_ (rst expr)) #f))) diff --git a/preprocessing/syntax-desugar.scm b/preprocessing/syntax-desugar.scm deleted file mode 100644 index 78fc290..0000000 --- a/preprocessing/syntax-desugar.scm +++ /dev/null @@ -1,153 +0,0 @@ -(defn syntax-desugar (expr) - ; (print "synde " expr) - (cond - ((thread-first? expr) (~> expr thread-first->nested-calls syntax-desugar)) - ((thread-last? expr) (~> expr thread-last->nested-calls syntax-desugar)) - ((list_? expr) (~> expr list->nested-cons syntax-desugar)) - ((let*? expr) (~> expr let*->nested-lets syntax-desugar)) - ((cond? expr) (~> expr cond->nested-ifs syntax-desugar)) - ((and? expr) (~> expr and->if syntax-desugar)) - ((or? expr) (~> expr or->if syntax-desugar)) - ((defn? expr) (~> expr defn->def-fn syntax-desugar)) - ((let? expr) - (let* ((bindings (let-bindings expr)) - (new-bindings - (map (fn (binding) - (list (let-binding-variable binding) - (syntax-desugar (let-binding-value binding)))) - bindings))) - (make-let new-bindings - (~> expr - let-body_ - make-sequence - syntax-desugar)))) - ((begin? expr) - (let ((expressions (begin-expressions expr))) - (if (null? (rst expressions)) - (fst expressions) - (~>> expressions - (map syntax-desugar) - make-begin)))) - - ; ((begin? expr) - ; (cons 'begin - ; (~>> expr - ; begin-expressions - ; (map syntax-desugar)))) - ((def? expr) - (make-def (def-name expr) - (syntax-desugar (def-value expr)))) - ((defprim? expr) - (make-defprim (defprim-name expr) - (defprim-args expr) - (~> expr - defprim-body_ - make-sequence - syntax-desugar))) - ((fn? expr) - (make-fn (fn-params expr) - (~> expr - fn-body_ - make-sequence - syntax-desugar))) - ((assignment? expr) - (make-assignment (assignment-name expr) - (syntax-desugar (assignment-value expr)))) - ((list? expr) - (map syntax-desugar expr)) - ((atomic? expr) expr) - (else - (error "Can not desugar expr: " expr)))) - -(defn let*->nested-lets (expr) - (let* ((bindings (let-bindings expr)) - (body (make-sequence (let-body_ expr)))) - (if (null? bindings) - body - (make-let (list (fst bindings)) - (~> bindings - rst - (make-let* body) - let*->nested-lets))))) - -(defn defn->def-fn (expr) - (make-def (defn-name expr) - (make-fn (defn-args expr) - (make-sequence (defn-body_ expr))))) - -(defn list->nested-cons (expr) - (list->nested-cons_ (rst expr))) -(defn list->nested-cons_ (elems) - (if (null? elems) - '() - (list 'cons (fst elems) - (list->nested-cons_ (rst elems))))) - -(defn thread-first->nested-calls (expr) - (thread-first->nested-calls_ (frst expr) (rrst expr))) - -(defn thread-last->nested-calls (expr) - (thread-last->nested-calls_ (frst expr) (rrst expr))) - -(defn thread-first->nested-calls_ (var fns) - (if (null? fns) - var - (thread-first->nested-calls_ - (let ((fn (fst fns))) - (if (list? fn) - (cons (fst fn) - (cons var - (rst fn))) - (list fn var))) - (rst fns)))) - -(defn thread-last->nested-calls_ (var fns) - (if (null? fns) - var - (thread-last->nested-calls_ - (let ((fn (fst fns))) - (if (list? fn) - (append fn (list var)) - (list fn var))) - (rst fns)))) - -(defn cond->nested-ifs (expr) - (defn helper (clauses) - (cond - ((null? clauses) - (error "Empty cond: " expr)) - ((null? (rst clauses)) - (error "cond must have at least 2 branches: " expr)) - ((null? (rrst clauses)) - (let ((first-clause (fst clauses)) - (second-clause (frst clauses))) - (if (eq? 'else (cond-clause-test second-clause)) - (make-if (cond-clause-test first-clause) - (make-sequence (cond-clause-action_ first-clause)) - (make-sequence (cond-clause-action_ second-clause))) - (error "Last clause of cond must be else: " expr)))) - (else - (let ((first-clause (fst clauses)) - (rest-clauses (rst clauses))) - (make-if (cond-clause-test first-clause) - (make-sequence (cond-clause-action_ first-clause)) - (helper rest-clauses)))))) - (helper (cond-clauses expr))) - -(defn or->if (expr) - (define (loop expr) - (if (null? expr) - #f - `(if ,(fst expr) - #t - ,(loop (rst expr))))) - (loop (or-arguments expr))) - -(defn and->if (expr) - (define (loop expr) - (if (null? expr) - #t - `(if ,(fst expr) - ,(loop (rst expr)) - #f))) - (loop (and-arguments expr))) diff --git a/programs/hello_world.scm b/programs/hello_world.scm deleted file mode 100644 index ee9d84e..0000000 --- a/programs/hello_world.scm +++ /dev/null @@ -1,31 +0,0 @@ -(def var-counter 0) -(defn generate-var () - (set! var-counter (fxadd1 var-counter)) - (string-append "%tmp" - (fixnum->string var-counter))) - -(print (generate-var)) -(print (generate-var)) - -; (defn map (f lst) -; (if (null? lst) -; lst -; (cons (f (fst lst)) -; (map f (rst lst))))) - -; (defn fib (n) -; (if (fx<=? n 1) -; n -; (fx+ (fib (fx- n 1)) -; (fib (fx- n 2))))) - -; (inspect fib) -; ; (print "hello world") - -; (inspect (map fib (list 1 2 3 4))) - -; (puts "test") -; (inspect (fib 10)) -; (puts "test") -; ; (print (char->string (fixnum->char (fib 10)))) -; (puts "test") diff --git a/programs/main.scm b/programs/main.scm new file mode 100644 index 0000000..6dc85c8 --- /dev/null +++ b/programs/main.scm @@ -0,0 +1,248 @@ +; (defn def? (expr) (tagged-list? expr 'def)) +; (defn def-name (expr) (frst expr)) +; (defn def-value (expr) (frrst expr)) +; (defn make-def (name value) (list 'def name value)) + +; (defn defn? (expr) (tagged-list? expr 'defn)) +; (defn defn-name (expr) (frst expr)) +; (defn defn-args (expr) (frrst expr)) +; (defn defn-body (expr) (frrrst expr)) +; (defn defn-body_ (expr) (rrrst expr)) +; (defn make-defn (name args body) (list 'defn name args body)) + +; (defn defprim? (expr) (tagged-list? expr 'defprim)) +; (defn defprim-name (expr) (frst expr)) +; (defn defprim-args (expr) (frrst expr)) +; (defn defprim-body (expr) (frrrst expr)) +; (defn defprim-body_ (expr) (rrrst expr)) +; (defn make-defprim (name args body) (list 'defprim name args body)) + +; (defn fn? (expr) (tagged-list? expr 'fn)) +; (defn fn-params (expr) (frst expr)) +; (defn fn-body (expr) (frrst expr)) +; (defn fn-body_ (expr) (rrst expr)) +; (defn make-fn (params body) +; (list 'fn params body)) + +; (defn assignment? (expr) (tagged-list? expr 'set!)) +; (defn assignment-name (expr) (frst expr)) +; (defn assignment-value (expr) (frrst expr)) +; (defn make-assignment (name value) (list 'set! name value)) + +; (defn if? (expr) (tagged-list? expr 'if)) +; (defn if-test (expr) (frst expr)) +; (defn if-consequent (expr) (frrst expr)) +; (defn if-alternative (expr) (frrrst expr)) + +; (defn make-if (test con alt) (list 'if test con alt)) + +; (defn list_? (expr) (tagged-list? expr 'list)) + +; (defn thread-first? (expr) (tagged-list? expr '~>)) +; (defn thread-last? (expr) (tagged-list? expr '~>>)) + +; (defn cond? (expr) (tagged-list? expr 'cond)) +; (defn cond-clauses (expr) (rst expr)) +; (defn cond-clause-test (expr) (fst expr)) +; (defn cond-clause-action (clause) (frst clause)) +; (defn cond-clause-action_ (clause) (rst clause)) + +; (defn or? (expr) (tagged-list? expr 'or)) +; (defn or-arguments (expr) (rst expr)) + +; (defn and? (expr) (tagged-list? expr 'and)) +; (defn and-arguments (expr) (rst expr)) + +; (defn let? (expr) (tagged-list? expr 'let)) +; (defn let-bindings (expr) (frst expr)) +; (defn let-body (expr) (frrst expr)) +; (defn let-body_ (expr) (rrst expr)) + +; (defn let-binding-variable (expr) (fst expr)) +; (defn let-binding-value (expr) (frst expr)) + +; (defn make-let (bindings body) +; (list 'let bindings body)) + +; (defn let*? (expr) (tagged-list? expr 'let*)) +; (defn make-let* (bindings body) +; (list 'let* bindings body)) + +; (defn begin? (expr) (tagged-list? expr 'begin)) +; (defn begin-expressions (expr) (rst expr)) + +; (defn make-sequence (expressions) +; (cond ((null? expressions) expressions) +; ((null? (rst expressions)) (fst expressions)) +; (else (make-begin expressions)))) + +; (defn make-begin (expressions) +; (cons 'begin expressions)) + +; (inspect (make-sequence (list 'foo))) + +; ; (defn syntax-desugar (expr) +; ; ; (print "synde " expr) +; ; (cond +; ; ((thread-first? expr) (~> expr thread-first->nested-calls syntax-desugar)) +; ; ((thread-last? expr) (~> expr thread-last->nested-calls syntax-desugar)) +; ; ((list_? expr) (~> expr list->nested-cons syntax-desugar)) +; ; ((let*? expr) (~> expr let*->nested-lets syntax-desugar)) +; ; ((cond? expr) (~> expr cond->nested-ifs syntax-desugar)) +; ; ((and? expr) (~> expr and->if syntax-desugar)) +; ; ((or? expr) (~> expr or->if syntax-desugar)) +; ; ((defn? expr) (~> expr defn->def-fn syntax-desugar)) +; ; ((let? expr) +; ; (let* ((bindings (let-bindings expr)) +; ; (new-bindings +; ; (map (fn (binding) +; ; (list (let-binding-variable binding) +; ; (syntax-desugar (let-binding-value binding)))) +; ; bindings))) +; ; (make-let new-bindings +; ; (~> expr +; ; let-body_ +; ; make-sequence +; ; syntax-desugar)))) +; ; ((begin? expr) +; ; (let ((expressions (begin-expressions expr))) +; ; (if (null? (rst expressions)) +; ; (fst expressions) +; ; (~>> expressions +; ; (map syntax-desugar) +; ; make-begin)))) + +; ; ; ((begin? expr) +; ; ; (cons 'begin +; ; ; (~>> expr +; ; ; begin-expressions +; ; ; (map syntax-desugar)))) +; ; ((def? expr) +; ; (make-def (def-name expr) +; ; (syntax-desugar (def-value expr)))) +; ; ((defprim? expr) +; ; (make-defprim (defprim-name expr) +; ; (defprim-args expr) +; ; (~> expr +; ; defprim-body_ +; ; make-sequence +; ; syntax-desugar))) +; ; ((fn? expr) +; ; (make-fn (fn-params expr) +; ; (~> expr +; ; fn-body_ +; ; make-sequence +; ; syntax-desugar))) +; ; ((assignment? expr) +; ; (make-assignment (assignment-name expr) +; ; (syntax-desugar (assignment-value expr)))) +; ; ((list? expr) +; ; (map syntax-desugar expr)) +; ; ((atomic? expr) expr) +; ; (else +; ; (error "Can not desugar expr: " expr)))) + +; ; (defn let*->nested-lets (expr) +; ; (let* ((bindings (let-bindings expr)) +; ; (body (make-sequence (let-body_ expr)))) +; ; (if (null? bindings) +; ; body +; ; (make-let (list (fst bindings)) +; ; (~> bindings +; ; rst +; ; (make-let* body) +; ; let*->nested-lets))))) + +; ; (defn defn->def-fn (expr) +; ; (make-def (defn-name expr) +; ; (make-fn (defn-args expr) +; ; (make-sequence (defn-body_ expr))))) + +; ; (defn list->nested-cons (expr) +; ; (list->nested-cons_ (rst expr))) +; ; (defn list->nested-cons_ (elems) +; ; (if (null? elems) +; ; (list) +; ; (list 'cons (fst elems) +; ; (list->nested-cons_ (rst elems))))) + +; ; (defn thread-first->nested-calls (expr) +; ; (thread-first->nested-calls_ (frst expr) (rrst expr))) + +; ; (defn thread-last->nested-calls (expr) +; ; (thread-last->nested-calls_ (frst expr) (rrst expr))) + +; ; (defn thread-first->nested-calls_ (var fns) +; ; (if (null? fns) +; ; var +; ; (thread-first->nested-calls_ +; ; (let ((fn (fst fns))) +; ; (if (list? fn) +; ; (cons (fst fn) +; ; (cons var +; ; (rst fn))) +; ; (list fn var))) +; ; (rst fns)))) + +; ; (defn thread-last->nested-calls_ (var fns) +; ; (if (null? fns) +; ; var +; ; (thread-last->nested-calls_ +; ; (let ((fn (fst fns))) +; ; (if (list? fn) +; ; (append fn (list var)) +; ; (list fn var))) +; ; (rst fns)))) + +; ; (defn cond->nested-ifs (expr) +; ; (defn helper (clauses) +; ; (cond +; ; ((null? clauses) +; ; (error "Empty cond: " expr)) +; ; ((null? (rst clauses)) +; ; (error "cond must have at least 2 branches: " expr)) +; ; ((null? (rrst clauses)) +; ; (let ((first-clause (fst clauses)) +; ; (second-clause (frst clauses))) +; ; (if (eq? 'else (cond-clause-test second-clause)) +; ; (make-if (cond-clause-test first-clause) +; ; (make-sequence (cond-clause-action_ first-clause)) +; ; (make-sequence (cond-clause-action_ second-clause))) +; ; (error "Last clause of cond must be else: " expr)))) +; ; (else +; ; (let ((first-clause (fst clauses)) +; ; (rest-clauses (rst clauses))) +; ; (make-if (cond-clause-test first-clause) +; ; (make-sequence (cond-clause-action_ first-clause)) +; ; (helper rest-clauses)))))) +; ; (helper (cond-clauses expr))) + +; ; (defn or->if (expr) +; ; (or->if_ (or-arguments expr))) + +; ; (defn or->if_ (expr) +; ; (if (null? expr) +; ; #f +; ; `(if ,(fst expr) +; ; #t +; ; ,(or->if_ (rst expr))))) + +; ; (defn and->if (expr) +; ; (loop (and-arguments expr))) + +; ; (defn and->if_ (expr) +; ; (if (null? expr) +; ; #t +; ; `(if ,(fst expr) +; ; ,(and->if_ (rst expr)) +; ; #f))) + +; ; ; (inspect (syntax-desugar '(~> x add1 add1))) +; ; (inspect (syntax-desugar '(~> x add1 add1))) + +; (inspect `(1 ```,,@,,@(list (fx+ 1 2)) 4)) +; (inspect `(1 ,@(list 1 2) 4)) +; (inspect `(1 `,(+ 1 ,(+ 2 3)) 4)) +; (inspect `(1 `,(+ 1 ,(+ 2 3)) 4)) + +(inspect (string->list "test")) diff --git a/programs/stdlib.scm b/programs/stdlib.scm index f9e9eb5..05e6a54 100644 --- a/programs/stdlib.scm +++ b/programs/stdlib.scm @@ -5,8 +5,7 @@ (defprim pair? (val) (eq? (__tag val) 6)) (defprim fixnum? (val) (eq? (__tag val) 0)) -(defprim null? (val) (eq? val (list))) - +(defprim null? (val) (eq? val '())) ; For now, the only fixnums are supported ; => just wrap the fixnum functions @@ -22,6 +21,38 @@ (defprim > (a b) (fx>? a b)) (defprim >= (a b) (fx>=? a b)) +(defprim ffst (e) (fst (fst e))) +(defprim frst (e) (fst (rst e))) +(defprim rfst (e) (rst (fst e))) +(defprim rrst (e) (rst (rst e))) + +(defprim fffst (e) (fst (fst (fst e)))) +(defprim ffrst (e) (fst (fst (rst e)))) +(defprim frfst (e) (fst (rst (fst e)))) +(defprim frrst (e) (fst (rst (rst e)))) +(defprim rffst (e) (rst (fst (fst e)))) +(defprim rfrst (e) (rst (fst (rst e)))) +(defprim rrfst (e) (rst (rst (fst e)))) +(defprim rrrst (e) (rst (rst (rst e)))) + +(defprim ffffst (e) (fst (fst (fst (fst e))))) +(defprim fffrst (e) (fst (fst (fst (rst e))))) +(defprim ffrfst (e) (fst (fst (rst (fst e))))) +(defprim ffrrst (e) (fst (fst (rst (rst e))))) +(defprim frffst (e) (fst (rst (fst (fst e))))) +(defprim frfrst (e) (fst (rst (fst (rst e))))) +(defprim frrfst (e) (fst (rst (rst (fst e))))) +(defprim frrrst (e) (fst (rst (rst (rst e))))) + +(defprim rfffst (e) (rst (fst (fst (fst e))))) +(defprim rffrst (e) (rst (fst (fst (rst e))))) +(defprim rfrfst (e) (rst (fst (rst (fst e))))) +(defprim rfrrst (e) (rst (fst (rst (rst e))))) +(defprim rrffst (e) (rst (rst (fst (fst e))))) +(defprim rrfrst (e) (rst (rst (fst (rst e))))) +(defprim rrrfst (e) (rst (rst (rst (fst e))))) +(defprim rrrrst (e) (rst (rst (rst (rst e))))) + (defprim fixnum->string_ (fx) (if (fxzero? fx) "" @@ -34,6 +65,15 @@ ((fxstring_ (fx- 0 fx)))) (else (fixnum->string_ fx)))) +(defprim string->list (str) + (string->list_ str 0 (string-length str))) + +(defprim string->list_ (str idx len) + (if (eq? idx len) + '() + (cons (string-ref str idx) + (string->list_ str (fxadd1 idx) len)))) + (defprim string-append* (lst) (if (null? lst) "" @@ -144,7 +184,7 @@ ; (inspect idx) (let ((char (string-ref str idx))) (cond - ((eq? char #\)) (cons (fxadd1 idx) (list))) + ((eq? char #\)) (cons (fxadd1 idx) '())) (else (let* ((res (read_ str idx len)) (new-idx (fst res)) @@ -176,8 +216,46 @@ (fxadd1 idx) (skip-comment str (fxadd1 idx) len))))) -; (defprim map (f lst) -; (if (null? lst) -; lst -; (cons (f (fst lst)) -; (map f (rst lst))))) +(defprim map (f lst) + (if (null? lst) + lst + (cons (f (fst lst)) + (map f (rst lst))))) + +(defprim for-each (f lst) + (if (null? lst) + 'done + (begin + (f (fst lst)) + (for-each f (rst lst))))) + +(defprim filter (pred lst) + (cond ((null? lst) '()) + ((eq? (pred (fst lst)) #t) + (cons (fst lst) + (filter pred (rst lst)))) + (else (filter pred (rst lst))))) + +(defprim alist-cons (var val alist) + (cons (cons var val) alist)) + +(defprim assoc (var alist) + (cond ((null? alist) #f) + ((eq? (ffst alist) var) (fst alist)) + (else (assoc var (rst alist))))) + +(defprim member? (var lst) + (cond ((null? lst) #f) + ((eq? var (fst lst)) #t) + (else (member? var (rst lst))))) + +(defprim append (a b) + (cond ((null? a) b) + ((null? b) a) + (else + (cons (fst a) + (append (rst a) b))))) + +(defprim tagged-list? (lst tag) + (and (not (null? lst)) + (eq? (fst lst) tag))) diff --git a/stdlib.scm b/stdlib.scm index ae2303f..c10f1b6 100644 --- a/stdlib.scm +++ b/stdlib.scm @@ -10,7 +10,8 @@ string=? string-ref string-substring closure-arity list-ref - inspect + inspect assoc alist-cons + char->string ; TODO: some preprocessing step does not handle begin begin if ))) diff --git a/syntax.scm b/syntax.scm index 82efa0a..5852a6b 100644 --- a/syntax.scm +++ b/syntax.scm @@ -38,7 +38,8 @@ (defn list_? (expr) (tagged-list? expr 'list)) -(defn pipe? (expr) (tagged-list? expr 'pipe)) +(defn thread-first? (expr) (tagged-list? expr '~>)) +(defn thread-last? (expr) (tagged-list? expr '~>>)) (defn cond? (expr) (tagged-list? expr 'cond)) (defn cond-clauses (expr) (rst expr)) @@ -60,6 +61,11 @@ (defn let-binding-variable (expr) (fst expr)) (defn let-binding-value (expr) (frst expr)) +(defn quote? (expr) (tagged-list? expr 'quote)) +(defn quasiquote? (expr) (tagged-list? expr 'quasiquote)) +(defn unquote? (expr) (tagged-list? expr 'unquote)) +(defn unquote-splicing? (expr) (tagged-list? expr 'unquote-splicing)) + (defn make-let (bindings body) (list 'let bindings body))