Continue FUNC transition.
Removing some list-func features, at least for now. e.g. (+ 5 (1 2 3)). Disable related tests. Improve (reduce) syntax.
This commit is contained in:
parent
0a649095ab
commit
68a7a55fc0
|
@ -149,18 +149,16 @@ Object evalMapArgs(const Object* argForms, struct Environment* env)
|
||||||
FOR_POINTER_IN_LIST(inputList) {
|
FOR_POINTER_IN_LIST(inputList) {
|
||||||
// Create a new list for each element,
|
// Create a new list for each element,
|
||||||
// since lambda evaluation looks for a list
|
// since lambda evaluation looks for a list
|
||||||
Object tempList = startList(cloneObject(*POINTER));
|
Object tempInput = cloneObject(*POINTER);
|
||||||
|
|
||||||
Object* params = &lambda.lambda->params;
|
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
|
// Add the lambda evaluation to the list
|
||||||
Object lambda_output = eval(&lambda.lambda->body, &newEnv);
|
Object lambda_output = eval(&lambda.lambda->body, &newEnv);
|
||||||
Object delisted = cloneObject(*lambda_output.list);
|
nf_addToList(&outputList, lambda_output);
|
||||||
nf_addToList(&outputList, delisted);
|
|
||||||
deleteEnv(&newEnv);
|
deleteEnv(&newEnv);
|
||||||
cleanObject(&tempList);
|
cleanObject(&tempInput);
|
||||||
cleanObject(&lambda_output);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cleanObject(&lambda);
|
cleanObject(&lambda);
|
||||||
|
@ -380,6 +378,7 @@ Object evalList(const Object* obj, struct Environment* env)
|
||||||
Object eval(const Object* obj, struct Environment* env)
|
Object eval(const Object* obj, struct Environment* env)
|
||||||
{
|
{
|
||||||
switch (obj->type) {
|
switch (obj->type) {
|
||||||
|
case TYPE_LAMBDA:
|
||||||
case TYPE_FUNC:
|
case TYPE_FUNC:
|
||||||
case TYPE_ERROR:
|
case TYPE_ERROR:
|
||||||
case TYPE_OTHER:
|
case TYPE_OTHER:
|
||||||
|
@ -395,9 +394,6 @@ Object eval(const Object* obj, struct Environment* env)
|
||||||
|
|
||||||
case TYPE_LIST:
|
case TYPE_LIST:
|
||||||
return evalList(obj, env);
|
return evalList(obj, env);
|
||||||
|
|
||||||
case TYPE_LAMBDA:
|
|
||||||
return eval(&obj->lambda->body, env);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return errorObject(BAD_TYPE);
|
return errorObject(BAD_TYPE);
|
||||||
|
@ -748,8 +744,6 @@ void handler(int nSignum, siginfo_t* si, void* vcontext)
|
||||||
} else {
|
} else {
|
||||||
printf("Happened before token processing.\n");
|
printf("Happened before token processing.\n");
|
||||||
}
|
}
|
||||||
struct Environment* e = global();
|
|
||||||
*e = defaultEnv();
|
|
||||||
ucontext_t* context = vcontext;
|
ucontext_t* context = vcontext;
|
||||||
context->uc_mcontext.gregs[REG_RIP]++;
|
context->uc_mcontext.gregs[REG_RIP]++;
|
||||||
exit(139);
|
exit(139);
|
||||||
|
|
57
src/plfunc.c
57
src/plfunc.c
|
@ -3,22 +3,17 @@
|
||||||
|
|
||||||
#include "plfunc.h"
|
#include "plfunc.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* (reduce (list, initial) (fn (prev total) (+ prev total)))
|
|
||||||
*/
|
|
||||||
Object reduce(Object* params, int length, struct Environment* env)
|
Object reduce(Object* params, int length, struct Environment* env)
|
||||||
{
|
{
|
||||||
const Object listInitial = params[0];
|
Object list = params[0];
|
||||||
const Object func = params[1];
|
const Object func = params[1];
|
||||||
|
Object total = params[2];
|
||||||
|
|
||||||
Object* list = itemAt(&listInitial, 0);
|
if (list.type != TYPE_LIST) {
|
||||||
Object total = cloneObject(*list->forward); // From given initial value
|
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);
|
total = simpleFuncEval(func, total, *POINTER, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,17 +37,18 @@ Object filter(Object* params, int length, struct Environment* env)
|
||||||
Object condition = params[0];
|
Object condition = params[0];
|
||||||
Object list = params[1];
|
Object list = params[1];
|
||||||
|
|
||||||
Object filteredList = listObject();
|
Object filtered = listObject();
|
||||||
FOR_POINTER_IN_LIST(&list) {
|
FOR_POINTER_IN_LIST(&list) {
|
||||||
Object conditional = cloneObject(condition);
|
Object l = startList(cloneObject(condition));
|
||||||
nf_addToList(&conditional, *POINTER);
|
Object testee = cloneObject(*POINTER);
|
||||||
Object result = eval(&conditional, env);
|
nf_addToList(&l, testee);
|
||||||
cleanObject(&conditional);
|
Object e = eval(&l, env);
|
||||||
if (result.number == 1) {
|
if (e.number) {
|
||||||
nf_addToList(&filteredList, *POINTER);
|
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)
|
Object append(Object* params, int length, struct Environment* env)
|
||||||
|
@ -175,7 +171,7 @@ Object parseEvalO(Object* params, int length, struct Environment* env)
|
||||||
cleanObject(&string);
|
cleanObject(&string);
|
||||||
return parsed;
|
return parsed;
|
||||||
} else if (text.type == TYPE_SLIST) {
|
} else if (text.type == TYPE_SLIST) {
|
||||||
return evalList(&text, env, 0);
|
return evalList(&text, env);
|
||||||
} else if (text.type != TYPE_STRING) {
|
} else if (text.type != TYPE_STRING) {
|
||||||
return errorObject(CAN_ONLY_EVAL_STRINGS);
|
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); \
|
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) \
|
#define BASIC_MATH(_name, _op) \
|
||||||
Object _name(Object* params, int length, struct Environment* env) \
|
Object _name(Object* params, int length, struct Environment* env) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -381,6 +365,17 @@ BASIC_OP(or, '|')
|
||||||
|
|
||||||
#ifdef STANDALONE
|
#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 pChar(Object* params, int length, struct Environment* env)
|
||||||
{
|
{
|
||||||
Object c = params[0];
|
Object c = params[0];
|
||||||
|
|
13
src/plfunc.h
13
src/plfunc.h
|
@ -35,7 +35,7 @@ fn(catObjects,
|
||||||
|
|
||||||
fn(filter,
|
fn(filter,
|
||||||
"Filter a list based on the given condition.",
|
"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);
|
); // (Object condition, Object list, struct Environment* env);
|
||||||
|
|
||||||
fn(append,
|
fn(append,
|
||||||
|
@ -57,11 +57,12 @@ fn(len,
|
||||||
|
|
||||||
fn(reduce,
|
fn(reduce,
|
||||||
"Performs a simple reduction. Does not currently work with lambdas.\n"
|
"Performs a simple reduction. Does not currently work with lambdas.\n"
|
||||||
"Takes two arguments:\n"
|
"Takes three arguments:\n"
|
||||||
" - A two-element list: (`values` `initial`)\n"
|
" - Values\n"
|
||||||
" - A function to apply to each value.",
|
" - A function to apply to each value\n"
|
||||||
"(reduce (5 6) +)", "11",
|
" - An initial value",
|
||||||
"(reduce ((1 2 3) 0) +)", "6",
|
"(reduce 5 + 6)", "11",
|
||||||
|
"(reduce (1 2 3) + 0)", "6",
|
||||||
); // (Object listInitial, Object func, struct Environment* env);
|
); // (Object listInitial, Object func, struct Environment* env);
|
||||||
|
|
||||||
fn(at,
|
fn(at,
|
||||||
|
|
32
src/tests.sh
32
src/tests.sh
|
@ -29,8 +29,8 @@ title() {
|
||||||
else
|
else
|
||||||
FIRST_TITLE=false
|
FIRST_TITLE=false
|
||||||
fi
|
fi
|
||||||
echo -n "[[0m$1] "
|
echo -n "[0m[$1] "
|
||||||
if [[ "$2" == "disable" ]]; then
|
if [[ "$2" == "disabled" ]]; then
|
||||||
echo -n "[33mDISABLED[0m"
|
echo -n "[33mDISABLED[0m"
|
||||||
DISABLED=true
|
DISABLED=true
|
||||||
fi
|
fi
|
||||||
|
@ -92,9 +92,6 @@ check "Division" "(/ 6418425 65)" "98745"
|
||||||
check "ChainAdd" "(+ 3917 17304 1293844 400 100000)" "1415465"
|
check "ChainAdd" "(+ 3917 17304 1293844 400 100000)" "1415465"
|
||||||
check "ChainMul" "(* 8263 23 123)" "23376027"
|
check "ChainMul" "(* 8263 23 123)" "23376027"
|
||||||
check "ChainDiv" "(/ 1493856 741 96 7)" "3"
|
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"
|
title "Comparison"
|
||||||
check "GratrThn" "(> 23847123 19375933)" "T"
|
check "GratrThn" "(> 23847123 19375933)" "T"
|
||||||
|
@ -159,6 +156,7 @@ check "MinLeft" "(min 17294722 17294721)" "17294721"
|
||||||
|
|
||||||
title "Lambdas"
|
title "Lambdas"
|
||||||
check "MultStmt" "(def yee (fn (a) (* 10 a))) ; (yee 5)" "50"
|
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 "DefinMap" "(def yee (fn (a) (* 10 a))) ; (map yee (5 10 2 (+ 12 0)))" "( 50 100 20 120 )"
|
||||||
check "AnonymousLambda" "\
|
check "AnonymousLambda" "\
|
||||||
(map (fn (a) (* a a)) (5 6 7))" "( 25 36 49 )"
|
(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"
|
title "Cat"
|
||||||
check "ExplicitCat" '(cat "Big" " Kitty")' "Big Kitty"
|
check "ExplicitCat" '(cat "Big" " Kitty")' "Big Kitty"
|
||||||
check "CatNums" '(cat "There are " (+ 2 3) " kitties")' "There are 5 kitties"
|
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"
|
title "Filtering"
|
||||||
check "Filtering" "(fil (< 321) (30 300 90 1200 135 801))" "( 1200 801 )"
|
check "Filtering" "(fil (fn (a) (< 321 a)) (30 300 90 1200 135 801))" "( 1200 801 )"
|
||||||
check "FilterEval" "(fil (= 1000) ((+ 450 550) (* 20 50) (/ 30 3) (- 10000 100)))" "( 1000 1000 )"
|
check "FilterEval" "(fil (fn (a) (= 1000 a)) ((+ 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 "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"
|
title "Structs"
|
||||||
check "StructDef" "(struct Post (title body))" "T"
|
check "StructDef" "(struct Post (title body))" "T"
|
||||||
|
@ -201,8 +196,8 @@ check "Accessing struct fields"\
|
||||||
"( TITLE BODY )"
|
"( TITLE BODY )"
|
||||||
|
|
||||||
title "HigherOrder"
|
title "HigherOrder"
|
||||||
check "Simple reducing" '(reduce ((1 2 3) 0) +)' '6'
|
check "Simple reducing" '(reduce (1 2 3) + 0)' '6'
|
||||||
check "NonListReducing" '(reduce (1 0) +)' '1'
|
check "NonListReducing" '(reduce 1 + 0)' '1'
|
||||||
check "FuncReturningAFunc" "(def plusser (fn (outer) (fn (inner) (+ outer inner))))\
|
check "FuncReturningAFunc" "(def plusser (fn (outer) (fn (inner) (+ outer inner))))\
|
||||||
(def plusFive (plusser 5))\
|
(def plusFive (plusser 5))\
|
||||||
(plusFive 10)" "15"
|
(plusFive 10)" "15"
|
||||||
|
@ -210,7 +205,6 @@ check "FuncReturningAFunc" "(def plusser (fn (outer) (fn (inner) (+ outer inner)
|
||||||
title "ShouldError"
|
title "ShouldError"
|
||||||
check "LenOfNotList" "(len 5)" "NOT_A_LIST"
|
check "LenOfNotList" "(len 5)" "NOT_A_LIST"
|
||||||
check "NoMapList" "(map sq)" "( )"
|
check "NoMapList" "(map sq)" "( )"
|
||||||
check "UnevenLists" "(+ (1 2) (1 2 3))" "LISTS_NOT_SAME_SIZE"
|
|
||||||
check "BadNumber" "(5df)" regex "BAD_NUMBER.*"
|
check "BadNumber" "(5df)" regex "BAD_NUMBER.*"
|
||||||
check "BadHex" "(0x0zf)" regex "BAD_NUMBER.*"
|
check "BadHex" "(0x0zf)" regex "BAD_NUMBER.*"
|
||||||
check "BadBinary" "(0b01120)" 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 "BadParens5" "hey))(" regex "'MISMATCHED_PARENS.*"
|
||||||
check "BadParens6" '(ey")"' 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"
|
title "Eval"
|
||||||
check "BasicNumberEval" '(eval "5")' "5"
|
check "BasicNumberEval" '(eval "5")' "5"
|
||||||
check "BasicOpEval" '(eval "(+ 5 10)")' "15"
|
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 "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 "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"
|
check "ForbbleDefine" '(loadfile "examples/forbble.pbl") (feval ( : "cubed" dup dup * * $ )) (feval (4 cubed .)) ""' "64"
|
||||||
|
|
12
src/web.c
12
src/web.c
|
@ -141,18 +141,6 @@ int start(int port)
|
||||||
return 0;
|
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)
|
void addRouteO(Object path, Object textFunc, struct Environment* env, enum RouteType type)
|
||||||
{
|
{
|
||||||
char* p = malloc(sizeof(char) * strlen(path.string) + 1);
|
char* p = malloc(sizeof(char) * strlen(path.string) + 1);
|
||||||
|
|
Loading…
Reference in New Issue