Login
7 branches 0 tags
Ben (RPI 4) Added GH Action for building a wasm repl 5dae78d 4 years ago 171 Commits
nujel / stdlib / z_compiler.nuj
;; Contains the self-hosting Nujel compiler

[def compile [let*
    [defun compile-do-args [args]
           ;[display ["[do-args] " [str/write args] "\n\n"]]
           [if [nil? [cdr args]]
               [cons [compile [car args]] #nil]
               [if [pair? [car args]]
                   [let* [def ocar [compile [car args]]]
                         [if [pair? ocar]
                             [cons ocar [compile-do-args [cdr args]]]
                             [compile-do-args [cdr args]]]
                   ]
                   [compile-do-args [cdr args]]]]
    ]

    [defun compile-do [source]
           ;[display ["[do] " [str/write source] "\n\n"]]
           [let* [def args [compile-do-args source]]
                 [if [nil? [cdr args]]
                     [car args]
                     [cons 'do args]]
           ]
    ]

    [defun compile-def [source]
           ;[display ["[def] " [str/write source] "\n\n"]]
           [list 'def [cadr source] [compile [caddr source]]]
    ]

    [defun compile-set! [source]
        ;[display ["[set] " [str/write source] "\n\n"]]
        [list 'set! [cadr source] [compile [caddr source]]]
    ]

    [defun compile-fun [source]
           ;[display ["[λ] " [str/write source] "\n\n"]]
           [if [string?  [caddr source]]
               [list 'λ* [cadr source] [caddr source] [compile-do [cddr source]]]
               [list 'λ* [cadr source]             "" [compile-do [cddr source]]]]
    ]

    [defun compile-try [source]
           ;[display ["[let] " [str/write source] "\n\n"]]
           [list 'try [compile [cadr source]] [compile-do [cddr source]]]
    ]

    [defun compile-let [source]
           ;[display ["[let] " [str/write source] "\n\n"]]
           [list 'let [cadr source] [compile-do [cddr source]]]
    ]

    [defun compile-let* [source]
           ;[display ["[let*] " [str/write source] "\n\n"]]
           [list 'let* [compile-do [cdr source]]]
    ]

    [defun compile-macro [macro source]
           [compile [macro-apply macro [cdr source]]]
    ]

    [defun compile [source]
           "Compile the forms in source"
           ;[display ["[opt] " [str/write [resolve [car source]]] "\n"  [str/write source] "\n\n"]]
           [let* [def op [resolve [car source]]]
                 [cond [[eq? op do]           [compile-do   source]]
                       [[eq? op def]          [compile-def  source]]
                       [[eq? op set!]         [compile-set! source]]
                       [[eq? op let]          [compile-let  source]]
                       [[eq? op let*]         [compile-let* source]]
                       [[eq? op λ]            [compile-fun  source]]
                       [[eq? op try]          [compile-try  source]]
                       [[eq? [car source] 'λ] [compile-fun  source]]
                       [[macro? op]           [compile-macro op source]]
                       [#t source]]
           ]
    ]

    compile
]]

[defmacro \ [...body]
        "Define a λ with the self-hosting Nujel compiler"
        [compile [cons 'λ ...body]]
]

[defun eval [expr]
          "Compile, Evaluate and then return the result of EXPR"
          [eval* [compile expr]]
]

[def +1 [μ [v]
           `[+ 1 ,v]
]]

[def defun [μ [name args ...body]
	      `[def ,name ,[compile `[λ ,args ,@...body]]]
]]

[def defmacro [μ [name args ...body]
	      `[def ,name ,[compile `[μ ,args ,@...body]]]
]]


[defun test [a] [+2 a]]

[defmacro +2 [v] `[+ 2 ,v]]