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}, {"cat", &catObjects}, {"fil", &filter}, {"len", &len},
{"ap", &append}, {"pre", &prepend}, {"ap", &append}, {"pre", &prepend},
{"at", &at}, {"rest", &rest}, {"rev", &reverse}, {"at", &at}, {"rest", &rest}, {"rev", &reverse},
{"isnum", &isNum}, {"isstr", &isString}, {"isnum", &isNum}, {"isstr", &isString}, {"iserr", &isErr},
{"prn", &print}, {"pch", &pChar}, {"penv", &printEnvO}, {"prn", &print}, {"pch", &pChar}, {"penv", &printEnvO},
{"eval", &parseEvalO}, {"eval", &parseEvalO},
#ifdef STANDALONE #ifdef STANDALONE

View File

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

View File

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

View File

@ -20,29 +20,27 @@
* @param env The environment to add the new definition to * @param env The environment to add the new definition to
* @return The symbol(s) defined * @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 char *name = symbol->string;
const Object *newValue = argForms->forward;
const char *name = newSymbol->string;
// Handles multi-definitions // Handles multi-definitions
if(newSymbol->type == TYPE_LIST && newValue->type == TYPE_LIST if(symbol->type == TYPE_LIST && value->type == TYPE_LIST
&& listLength(newSymbol) == listLength(newValue)) { && listLength(symbol) == listLength(value)) {
FOR_POINTERS_IN_LISTS(newSymbol, newValue) { FOR_POINTERS_IN_LISTS(symbol, value) {
Object finalValue = eval(P2, env); Object finalValue = eval(P2, env);
addToEnv(env, P1->string, finalValue); addToEnv(env, P1->string, finalValue);
cleanObject(&finalValue); cleanObject(&finalValue);
} }
return cloneObject(*newSymbol); return cloneObject(*symbol);
} }
Object finalValue = eval(newSymbol->forward, env); Object finalValue = eval(value, env);
addToEnv(env, name, finalValue); addToEnv(env, name, finalValue);
cleanObject(&finalValue); cleanObject(&finalValue);
return cloneObject(*newSymbol); return cloneObject(*symbol);
} }
Object evalIfArgs(const Object *argForms, struct Environment *env) 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) { 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) { } else if(strcmp(first->string, "if") == 0) {
return evalIfArgs(rest, env); return evalIfArgs(rest, env);
} else if(strcmp(first->string, "fn") == 0) { } else if(strcmp(first->string, "fn") == 0) {
@ -493,6 +497,12 @@ Object isString(Object test, Object ignore, struct Environment *ignore2)
boolObject(1) : boolObject(0); 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) Object print(Object p, Object ignore, struct Environment *env)
{ {
p = cloneObject(p); 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) 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 errorObject(CAN_ONLY_EVAL_STRINGS);
} }
return parseEval(text.string, env); 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 isNum(Object test, Object ignore, struct Environment *ignore2);
Object isString(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 print(Object p, Object ignore, struct Environment *ignore2);
Object pChar(Object c, Object i1, struct Environment *i2); Object pChar(Object c, Object i1, struct Environment *i2);