Breaking: Stop `def` adding vars to higher scopes

Fixed OOP error in allocating lambda environments. Add ability to disable test
groups. Disabled forbble tests and `switch` implementation (broken by `def`
change)
This commit is contained in:
Sage Vaillancourt 2021-07-12 20:34:54 -04:00
parent ce28c84696
commit 811e9e3dd2
4 changed files with 58 additions and 39 deletions

View File

@ -18,7 +18,6 @@ Object fetchFromEnvironment(const char *name, struct Environment *env)
if(env->size == 0)
return errorObject(EMPTY_ENV);
printd("Fetching '%s' from env\n", name);
for(int i = 0; i < env->size; i++) {
if(env->strings[i] == NULL) {
printd("Try %d (NULL)\n", i);
@ -38,7 +37,6 @@ Object fetchFromEnvironment(const char *name, struct Environment *env)
return fetchFromEnvironment(name, env->outer);
}
printf("'%s'\n", name);
return errorObject(DID_NOT_FIND_SYMBOL);
}
@ -58,7 +56,7 @@ struct Environment envForLambda(const Object *params, const Object *arg_forms,
return env;
env.strings = calloc(sizeof(char*), paramCount + 1);
env.objects = malloc(sizeof(Object) * paramCount + 1);
env.objects = malloc(sizeof(Object) * (paramCount + 1));
const Object *march = arg_forms;
for(int i = 0; i < paramCount; i++) {
@ -110,16 +108,19 @@ void addToEnv(struct Environment *env, const char *name, const Object obj)
int i;
struct Environment *temp_env = env;
int is_local = 1;
while(temp_env) {
for(i = 0; i < temp_env->size; i++) {
// Add *new* item to env only if we're in the local scope
if(temp_env->strings[i] == NULL) {
//printf("Add new object\n");
if (is_local) {
temp_env->strings[i] = calloc(sizeof(char), strlen(name) + 1);
strncpy(temp_env->strings[i], name, strlen(name));
temp_env->objects[i] = cloneObject(obj);
return;
}
if(strcmp(temp_env->strings[i], name) == 0) {
break;
} else if(strcmp(temp_env->strings[i], name) == 0) {
Object o = cloneObject(obj);
cleanObject(&temp_env->objects[i]);
temp_env->objects[i] = o;
@ -127,21 +128,23 @@ void addToEnv(struct Environment *env, const char *name, const Object obj)
}
}
temp_env = temp_env->outer;
is_local = 0;
}
printd("Reallocating environment\n");
const int inc = 5;
const int old_size = env->size;
env->size += inc;
env->strings = realloc(env->strings, sizeof(char*) * env->size);
env->objects = realloc(env->objects, sizeof(Object) * env->size);
for(int j = 0; j < inc; j++) {
env->strings[i + j] = NULL;
env->strings[old_size + j] = NULL;
}
env->strings[i] = malloc(strlen(name) + 1);
strncpy(env->strings[i], name, strlen(name) + 1);
env->objects[i] = cloneObject(obj);
env->strings[old_size] = malloc(strlen(name) + 1);
strncpy(env->strings[old_size], name, strlen(name) + 1);
env->objects[old_size] = cloneObject(obj);
}
void printEnv(struct Environment *env)
@ -151,10 +154,14 @@ void printEnv(struct Environment *env)
return;
}
for(int i = 0; i < env->size; i++) {
if(env->strings[i] == NULL)
return;
printf("env[%d]: '%s'\n ", i, env->strings[i]);
if(env->strings[i] == NULL) {
printf("env[%d]: NULL %p\n", i, env->strings[i]);
break;
}
printf("env[%d]: '%s' %p\n", i, env->strings[i], env->strings[i]);
printf(" ");
printObj(&env->objects[i]);
printf("");
}
}

View File

@ -25,14 +25,14 @@
; 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))
)
))
))
;(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))
; )
; ))
;))

View File

@ -20,8 +20,11 @@
* @param env The environment to add the new definition to
* @return The symbol(s) defined
*/
Object evalDefArgs(const Object *symbol, const Object *value, struct Environment *env)
{
Object evalDefArgs(
const Object *symbol,
const Object *value,
struct Environment *env
) {
const char *name = symbol->string;
// Handles multi-definitions

View File

@ -7,6 +7,7 @@ TOTAL_FAILS=0
FAILS=0
FAIL_OUTPUT=""
VALGRIND=false
DISABLED=false
CURRENT_BLOCK=""
@ -21,10 +22,15 @@ endBlock() {
FAIL_OUTPUT=""
fi
FAILS=0
DISABLED=false
}
title() {
echo -n "[$1] "
if [[ "$2" == "disable" ]]; then
echo -n "DISABLED"
DISABLED=true
fi
}
pass() {
@ -34,12 +40,15 @@ pass() {
fail() {
echo -n "X"
FAIL_OUTPUT="$FAIL_OUTPUT $1 test FAILED $2"
FAIL_OUTPUT="$FAIL_OUTPUT $1 FAILED\n When running \"$2\""
((FAILS++))
((TOTAL_FAILS++))
}
check() {
if $DISABLED; then
return 1
fi
if $VALGRIND; then
echo -ne "\n $1\r"
local output=$($VALCOM ./pl "(loadfile \"examples/lib.pbl\") $2")
@ -48,10 +57,10 @@ check() {
fi
if [ "$output" == "$3" ]; then
pass $1
pass "$1"
else
fail $1 "$2"
FAIL_OUTPUT="${FAIL_OUTPUT}\n Expected '$3' but received '$output'"
fail "$1" "$2"
FAIL_OUTPUT="${FAIL_OUTPUT}\n  expected '$3' but received '$output'\n"
fi
}
@ -190,16 +199,16 @@ 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 )"
endBlock
title "Forbble"
title "Forbble" disable
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"
endBlock
# title "Environment"
# check "EnvStressTestEarly" "(def a 1)(def b 20)(def c 'yee')(def d 'yeehunnid')(def e 3) (a)" "1"
# check "EnvStressTestLate" "(def a 1)(def b 2)(def c 3)(def d 4)(def e 5)(def f 6)(def n 40) (n)" "40"
# endBlock
title "Environment" disable
check "EnvStressTestEarly" "(def a 1)(def b 20)(def c 'yee')(def d 'yeehunnid')(def e 3) (a)" "( 1 )"
check "EnvStressTestLate" "(def a 1)(def b 2)(def c 3)(def d 4)(def e 5)(def f 6)(def n 40) (n)" "40"
endBlock
echo ""