Reference count LAMBDAS.

Remove more unused code/checks.
Simplify evalList (though it could use more work).
This commit is contained in:
Sage Vaillancourt 2022-03-26 19:51:52 -04:00
parent 03920147d4
commit 158c21f441
5 changed files with 31 additions and 104 deletions

View File

@ -38,8 +38,6 @@ void deleteEnv(struct Environment* e);
struct Environment defaultEnv();
struct StructDef getStructDef(struct Environment* env, const char* name);
int getStructIndex(struct Environment* env, const char* name);
/// Needs to be freed!

View File

@ -59,9 +59,6 @@ Object* itemAt(const Object* listObj, int n)
}
FOR_POINTER_IN_LIST(listObj) {
if (POINTER == NULL) {
return NULL;
}
if (n-- == 0) {
return POINTER;
}
@ -179,7 +176,6 @@ void nf_addToList(Object* dest, const Object src)
static const char* errorText[] = {"MISMATCHED_PARENS",
"NULL_ENV",
"EMPTY_ENV",
"BUILT_IN_NOT_FOUND",
"NULL_PARSE",
"NULL_LAMBDA_LIST",
"NULL_MAP_ARGS",
@ -189,7 +185,6 @@ static const char* errorText[] = {"MISMATCHED_PARENS",
"LISTS_NOT_SAME_SIZE",
"BAD_NUMBER",
"UNSUPPORTED_NUMBER_TYPE",
"NOT_A_SYMBOL",
"ONLY_ONE_ARGUMENT",
"NOT_A_LIST",
"SCRIPT_NOT_FOUND",
@ -279,9 +274,6 @@ int stringStruct(char* dest, const Object* obj)
int stringNObj(char* dest, const Object* obj, const size_t len)
{
const char* initial = dest;
if (!dest || !obj) {
return 0;
}
switch (obj->type) {
case TYPE_NUMBER:
@ -396,8 +388,6 @@ void printType(const Object* obj)
}
}
void nestedPrintList(const Object* list, int newline);
void _printObj(const Object* obj, int newline)
{
#ifdef DEBUG
@ -440,29 +430,12 @@ inline void printObj(const Object* obj)
_printObj(obj, 1);
}
void nestedPrintList(const Object* list, int newline)
{
printf("(");
if (list && isListy(*list)) {
FOR_POINTER_IN_LIST(list) {
printf(" ");
_printObj(POINTER, 0);
}
}
printf(" )");
if (newline) {
printf("\n");
}
}
#endif
/**
* Performs appropriate free() on a given Object and NULLs its ->forward
* Returns immediately if param is NULL
*
* Strings: The Object's ->string is freed and NULLed
* Strings: The Object's ->string is freed
* Lists: deleteList() is called on the Object (may recurse)
* Lambdas: The body and params are cleaned, and the lambda itself is freed
*
@ -470,24 +443,22 @@ void nestedPrintList(const Object* list, int newline)
*/
void cleanObject(Object* target)
{
if (target == NULL) {
return;
}
switch (target->type) {
case TYPE_STRING:
case TYPE_SYMBOL:
free(target->string);
target->string = NULL;
break;
case TYPE_LIST:
case TYPE_SLIST:
deleteList(target);
break;
case TYPE_LAMBDA:
cleanObject(&target->lambda->params);
cleanObject(&target->lambda->body);
free(target->lambda);
target->lambda->refs -= 1;
if (!target->lambda->refs) {
cleanObject(&target->lambda->params);
cleanObject(&target->lambda->body);
free(target->lambda);
}
break;
case TYPE_STRUCT:
for (int i = 0; i < global()->structDefs[target->structObject->definition].fieldCount; i++) {
@ -495,14 +466,12 @@ void cleanObject(Object* target)
}
free(target->structObject->fields);
free(target->structObject);
target->structObject = NULL;
break;
case TYPE_ERROR:
#ifndef SIMPLE_ERRORS
free(target->error->plContext);
free(target->error->context);
free(target->error);
target->error = NULL;
#endif
break;
case TYPE_OTHER:
@ -515,8 +484,6 @@ void cleanObject(Object* target)
case TYPE_FUNC:
break;
}
target->forward = NULL;
}
/**
@ -553,18 +520,10 @@ void deleteList(Object* dest)
cleanObject(prevMarch);
free(prevMarch);
}
dest->list = NULL;
}
void _copyList(Object* dest, const Object* src, int delete)
{
if (!dest || !src) { printd("NULL\n");
return;
}
if (!isListy(*dest) || !isListy(*src)) { printd("NOT A LIST\n");
return;
}
if (delete) {
deleteList(dest);
}
@ -684,7 +643,8 @@ inline int isValidType(const Object test)
*/
inline Object cloneLambda(const Object old)
{
return constructLambda(&old.lambda->params, &old.lambda->body, NULL);
old.lambda->refs += 1;
return old;
}
Object cloneString(Object obj)
@ -796,6 +756,7 @@ inline Object constructLambda(const Object* params, const Object* body, struct E
o.lambda = malloc(sizeof(struct Lambda));
o.lambda->params = listObject();
o.lambda->body = listObject();
o.lambda->refs = 1;
copyList(&o.lambda->params, params);
copyList(&o.lambda->body, body);

View File

@ -44,7 +44,6 @@ enum errorCode {
MISMATCHED_PARENS,
NULL_ENV,
EMPTY_ENV,
BUILT_IN_NOT_FOUND,
NULL_PARSE,
NULL_LAMBDA_LIST,
NULL_MAP_ARGS,
@ -54,7 +53,6 @@ enum errorCode {
LISTS_NOT_SAME_SIZE,
BAD_NUMBER,
UNSUPPORTED_NUMBER_TYPE,
NOT_A_SYMBOL,
ONLY_ONE_ARGUMENT,
NOT_A_LIST,
SCRIPT_NOT_FOUND,
@ -120,11 +118,11 @@ struct StructDef {
struct StructObject {
int definition;
//struct StructDef *definition;
struct Object* fields; // Order should match that in the definition.
};
struct Lambda {
int refs;
Object params;
Object body;
};

View File

@ -39,17 +39,6 @@ Object evalDefArgs(const Object* symbol, const Object* value,
{
const char* name = symbol->string;
// Handles multi-definitions
if (bothAre(TYPE_LIST, symbol, value) &&
listLength(symbol) == listLength(value)) {
FOR_POINTERS_IN_LISTS(symbol, value) {
Object finalValue = eval(P2, env);
addToEnv(env, P1->string, finalValue);
cleanObject(&finalValue);
}
return cloneObject(*symbol);
}
Object finalValue = eval(value, env);
addToEnv(env, name, finalValue);
@ -87,9 +76,7 @@ Object evalStructArgs(const Object* symbol, const Object* fields, struct Environ
}
}
while (env->outer) {
env = env->outer;
}
env = global();
env->structDefs[env->structCount] = def;
env->structCount += 1;
@ -157,12 +144,9 @@ Object evalMapArgs(const Object* argForms, struct Environment* env)
}
Object evalBuiltIns(const Object* first, const Object* rest,
struct Environment* env)
struct Environment* env, int* found)
{
if (first->type != TYPE_SYMBOL) {
return errorObject(NOT_A_SYMBOL);
}
*found = 1;
if (strcmp(first->string, "def") == 0) {
return evalDefArgs(rest, rest->forward, env);
#ifndef LOW_MEM
@ -182,7 +166,8 @@ Object evalBuiltIns(const Object* first, const Object* rest,
return evalStructArgs(rest, rest->forward, env);
}
return errorObject(BUILT_IN_NOT_FOUND);
*found = 0;
return *first;
}
/**
@ -296,37 +281,28 @@ Object evalList(const Object* obj, struct Environment* env)
}
Object* first_form = obj->list;
{ // Try to eval built-ins
Object builtIn = evalBuiltIns(first_form, first_form->forward, env);
if (!isError(builtIn, BUILT_IN_NOT_FOUND) &&
!isError(builtIn, NOT_A_SYMBOL)) {
if (first_form->type == TYPE_SYMBOL) {
int found;
Object builtIn = evalBuiltIns(first_form, first_form->forward, env, &found);
if (found) {
return builtIn;
}
cleanObject(&builtIn);
}
int def = -1;
if (first_form->type == TYPE_SYMBOL) {
struct Environment* outerEnv = global();
for (int i = 0; i < outerEnv->structCount; i++) {
if (strcmp(first_form->string, outerEnv->structDefs[i].name) == 0) {
def = i;
break;
Object structo = structObject(i);
int s = 0;
FOR_POINTER_IN_LIST(obj) {
if (s != 0) { // Skip the field name
structo.structObject->fields[s - 1] = eval(POINTER, env);
}
s++;
}
return structo;
}
}
}
if (def >= 0) {
Object structo = structObject(def);
int i = 0;
FOR_POINTER_IN_LIST(obj) {
if (i != 0) {
structo.structObject->fields[i - 1] = eval(POINTER, env);
}
i++;
}
return structo;
}
// Evaluate the list based on the first element's type
Object first_eval = eval(first_form, env);
@ -338,7 +314,7 @@ Object evalList(const Object* obj, struct Environment* env)
case TYPE_LAMBDA:
return listEvalLambda(&first_eval, first_form->forward, env);
default: { // Return list with each element evaluated
default: { // Return list with each element evaluated
Object list = listObject();
int i = 0;
nf_addToList(&list, first_eval);
@ -597,7 +573,7 @@ Object parseEval(const char* input, struct Environment* env)
cleanObject(&obj);
Object parsed = parse(tok).obj;
if (parsed.type == TYPE_ERROR) {
obj = parsed; // TODO Check necessity
obj = parsed; // TODO Check necessity
obj.error->plContext = malloc(sizeof(struct Slice));
*obj.error->plContext = *lastOpen;
break;
@ -749,10 +725,6 @@ int main(int argc, const char* argv[])
action.sa_sigaction = handler;
sigaction(SIGSEGV, &action, NULL);
// struct Environment* e = &env;
// e += 10000;
// printEnv(e);
readFile(SCRIPTDIR "/lib.pbl", &env);
if (argc >= 2) {
FILE* file = fopen(argv[1], "r");

View File

@ -65,8 +65,6 @@ struct Slice* nf_tokenize(const char* input, struct Error* err)
int parens = 0;
while (input[i] != '\0') {
int l = 1;
// printd("input: '%c'\n", input[i]);
if (isWhitespace(input[i]) || input[i] == ';') {
if (input[i] == '\n') {
lineNumber++;