Login
7 branches 0 tags
Ben (X13/Arch) Added AoC challenges as automatic tests bc99b74 4 years ago 231 Commits
nujel / stdlib / flow.nuj
; Mostly macros implementing different control flow constructs

[defmacro if-not [pred then else]
          `[if ~pred ~else ~then]
]

[defmacro if-let [binding then else]
          `[let* [def ~[car binding] ~[cadr binding]]
                 [if ~[car binding] ~then ~else]
           ]
]

[defmacro when-let [binding ...body]
          `[if-let ~binding ~[cons 'do ...body] #nil]
]

[defmacro when-not [pred ...body]
          "Evalutes to BODY if PRED is false"
          `[if ~pred #nil [do ~@...body]]
]

[defmacro when [pred ...body]
          "Evalutes to BODY if PRED is true"
          `[if ~pred [do ~@...body] #nil]
]

[defun let/arg [arg]
       [when-not [pair? arg] [throw `[:invalid-let-form "Please fix the structure of the let form" ~arg]]]
       [when-not [symbol? [car arg]] [throw `[:invalid-let-form "Please fix the structure of the let form" ~arg]]]
       `[def ~[car arg] ~[cadr arg]]
]
[defun let/args [args]
       [if args
           [cons [let/arg [car args]]
                 [let/args [cdr args]]]
           #nil]
]
[defmacro let [bindings ...body]
          "Evalutes to BODY if PRED is true"
          `[let* [do ~@[let/args bindings] ~@...body]]
]

[defun case/clauses/multiple [key-sym cases]
       [when cases
             [cons [list '== key-sym [car cases]]
                   [case/clauses/multiple key-sym [cdr cases]]]]
]

[defun case/clauses [key-sym clauses]
       [when clauses
             [if [== [caar clauses] 'otherwise]
                 [cons 'do [cdar clauses]]
                 [list 'if
                       [if [pair? [caar clauses]]
                           [cons 'or [case/clauses/multiple key-sym [caar clauses]]]
                           [list '== key-sym [caar clauses]]]
                       [cons 'do [cdar clauses]]
                       [case/clauses key-sym [cdr clauses]]]]]
]

[defmacro case [key-form ...clauses]
          [def key-sym [gensym]]
          [list 'let*
                [list 'def key-sym key-form]
                [case/clauses key-sym ...clauses]]
]

[defmacro cond [...body]
          "Contains multiple cond clauses"
          [when ...body
                [list 'if
                      [caar ...body]
                      [cons 'do [cdar ...body]]
                      [macro-apply cond [cdr ...body]]]]
]