diff --git a/src/pebblisp.c b/src/pebblisp.c index 1437ee8..7f92053 100644 --- a/src/pebblisp.c +++ b/src/pebblisp.c @@ -149,18 +149,16 @@ Object evalMapArgs(const Object* argForms, struct Environment* env) FOR_POINTER_IN_LIST(inputList) { // Create a new list for each element, // since lambda evaluation looks for a list - Object tempList = startList(cloneObject(*POINTER)); + Object tempInput = cloneObject(*POINTER); Object* params = &lambda.lambda->params; - struct Environment newEnv = envForLambda(params, &tempList, env); + struct Environment newEnv = envForLambda(params, &tempInput, env); // Add the lambda evaluation to the list Object lambda_output = eval(&lambda.lambda->body, &newEnv); - Object delisted = cloneObject(*lambda_output.list); - nf_addToList(&outputList, delisted); + nf_addToList(&outputList, lambda_output); deleteEnv(&newEnv); - cleanObject(&tempList); - cleanObject(&lambda_output); + cleanObject(&tempInput); } } cleanObject(&lambda); @@ -380,6 +378,7 @@ Object evalList(const Object* obj, struct Environment* env) Object eval(const Object* obj, struct Environment* env) { switch (obj->type) { + case TYPE_LAMBDA: case TYPE_FUNC: case TYPE_ERROR: case TYPE_OTHER: @@ -395,9 +394,6 @@ Object eval(const Object* obj, struct Environment* env) case TYPE_LIST: return evalList(obj, env); - - case TYPE_LAMBDA: - return eval(&obj->lambda->body, env); } return errorObject(BAD_TYPE); @@ -748,8 +744,6 @@ void handler(int nSignum, siginfo_t* si, void* vcontext) } else { printf("Happened before token processing.\n"); } - struct Environment* e = global(); - *e = defaultEnv(); ucontext_t* context = vcontext; context->uc_mcontext.gregs[REG_RIP]++; exit(139); diff --git a/src/plfunc.c b/src/plfunc.c index e9422f4..295e50b 100644 --- a/src/plfunc.c +++ b/src/plfunc.c @@ -3,22 +3,17 @@ #include "plfunc.h" -/** - * (reduce (list, initial) (fn (prev total) (+ prev total))) - */ Object reduce(Object* params, int length, struct Environment* env) { - const Object listInitial = params[0]; + Object list = params[0]; const Object func = params[1]; + Object total = params[2]; - Object* list = itemAt(&listInitial, 0); - Object total = cloneObject(*list->forward); // From given initial value - - if (list->type != TYPE_LIST) { - return simpleFuncEval(func, total, *list, env); + if (list.type != TYPE_LIST) { + return simpleFuncEval(func, total, list, env); } - FOR_POINTER_IN_LIST(list) { + FOR_POINTER_IN_LIST(&list) { total = simpleFuncEval(func, total, *POINTER, env); } @@ -42,17 +37,18 @@ Object filter(Object* params, int length, struct Environment* env) Object condition = params[0]; Object list = params[1]; - Object filteredList = listObject(); + Object filtered = listObject(); FOR_POINTER_IN_LIST(&list) { - Object conditional = cloneObject(condition); - nf_addToList(&conditional, *POINTER); - Object result = eval(&conditional, env); - cleanObject(&conditional); - if (result.number == 1) { - nf_addToList(&filteredList, *POINTER); + Object l = startList(cloneObject(condition)); + Object testee = cloneObject(*POINTER); + nf_addToList(&l, testee); + Object e = eval(&l, env); + if (e.number) { + nf_addToList(&filtered, testee); // May need to re-clone testee? } + cleanObject(&l); } - return filteredList; + return filtered; } Object append(Object* params, int length, struct Environment* env) @@ -175,7 +171,7 @@ Object parseEvalO(Object* params, int length, struct Environment* env) cleanObject(&string); return parsed; } else if (text.type == TYPE_SLIST) { - return evalList(&text, env, 0); + return evalList(&text, env); } else if (text.type != TYPE_STRING) { return errorObject(CAN_ONLY_EVAL_STRINGS); } @@ -332,18 +328,6 @@ Object len(Object* params, int length, struct Environment* env) return basicOp(&obj1, &obj2, _char, env); \ } - -#define PLUS + - -// Object add(Object* params, int length, struct Environment* env) -// { -// Object sum = numberObject(0); -// for (int i = 0; i < length; i++) { -// sum.number += params[i].number; -// } -// return sum; -// } - #define BASIC_MATH(_name, _op) \ Object _name(Object* params, int length, struct Environment* env) \ { \ @@ -381,6 +365,17 @@ BASIC_OP(or, '|') #ifdef STANDALONE +Object print(Object* params, int length, struct Environment* env) +{ + Object p = params[0]; + Object c = cloneObject(p); + Object e = eval(&c, env); + _printObj(&e, 0); + cleanObject(&c); + cleanObject(&e); + return numberObject(0); +} + Object pChar(Object* params, int length, struct Environment* env) { Object c = params[0]; diff --git a/src/plfunc.h b/src/plfunc.h index 4472466..71ad83c 100644 --- a/src/plfunc.h +++ b/src/plfunc.h @@ -35,7 +35,7 @@ fn(catObjects, fn(filter, "Filter a list based on the given condition.", - "(fil (< 50) (25 60 100))", "( 60 100 )", + "(fil (fn (a) (< 50 a)) (25 60 100))", "( 60 100 )", ); // (Object condition, Object list, struct Environment* env); fn(append, @@ -57,11 +57,12 @@ fn(len, fn(reduce, "Performs a simple reduction. Does not currently work with lambdas.\n" - "Takes two arguments:\n" - " - A two-element list: (`values` `initial`)\n" - " - A function to apply to each value.", - "(reduce (5 6) +)", "11", - "(reduce ((1 2 3) 0) +)", "6", + "Takes three arguments:\n" + " - Values\n" + " - A function to apply to each value\n" + " - An initial value", + "(reduce 5 + 6)", "11", + "(reduce (1 2 3) + 0)", "6", ); // (Object listInitial, Object func, struct Environment* env); fn(at, diff --git a/src/tests.sh b/src/tests.sh index 2e87563..9690394 100755 --- a/src/tests.sh +++ b/src/tests.sh @@ -29,8 +29,8 @@ title() { else FIRST_TITLE=false fi - echo -n "[$1] " - if [[ "$2" == "disable" ]]; then + echo -n "[$1] " + if [[ "$2" == "disabled" ]]; then echo -n "DISABLED" DISABLED=true fi @@ -92,9 +92,6 @@ check "Division" "(/ 6418425 65)" "98745" check "ChainAdd" "(+ 3917 17304 1293844 400 100000)" "1415465" check "ChainMul" "(* 8263 23 123)" "23376027" check "ChainDiv" "(/ 1493856 741 96 7)" "3" -check "ListAddi" "(+ 5 (1 2 3 (+ 10 10)))" "( 6 7 8 25 )" -check "ListModu" "(% 5 (1 2 3 (* 11 11)))" "( 1 2 3 1 )" -check "ListsMul" "(* (10 20 30) (1 20 300))" "( 10 400 9000 )" title "Comparison" check "GratrThn" "(> 23847123 19375933)" "T" @@ -159,6 +156,7 @@ check "MinLeft" "(min 17294722 17294721)" "17294721" title "Lambdas" check "MultStmt" "(def yee (fn (a) (* 10 a))) ; (yee 5)" "50" +check "MultStmtNoSemi" "(def yee (fn (a) (* 10 a)))(yee 5)" "50" check "DefinMap" "(def yee (fn (a) (* 10 a))) ; (map yee (5 10 2 (+ 12 0)))" "( 50 100 20 120 )" check "AnonymousLambda" "\ (map (fn (a) (* a a)) (5 6 7))" "( 25 36 49 )" @@ -182,14 +180,11 @@ check "Duplicate" "(def dupe (fn (a) (() (a a a))));(dupe (*10 10))" "( 100 100 title "Cat" check "ExplicitCat" '(cat "Big" " Kitty")' "Big Kitty" check "CatNums" '(cat "There are " (+ 2 3) " kitties")' "There are 5 kitties" -check "ImplicitCat" '(+ "There are " (* 5 4) " bonks")' "There are 20 bonks" -# Mixing of `+` and implicit cat currently expected but not recommended: -check "CatAssocLeft" '(+ 10 20 " rascals")' "30 rascals" title "Filtering" -check "Filtering" "(fil (< 321) (30 300 90 1200 135 801))" "( 1200 801 )" -check "FilterEval" "(fil (= 1000) ((+ 450 550) (* 20 50) (/ 30 3) (- 10000 100)))" "( 1000 1000 )" -check "MapFilter" "(fil (< 50) (map sq (1 2 3 4 5 6 7 8 9 10 11 12)))" "( 64 81 100 121 144 )" +check "Filtering" "(fil (fn (a) (< 321 a)) (30 300 90 1200 135 801))" "( 1200 801 )" +check "FilterEval" "(fil (fn (a) (= 1000 a)) ((+ 450 550) (* 20 50) (/ 30 3) (- 10000 100)))" "( 1000 1000 )" +check "MapFilter" "(fil (fn (a) (< 50 a)) (map sq (1 2 3 4 5 6 7 8 9 10 11 12)))" "( 64 81 100 121 144 )" title "Structs" check "StructDef" "(struct Post (title body))" "T" @@ -201,8 +196,8 @@ check "Accessing struct fields"\ "( TITLE BODY )" title "HigherOrder" -check "Simple reducing" '(reduce ((1 2 3) 0) +)' '6' -check "NonListReducing" '(reduce (1 0) +)' '1' +check "Simple reducing" '(reduce (1 2 3) + 0)' '6' +check "NonListReducing" '(reduce 1 + 0)' '1' check "FuncReturningAFunc" "(def plusser (fn (outer) (fn (inner) (+ outer inner))))\ (def plusFive (plusser 5))\ (plusFive 10)" "15" @@ -210,7 +205,6 @@ check "FuncReturningAFunc" "(def plusser (fn (outer) (fn (inner) (+ outer inner) title "ShouldError" check "LenOfNotList" "(len 5)" "NOT_A_LIST" check "NoMapList" "(map sq)" "( )" -check "UnevenLists" "(+ (1 2) (1 2 3))" "LISTS_NOT_SAME_SIZE" check "BadNumber" "(5df)" regex "BAD_NUMBER.*" check "BadHex" "(0x0zf)" regex "BAD_NUMBER.*" check "BadBinary" "(0b01120)" regex "BAD_NUMBER.*" @@ -221,12 +215,18 @@ check "BadParens4" ")))hey" regex "'MISMATCHED_PARENS.*" check "BadParens5" "hey))(" regex "'MISMATCHED_PARENS.*" check "BadParens6" '(ey")"' regex "'MISMATCHED_PARENS.*" +title "ListArithmetic" disabled +check "UnevenLists" "(+ (1 2) (1 2 3))" "LISTS_NOT_SAME_SIZE" +check "ListAddi" "(+ 5 (1 2 3 (+ 10 10)))" "( 6 7 8 25 )" +check "ListModu" "(% 5 (1 2 3 (* 11 11)))" "( 1 2 3 1 )" +check "ListsMul" "(* (10 20 30) (1 20 300))" "( 10 400 9000 )" + title "Eval" check "BasicNumberEval" '(eval "5")' "5" check "BasicOpEval" '(eval "(+ 5 10)")' "15" -check "MapFilter" '(eval "(fil (< 50) (map sq (1 2 3 4 5 6 7 8 9 10 11 12)))")' "( 64 81 100 121 144 )" +check "MapFilter" '(eval "(fil (fn (a) (< 50 a)) (map sq (1 2 3 4 5 6 7 8 9 10 11 12)))")' "( 64 81 100 121 144 )" -title "Forbble" disable +title "Forbble" disabled check "BasicForbbleOp" '(loadfile "examples/forbble.pbl") (feval (10 10 * .)) ""' "100" check "FibForbble" '(loadfile "examples/forbble.pbl") (feval (1 1 _f _f _f _f _f _f _f _f _f _f _f _f _f _f _f _f _f _f _f _f _f .)) ""' "28657" check "ForbbleDefine" '(loadfile "examples/forbble.pbl") (feval ( : "cubed" dup dup * * $ )) (feval (4 cubed .)) ""' "64" diff --git a/src/web.c b/src/web.c index 054bd74..627ecd2 100644 --- a/src/web.c +++ b/src/web.c @@ -141,18 +141,6 @@ int start(int port) return 0; } -Object print(Object* params, int length, struct Environment* env) -{ - Object p = params[0]; - Object ignore = params[1]; - Object c = cloneObject(p); - Object e = eval(&c, env); - _printObj(&e, 0); - cleanObject(&c); - cleanObject(&e); - return numberObject(0); -} - void addRouteO(Object path, Object textFunc, struct Environment* env, enum RouteType type) { char* p = malloc(sizeof(char) * strlen(path.string) + 1);