From 44beab651c5f1e028aed6e9c3a8462150d79ca38 Mon Sep 17 00:00:00 2001 From: Aidan Date: Sat, 18 Jul 2020 10:44:18 -0700 Subject: [PATCH] added progn form --- Readme.md | 5 +++-- stdlib/control_flow.go | 11 +++++++++++ stdlib/stdlib.go | 7 +++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index f8abce7..63d0b30 100644 --- a/Readme.md +++ b/Readme.md @@ -43,10 +43,11 @@ Use the `func` function from the stdlib: In this case, `(form_to_be_evaluated)` will not be evaluated until the function is called. ### Control flow -See `stdlib/control_flow.go`. We have if and while forms: +See `stdlib/control_flow.go`. We have if, while, and progn forms: `(if (cond) (then) (else))` `(when (cond) (form1)....... (formN))` - +`(progn (form1)..... (formN))` +If and While should be self explanatory. For those new to LISP, the rough idea of progn is to evaluate a sequence of N forms and return the result of the final one. We also have functioning implementations of map and reduce in the stdlib (incomplete) ## Comments diff --git a/stdlib/control_flow.go b/stdlib/control_flow.go index 5889e33..279f94f 100644 --- a/stdlib/control_flow.go +++ b/stdlib/control_flow.go @@ -22,6 +22,17 @@ import ( "gitlab.com/whom/shs/log" ) +/* eval N forms. return the last one + */ +func shs_progn(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token { + var res *ast.Token + for iter := in; iter != nil; iter = iter.Next { + res = iter.Eval(ft, vt, false) + } + + return res +} + /* return one evaluated form or another based on the boolean statement */ func shs_if(in *ast.Token, vt ast.VarTable, ft ast.FuncTable) *ast.Token { diff --git a/stdlib/stdlib.go b/stdlib/stdlib.go index c50b42c..a243700 100644 --- a/stdlib/stdlib.go +++ b/stdlib/stdlib.go @@ -42,6 +42,13 @@ func GenFuncTable() ast.FuncTable { Args: -1, }, + "progn": &ast.Function{ + Function: shs_progn, + Name: "shs_progn", + TimesCalled: 0, + Args: -1, + }, + "eval": &ast.Function{ Function: eval, Name: "eval",