Add `iserr`, `defe`. Fix `eval`. Increase env size

`iserr` is a basic type-check like `isnum`
`defe` adds a string to the environment as the equivalent symbol
`eval` can take in variables or functions, instead of just raw strings
Broke type-printing into its own function
Errors maxing out an environment. Likely extending incorrectly
This commit is contained in:
Sage Vaillancourt 2020-11-06 15:07:12 -05:00
parent 31fcf0c2d8
commit 7c7a68df5f
5 changed files with 64 additions and 37 deletions

View File

@ -229,7 +229,7 @@ struct Environment defaultEnv()
{"cat", &catObjects}, {"fil", &filter}, {"len", &len},
{"ap", &append}, {"pre", &prepend},
{"at", &at}, {"rest", &rest}, {"rev", &reverse},
{"isnum", &isNum}, {"isstr", &isString},
{"isnum", &isNum}, {"isstr", &isString}, {"iserr", &isErr},
{"prn", &print}, {"pch", &pChar}, {"penv", &printEnvO},
{"eval", &parseEvalO},
#ifdef STANDALONE

View File

@ -331,44 +331,54 @@ void debugObj(const Object *obj)
return;
}
void _printList(const Object *list, int newline);
void _printObj(const Object *obj, int newline)
void printType(const Object *obj)
{
switch(obj->type) {
case TYPE_NUMBER:
printd("TYPE_NUMBER");
break;
printf("TYPE_NUMBER");
return;
case TYPE_BOOL:
printd("TYPE_BOOL");
break;
printf("TYPE_BOOL");
return;
case TYPE_LIST:
printd("TYPE_LIST\n");
break;
printf("TYPE_LIST");
return;
case TYPE_FUNC:
printd("TYPE_FUNC");
break;
printf("TYPE_FUNC");
return;
case TYPE_SYMBOL:
printd("TYPE_SYMBOL");
break;
printf("TYPE_SYMBOL");
return;
case TYPE_STRING:
printd("TYPE_STRING");
break;
printf("TYPE_STRING");
return;
case TYPE_LAMBDA:
printd("TYPE_LAMBDA Params:\n");
printObj(&obj->lambda->params);
printf("->");
printd("Lambda Body: \n");
printObj(&obj->lambda->body);
printf("TYPE_LAMBDA Params:\n");
return;
case TYPE_OTHER:
printd("TYPE_OTHER: ");
printf("TYPE_OTHER: ");
case TYPE_ERROR:
printd("TYPE_ERROR: ");
break;
printf("TYPE_ERROR: ");
return;
}
if(!isValidType(*obj))
printd("TYPE_OTHER (as int)");
printf("UNKNOWN TYPE (%d)", obj->type);
}
void _printList(const Object *list, int newline);
void _printObj(const Object *obj, int newline)
{
#ifdef DEBUG
printType(obj);
#endif
if (obj->type == TYPE_LAMBDA) {
printObj(&obj->lambda->params);
printf("->");
printObj(&obj->lambda->body);
return;
}
char temp[100] = "";
stringObj(temp, obj);

View File

@ -2,7 +2,7 @@
#define OBJECT_H
#define MAX_TOK_CNT 1024 // 128
#define MAX_ENV_ELM 50 // 50
#define MAX_ENV_ELM 100
#define FOR_POINTER_IN_LIST(_list) \
if(_list && _list->type == TYPE_LIST) \
@ -90,6 +90,7 @@ struct Other {
char* stringObj(char *dest, const Object *obj);
void printList(const Object *list);
void printType(const Object *obj);
void printObj(const Object *obj);
void _printObj(const Object *obj, int newline);
void debugObj(const Object *obj);

View File

@ -20,29 +20,27 @@
* @param env The environment to add the new definition to
* @return The symbol(s) defined
*/
Object evalDefArgs(const Object *argForms, struct Environment *env)
Object evalDefArgs(const Object *symbol, const Object *value, struct Environment *env)
{
const Object *newSymbol = argForms;
const Object *newValue = argForms->forward;
const char *name = newSymbol->string;
const char *name = symbol->string;
// Handles multi-definitions
if(newSymbol->type == TYPE_LIST && newValue->type == TYPE_LIST
&& listLength(newSymbol) == listLength(newValue)) {
FOR_POINTERS_IN_LISTS(newSymbol, newValue) {
if(symbol->type == TYPE_LIST && value->type == TYPE_LIST
&& listLength(symbol) == listLength(value)) {
FOR_POINTERS_IN_LISTS(symbol, value) {
Object finalValue = eval(P2, env);
addToEnv(env, P1->string, finalValue);
cleanObject(&finalValue);
}
return cloneObject(*newSymbol);
return cloneObject(*symbol);
}
Object finalValue = eval(newSymbol->forward, env);
Object finalValue = eval(value, env);
addToEnv(env, name, finalValue);
cleanObject(&finalValue);
return cloneObject(*newSymbol);
return cloneObject(*symbol);
}
Object evalIfArgs(const Object *argForms, struct Environment *env)
@ -101,7 +99,13 @@ Object evalBuiltIns(const Object *first, const Object *rest,
}
if(strcmp(first->string, "def") == 0) {
return evalDefArgs(rest, env);
return evalDefArgs(rest, rest->forward, env);
} else if(strcmp(first->string, "defe") == 0) {
Object symbol = eval(rest, env);
printObj(&symbol);
Object e = evalDefArgs(&symbol, rest->forward, env);
cleanObject(&symbol);
return e;
} else if(strcmp(first->string, "if") == 0) {
return evalIfArgs(rest, env);
} else if(strcmp(first->string, "fn") == 0) {
@ -493,6 +497,12 @@ Object isString(Object test, Object ignore, struct Environment *ignore2)
boolObject(1) : boolObject(0);
}
Object isErr(Object test, Object ignore, struct Environment *ignore2)
{
return test.type == TYPE_ERROR ?
boolObject(1) : boolObject(0);
}
Object print(Object p, Object ignore, struct Environment *env)
{
p = cloneObject(p);
@ -521,7 +531,12 @@ Object printEnvO(Object i1, Object i2, struct Environment *env) {
Object parseEvalO(Object text, Object ignore, struct Environment *env)
{
if(text.type != TYPE_STRING) {
if(text.type == TYPE_SYMBOL) {
Object string = eval(&text, env);
Object parsed = parseEval(string.string, env);
cleanObject(&string);
return parsed;
} else if(text.type != TYPE_STRING) {
return errorObject(CAN_ONLY_EVAL_STRINGS);
}
return parseEval(text.string, env);

View File

@ -57,6 +57,7 @@ Object reverse(Object _list, Object ignore, struct Environment *ignore2);
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 print(Object p, Object ignore, struct Environment *ignore2);
Object pChar(Object c, Object i1, struct Environment *i2);