From 49bf4aa1a2499e861a756bf0ad5bba6063619a29 Mon Sep 17 00:00:00 2001 From: Sage Vaillancourt Date: Fri, 10 Dec 2021 16:33:59 -0500 Subject: [PATCH] Add system calls and some char processing. Color REPL error output. Add 'clear' shorthand to REPL. Add basic switch to lib. --- src/env.c | 3 +++ src/examples/lib.pbl | 21 ++++++++++----------- src/examples/repl.pbl | 14 ++++++++++++-- src/object.c | 8 +++++++- src/pebblisp.c | 28 ++++++++++++++++++++++++++-- src/pebblisp.h | 4 ++++ 6 files changed, 62 insertions(+), 16 deletions(-) diff --git a/src/env.c b/src/env.c index a6909fb..d8d126b 100644 --- a/src/env.c +++ b/src/env.c @@ -217,13 +217,16 @@ struct Environment defaultEnv() {"cat", &catObjects}, {"fil", &filter}, {"len", &len}, {"ap", &append}, {"pre", &prepend}, {"at", &at}, {"rest", &rest}, + {"chat", &charAt}, #ifndef LOW_MEM {"rev", &reverse}, #endif {"isnum", &isNum}, {"isstr", &isString}, {"iserr", &isErr}, + {"char", &charVal}, {"eval", &parseEvalO}, #ifdef STANDALONE {"prn", &print}, {"pch", &pChar}, {"penv", &printEnvO}, + {"sys", &systemCall}, {"loadfile", &loadFile}, {"inp", &takeInput}, #endif diff --git a/src/examples/lib.pbl b/src/examples/lib.pbl index e2940b1..2230342 100644 --- a/src/examples/lib.pbl +++ b/src/examples/lib.pbl @@ -25,14 +25,13 @@ ; Return the smaller of the two (def min (fn (a b) (if (< a b) a b))) -;(def switch (fn (pair_list) -; (if (= 0 (len pair_list)) -; "no match" -; ( -; (def _pair (at 0 pair_list)) -; (if (at 0 _pair) -; (at 1 _pair) -; (switch (rest pair_list)) -; ) -; )) -;)) +; Switch expression +; Doesn't yet work with lambdas +(def switch (fn (val pair_list) + (if (= 0 (len pair_list)) "no match" ( + (def current (at 0 pair_list)) + (if (= val (at 0 current)) (at 1 current) ( + (switch val (rest pair_list)) + )) + )) +)) diff --git a/src/examples/repl.pbl b/src/examples/repl.pbl index 0ab0312..5b61ef4 100755 --- a/src/examples/repl.pbl +++ b/src/examples/repl.pbl @@ -3,8 +3,18 @@ (prn "pebblisp::> ") (def input (inp)) (if (= input "q") () ( - (prnl (eval input)) - (repl))) + ;(switch input ( + ; ("clear" (fn () (sys "clear"))) + ;)) + + (if (= input "") () ( + (if (= input "clear") (sys "clear") ( + (def ret (eval input)) + (if (iserr ret) (prn "X => ") (prn "Ok => ")) + (prnl ret) + (prn ""))))) + (repl) + )) ))) (repl) diff --git a/src/object.c b/src/object.c index 45aa9d3..1828454 100644 --- a/src/object.c +++ b/src/object.c @@ -771,14 +771,20 @@ inline enum errorCode getErrorCode(const Object obj) #ifndef SIMPLE_ERRORS inline void errorAddContext(Object *o, const char* context) { + printf("o: %p\n", o); + printf("o->error: %s\n", o->error); + printf("o->error->context: %s\n", o->error->context); o->error->context = calloc(sizeof(char), RESULT_LENGTH); + printf("context: %p\n", context); strncpy(o->error->context, context, RESULT_LENGTH); } inline Object errorWithContext(enum errorCode err, const char* context) { Object o = errorObject(err); - errorAddContext(&o, context); + if (context) { + errorAddContext(&o, context); + } return o; } #endif diff --git a/src/pebblisp.c b/src/pebblisp.c index 14fb3cf..e17de84 100644 --- a/src/pebblisp.c +++ b/src/pebblisp.c @@ -215,8 +215,8 @@ Object listEvalFunc( Object listEvalLambda( Object *lambda, const Object *remaining, - struct Environment *env) -{ + struct Environment *env +) { struct Environment newEnv = envForLambda( &lambda->lambda->params, remaining, @@ -524,12 +524,29 @@ Object isString(Object test, Object ignore, struct Environment *ignore2) boolObject(1) : boolObject(0); } +// Get the int value of a string's first character +Object charVal(Object test, Object ignore, struct Environment *ignore2) +{ + return numberObject(test.string[0]); +// return test.type == TYPE_STRING && test.string[0] == '\0' ? +// boolObject(1) : boolObject(0); +} + Object isErr(Object test, Object ignore, struct Environment *ignore2) { return test.type == TYPE_ERROR ? boolObject(1) : boolObject(0); } +Object charAt(Object string, Object at, struct Environment *ignore) +{ + char* c = malloc(sizeof(char) * 2); + c[0] = string.string[at.number]; + c[1] = '\0'; + string.string = c; + return string; +} + #ifdef STANDALONE Object print(Object p, Object ignore, struct Environment *env) { @@ -828,6 +845,13 @@ Object loadFile(Object filename, Object _, struct Environment *env) { return numberObject(1); } +Object systemCall(Object process, Object _, struct Environment *env) { + if (isStringy(process)) { + return numberObject(system(process.string)); + } + return numberObject(255); +} + void repl(struct Environment *env) { if (readFile(SCRIPTDIR "/repl.pbl", env) == 1) { fprintf(stderr, "Could not read '%s'\n", SCRIPTDIR "/repl.pbl"); diff --git a/src/pebblisp.h b/src/pebblisp.h index 072fcec..f357c31 100644 --- a/src/pebblisp.h +++ b/src/pebblisp.h @@ -59,6 +59,9 @@ Object isNum(Object test, Object ignore, struct Environment *ignore2); Object isString(Object test, Object ignore, struct Environment *ignore2); Object isErr(Object test, Object ignore, struct Environment *ignore2); +Object charAt(Object string, Object at, struct Environment *ignore); +Object charVal(Object test, Object ignore, struct Environment *ignore2); + Object print(Object p, Object ignore, struct Environment *ignore2); Object pChar(Object c, Object i1, struct Environment *i2); Object printEnvO(Object i1, Object i2, struct Environment *env); @@ -66,6 +69,7 @@ Object parseEvalO(Object text, Object ignore, struct Environment *env); #ifdef STANDALONE Object takeInput(Object i1, Object i2, struct Environment *i3); +Object systemCall(Object call, Object _, struct Environment *i3); Object loadFile(Object filename, Object _, struct Environment *env); #endif