diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6d7ce0a..69df6fc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,7 +43,7 @@ jobs: run: | mkdir -p ${{ github.workspace }}/release cp -v ${{ github.workspace }}/build/src/lisp ${{ github.workspace }}/release/ - cp -v -r ${{ github.workspace }}/stdlib ${{ github.workspace }}/release/ + cp -v -r ${{ github.workspace }}/src/stdlib ${{ github.workspace }}/release/ tar -czvf lisp-linux-amd64.tar.gz -C ${{ github.workspace }}/release lisp stdlib pwd ls -la diff --git a/doc/getting-started.md b/doc/getting-started.md index 682570b..d4f3fca 100644 --- a/doc/getting-started.md +++ b/doc/getting-started.md @@ -190,8 +190,8 @@ passing them to the macro. Arguments can be unquoted with `,` and `,@`. | `and` , `or`, `not` | Boolean operators | | | `print` , `println` | Print to command line | | | `cons` | Create cons cell | `(cons 1 (cons 2 (cons 3 nil)))` | -| `car` | Access _car_ of _cons_ cell | `(car (cons 1 2))` | -| `cdr` | Access _cdr_ of _cons_ cell | `(cdr (cons 1 2))` | +| `car` | Access _car_ of _cons_ cell | `(car (cons 1 2))` returns `1` | +| `cdr` | Access _cdr_ of _cons_ cell | `(cdr (cons 1 2))` returns `2` | | `append` | Concatinate lists | `(append (list 1 2 3) (list 4 5 6))` | | `map` | Return list of elements with function applied | `(map (lambda (x) (* x x)) (list 1 2 3))` | | `filter` `(filter pred lst)` | Return list of elements for wich pred is true | `(filter (lambda (x) (> x 1)) (list 1 2 3))` | @@ -206,4 +206,5 @@ passing them to the macro. Arguments can be unquoted with `,` and `,@`. | `strcmp` | Compare string | | | `strlen` | Get length of string | | | `strip` | Remove leading or trailing whitespace | | +| `split` | Split string on delimiteer | `(split " " "hello world")` | | `getenv` | Get environment variable | `(getenv "HOME")` | diff --git a/src/builtin.cpp b/src/builtin.cpp index 0ba2c29..bf8aad3 100644 --- a/src/builtin.cpp +++ b/src/builtin.cpp @@ -823,6 +823,13 @@ Expr * f_symbol_name( Expr * arg, Context & context, const IO & io ) /////////////////////////////////////////////////////////////////////////////// +Expr * f_dump( Expr * arg, Context & context, const IO & io ) +{ + return make_nil(); +} + +/////////////////////////////////////////////////////////////////////////////// + void load( Context & ctx ) { ctx.defvar( "+", make_native( builtin::f_add ) ); @@ -877,6 +884,7 @@ void load( Context & ctx ) ctx.defvar( "filter", make_native( builtin::f_filter ) ); ctx.defvar( "apply", make_native( builtin::f_apply ) ); ctx.defvar( "load", make_native( builtin::f_load ) ); + ctx.defvar( "dump", make_native( builtin::f_dump ) ); } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/eval.cpp b/src/eval.cpp index 1d70835..a41cd86 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -133,19 +133,7 @@ bool Context::is_root() const /////////////////////////////////////////////////////////////////////////////// -std::string init_script() -{ - const char * home = getenv( "HOME" ); - assert( home != nullptr ); - - std::string profile = ".profile.lsp"; - - return "(load \"" + std::string( home ) + "/" + profile + "\")"; -} - -/////////////////////////////////////////////////////////////////////////////// - -void eval_profile( Context & context, const IO & io ) +void load_shell_macros( Context & context, const IO & io ) { const std::string shell_macros = R"( ; test if a symbol is defined @@ -165,6 +153,13 @@ void eval_profile( Context & context, const IO & io ) )"; ( void ) eval( shell_macros, context, io ); +} + +/////////////////////////////////////////////////////////////////////////////// + +void eval_profile( Context & context, const IO & io ) +{ + load_shell_macros( context, io ); const char * home = getenv( "HOME" ); assert( home != nullptr ); @@ -730,8 +725,6 @@ int repl() eval_profile( ctx, io ); - std::cout << std::endl; - do { std::string line; diff --git a/src/eval.h b/src/eval.h index ad4eb2f..1a539f3 100644 --- a/src/eval.h +++ b/src/eval.h @@ -68,6 +68,8 @@ int eval( const std::string & source, Flags flags = FLAG_NEWLINE | FLAG_INTERACT Expr * eval_program( Expr * program, Context & context, const IO & io ); +void load_shell_macros( Context & context, const IO & io ); + int repl(); /////////////////////////////////////////////////////////////////////////////// diff --git a/stdlib/profile.lsp b/src/stdlib/profile.lsp similarity index 85% rename from stdlib/profile.lsp rename to src/stdlib/profile.lsp index 29caf1a..adef408 100644 --- a/stdlib/profile.lsp +++ b/src/stdlib/profile.lsp @@ -4,5 +4,3 @@ (progn (load (strcat lib "util.lsp")) (load (strcat lib "shell.lsp")))) - -(println "Loaded profile.") \ No newline at end of file diff --git a/stdlib/shell.lsp b/src/stdlib/shell.lsp similarity index 100% rename from stdlib/shell.lsp rename to src/stdlib/shell.lsp diff --git a/stdlib/util.lsp b/src/stdlib/util.lsp similarity index 100% rename from stdlib/util.lsp rename to src/stdlib/util.lsp diff --git a/tests/test_lisp.cpp b/tests/test_lisp.cpp index c79d36b..6aac9c7 100644 --- a/tests/test_lisp.cpp +++ b/tests/test_lisp.cpp @@ -1011,3 +1011,21 @@ TEST_F( LispTest, test_apply_1 ) EXPECT_EQ( err.str(), "" ); EXPECT_EQ( out.str(), "6" ); } + +TEST_F( LispTest, test_split_01 ) +{ + std::string src = "(length (split \" \" \"this text if full of spaces\"))"; + int r = eval( src, ctx, io ); + EXPECT_EQ( r, 0 ); + EXPECT_EQ( err.str(), "" ); + EXPECT_EQ( out.str(), "6" ); +} + +TEST_F( LispTest, test_strip_01 ) +{ + std::string src = "(print (strip \" remove leading and trailing whitespace\n \"))"; + int r = eval( src, ctx, io ); + EXPECT_EQ( r, 0 ); + EXPECT_EQ( err.str(), "" ); + EXPECT_EQ( out.str(), "remove leading and trailing whitespace" ); +} \ No newline at end of file diff --git a/tests/test_shell.cpp b/tests/test_shell.cpp index cc91226..147b77f 100644 --- a/tests/test_shell.cpp +++ b/tests/test_shell.cpp @@ -4,30 +4,35 @@ using namespace lisp; +class ShellTest : public LispTest +{ +public: + void SetUp() override + { + load_shell_macros( ctx, io ); + } +}; + #ifdef __linux__ -TEST_F( LispTest, test_shell_01 ) +TEST_F( ShellTest, test_shell_01 ) { std::string src = R"( -(load "stdlib/shell.lsp") - (defvar result ($ (pipe - (sh find "src") - (sh grep "lisp.h")))) + (sh ls "/") + (sh grep "var")))) (print result) )"; int r = eval( src, ctx, io ); EXPECT_EQ( err.str(), "" ); - EXPECT_EQ( out.str(), "src/lisp.h" ); + EXPECT_EQ( out.str(), "var" ); } -TEST_F( LispTest, test_shell_02 ) +TEST_F( ShellTest, test_shell_02 ) { std::string src = R"( -(load "stdlib/shell.lsp") - (defvar reversed ($ (pipe @@ -41,11 +46,9 @@ TEST_F( LispTest, test_shell_02 ) EXPECT_EQ( out.str(), "dlrow olleh" ); } -TEST_F( LispTest, test_shell_03 ) +TEST_F( ShellTest, test_shell_03 ) { std::string src = R"( -(load "stdlib/shell.lsp") - (print ($ (sh uname -o))) )"; int r = eval( src, ctx, io ); diff --git a/tests/util.h b/tests/util.h index 66c7f5b..731bed4 100644 --- a/tests/util.h +++ b/tests/util.h @@ -16,14 +16,6 @@ class LispTest : public ::testing::Test { } - void SetUp() override - { - } - - void TearDown() override - { - } - protected: Context ctx; std::ostringstream out, err; diff --git a/tools/create-release.lsp b/tools/create-release.lsp index a79407e..edb2e25 100755 --- a/tools/create-release.lsp +++ b/tools/create-release.lsp @@ -24,7 +24,7 @@ (let ((tmp-dir (strip ($ (sh mktemp -d))))) (and (sh cp -v (strcat build-dir "/" "src/lisp") tmp-dir) - (sh cp -vr "stdlib" tmp-dir) + (sh cp -vr "src/stdlib" tmp-dir) (sh tar -czvf archive-name -C tmp-dir "lisp" "stdlib") (sh rm -rfv tmp-dir))))