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:
parent
31fcf0c2d8
commit
7c7a68df5f
|
@ -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
|
||||
|
|
56
src/object.c
56
src/object.c
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue