Extremely barebones struct object implementation.
This commit is contained in:
parent
e2c977e95a
commit
6c8ff04711
|
@ -3,6 +3,8 @@ exe = pl
|
||||||
|
|
||||||
BINPREFIX ?= /usr/bin
|
BINPREFIX ?= /usr/bin
|
||||||
SCRIPTDIR ?= /usr/local/share/pebblisp
|
SCRIPTDIR ?= /usr/local/share/pebblisp
|
||||||
|
mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
|
||||||
|
mkfile_dir := $(dir $(mkfile_path))
|
||||||
|
|
||||||
GCC_COM ?= gcc -g -O0 -Wall -o $(exe) -D STANDALONE -DSCRIPTDIR=\"$(SCRIPTDIR)\"
|
GCC_COM ?= gcc -g -O0 -Wall -o $(exe) -D STANDALONE -DSCRIPTDIR=\"$(SCRIPTDIR)\"
|
||||||
|
|
||||||
|
@ -12,6 +14,9 @@ all:
|
||||||
notest:
|
notest:
|
||||||
$(GCC_COM) $(files)
|
$(GCC_COM) $(files)
|
||||||
|
|
||||||
|
local:
|
||||||
|
gcc -g -O0 -Wall -o $(exe) -D STANDALONE -DSCRIPTDIR=\"$(mkfile_dir)/examples\" $(files)
|
||||||
|
|
||||||
val:
|
val:
|
||||||
$(GCC_COM) $(files) && ./tests.sh -val
|
$(GCC_COM) $(files) && ./tests.sh -val
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@ struct Environment envForLambda(const Object* params, const Object* arg_forms,
|
||||||
struct Environment env = {.outer = outer,
|
struct Environment env = {.outer = outer,
|
||||||
.strings = NULL,
|
.strings = NULL,
|
||||||
.objects = NULL,
|
.objects = NULL,
|
||||||
|
.structCount = 0,
|
||||||
.size = paramCount};
|
.size = paramCount};
|
||||||
|
|
||||||
if (paramCount == 0) {
|
if (paramCount == 0) {
|
||||||
|
@ -210,6 +211,7 @@ struct Environment defaultEnv()
|
||||||
.strings = strings,
|
.strings = strings,
|
||||||
.objects = objects,
|
.objects = objects,
|
||||||
.size = size,
|
.size = size,
|
||||||
|
.structCount = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct symFunc symFuncs[] = {
|
struct symFunc symFuncs[] = {
|
||||||
|
@ -243,7 +245,7 @@ struct Environment defaultEnv()
|
||||||
{"prn", &print},
|
{"prn", &print},
|
||||||
{"pch", &pChar},
|
{"pch", &pChar},
|
||||||
{"penv", &printEnvO},
|
{"penv", &printEnvO},
|
||||||
{"sys", &systemCall},
|
//{"sys", &systemCall},
|
||||||
{"loadfile", &loadFile},
|
{"loadfile", &loadFile},
|
||||||
{"inp", &takeInput},
|
{"inp", &takeInput},
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -9,6 +9,9 @@ struct Environment {
|
||||||
Object* objects;
|
Object* objects;
|
||||||
struct Environment* outer;
|
struct Environment* outer;
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
|
int structCount;
|
||||||
|
struct StructDef* structDefs;
|
||||||
};
|
};
|
||||||
|
|
||||||
Object fetchFromEnvironment(const char* name, struct Environment* env);
|
Object fetchFromEnvironment(const char* name, struct Environment* env);
|
||||||
|
|
126
src/object.c
126
src/object.c
|
@ -95,6 +95,8 @@ inline int isEmpty(const Object* obj)
|
||||||
return obj->list == NULL;
|
return obj->list == NULL;
|
||||||
case TYPE_LAMBDA:
|
case TYPE_LAMBDA:
|
||||||
return obj->lambda == NULL;
|
return obj->lambda == NULL;
|
||||||
|
case TYPE_STRUCT:
|
||||||
|
return obj->structObject == NULL;
|
||||||
case TYPE_SYMBOL:
|
case TYPE_SYMBOL:
|
||||||
case TYPE_STRING:
|
case TYPE_STRING:
|
||||||
return obj->string == NULL || obj->string[0] == '\0';
|
return obj->string == NULL || obj->string[0] == '\0';
|
||||||
|
@ -109,6 +111,7 @@ inline int isEmpty(const Object* obj)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int allocations = 0;
|
||||||
/**
|
/**
|
||||||
* Allocate a copy of a given object into the given pointer.
|
* Allocate a copy of a given object into the given pointer.
|
||||||
* Does nothing if `spot` is NULL
|
* Does nothing if `spot` is NULL
|
||||||
|
@ -117,6 +120,12 @@ inline int isEmpty(const Object* obj)
|
||||||
*/
|
*/
|
||||||
void allocObject(Object** spot, const Object src)
|
void allocObject(Object** spot, const Object src)
|
||||||
{
|
{
|
||||||
|
if (allocations >= 10000) {
|
||||||
|
printf("MAX ALLOCATIONS EXCEEDED\n");
|
||||||
|
*spot = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
allocations++;
|
||||||
*spot = malloc(sizeof(struct Object));
|
*spot = malloc(sizeof(struct Object));
|
||||||
**spot = src;
|
**spot = src;
|
||||||
(*spot)->forward = NULL;
|
(*spot)->forward = NULL;
|
||||||
|
@ -247,6 +256,42 @@ void stringList(char* dest, const Object* obj)
|
||||||
strcat(dest, " )");
|
strcat(dest, " )");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a string from a given struct Object
|
||||||
|
* Blocks out with curly braces
|
||||||
|
*/
|
||||||
|
void stringStruct(char* dest, const Object* obj)
|
||||||
|
{
|
||||||
|
struct StructObject* so = obj->structObject;
|
||||||
|
dest[0] = '{';
|
||||||
|
dest[1] = '\0';
|
||||||
|
|
||||||
|
for (int i = 0; i < so->definition->fieldCount; i++) {
|
||||||
|
strcat(dest, " ");
|
||||||
|
strcat(dest, so->definition->names[i]);
|
||||||
|
strcat(dest, ": ");
|
||||||
|
int isString = so->fields[i].type == TYPE_STRING;
|
||||||
|
if (isString) {
|
||||||
|
strcat(dest, "\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
char tok[90] = "";
|
||||||
|
stringObj(tok, &so->fields[i]);
|
||||||
|
strcat(dest, tok);
|
||||||
|
|
||||||
|
if (isString) {
|
||||||
|
strcat(dest, "\"");
|
||||||
|
}
|
||||||
|
strcat(dest, ",");
|
||||||
|
}
|
||||||
|
int i = 0;
|
||||||
|
while (dest[i]) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
dest[i - 1] = ' ';
|
||||||
|
dest[i + 0] = '}';
|
||||||
|
dest[i + 1] = '\0';
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Creates a string from a given Object
|
* Creates a string from a given Object
|
||||||
* Returns NULL if either param is NULL
|
* Returns NULL if either param is NULL
|
||||||
|
@ -282,6 +327,10 @@ char* stringNObj(char* dest, const Object* obj, const size_t len)
|
||||||
case TYPE_SYMBOL:
|
case TYPE_SYMBOL:
|
||||||
snprintf(dest, len, "`%s`", obj->string);
|
snprintf(dest, len, "`%s`", obj->string);
|
||||||
break;
|
break;
|
||||||
|
case TYPE_STRUCT:
|
||||||
|
//snprintf(dest, len, "{%s}", obj->structObject->definition->names[0]);
|
||||||
|
stringStruct(dest, obj);
|
||||||
|
break;
|
||||||
case TYPE_LIST:
|
case TYPE_LIST:
|
||||||
case TYPE_SLIST:
|
case TYPE_SLIST:
|
||||||
stringList(dest, obj);
|
stringList(dest, obj);
|
||||||
|
@ -335,38 +384,26 @@ void debugObj(const Object* obj)
|
||||||
|
|
||||||
#if defined(DEBUG) || defined(STANDALONE)
|
#if defined(DEBUG) || defined(STANDALONE)
|
||||||
|
|
||||||
|
#define SIMPLE_TYPE(_type) case _type:\
|
||||||
|
printf(#_type);\
|
||||||
|
return
|
||||||
|
|
||||||
void printType(const Object* obj)
|
void printType(const Object* obj)
|
||||||
{
|
{
|
||||||
switch (obj->type) {
|
switch (obj->type) {
|
||||||
case TYPE_NUMBER:
|
SIMPLE_TYPE(TYPE_NUMBER);
|
||||||
printf("TYPE_NUMBER");
|
SIMPLE_TYPE(TYPE_STRUCT);
|
||||||
return;
|
SIMPLE_TYPE(TYPE_BOOL);
|
||||||
case TYPE_BOOL:
|
SIMPLE_TYPE(TYPE_LIST);
|
||||||
printf("TYPE_BOOL");
|
SIMPLE_TYPE(TYPE_SLIST);
|
||||||
return;
|
SIMPLE_TYPE(TYPE_FUNC);
|
||||||
case TYPE_LIST:
|
SIMPLE_TYPE(TYPE_SYMBOL);
|
||||||
printf("TYPE_LIST");
|
SIMPLE_TYPE(TYPE_STRING);
|
||||||
return;
|
SIMPLE_TYPE(TYPE_OTHER);
|
||||||
case TYPE_SLIST:
|
SIMPLE_TYPE(TYPE_ERROR);
|
||||||
printf("TYPE_SLIST");
|
|
||||||
return;
|
|
||||||
case TYPE_FUNC:
|
|
||||||
printf("TYPE_FUNC");
|
|
||||||
return;
|
|
||||||
case TYPE_SYMBOL:
|
|
||||||
printf("TYPE_SYMBOL");
|
|
||||||
return;
|
|
||||||
case TYPE_STRING:
|
|
||||||
printf("TYPE_STRING");
|
|
||||||
return;
|
|
||||||
case TYPE_LAMBDA:
|
case TYPE_LAMBDA:
|
||||||
printf("TYPE_LAMBDA Params:\n");
|
printf("TYPE_LAMBDA Params:\n");
|
||||||
return;
|
return;
|
||||||
case TYPE_OTHER:
|
|
||||||
printf("TYPE_OTHER: ");
|
|
||||||
case TYPE_ERROR:
|
|
||||||
printf("TYPE_ERROR: ");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isValidType(*obj)) {
|
if (!isValidType(*obj)) {
|
||||||
|
@ -467,10 +504,18 @@ void cleanObject(Object* target)
|
||||||
cleanObject(&target->lambda->body);
|
cleanObject(&target->lambda->body);
|
||||||
free(target->lambda);
|
free(target->lambda);
|
||||||
break;
|
break;
|
||||||
|
case TYPE_STRUCT:
|
||||||
|
for (int i = 0; i < target->structObject->definition->fieldCount; i++) {
|
||||||
|
cleanObject(&target->structObject->fields[i]);
|
||||||
|
}
|
||||||
|
free(target->structObject->fields);
|
||||||
|
free(target->structObject);
|
||||||
|
target->structObject = NULL;
|
||||||
|
break;
|
||||||
case TYPE_ERROR:
|
case TYPE_ERROR:
|
||||||
#ifndef SIMPLE_ERRORS
|
#ifndef SIMPLE_ERRORS
|
||||||
free(target->error->context);
|
//free(target->error->context);
|
||||||
free(target->error);
|
//free(target->error);
|
||||||
target->error = NULL;
|
target->error = NULL;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
@ -605,6 +650,16 @@ inline Object listObject()
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns an empty struct Object
|
||||||
|
inline Object structObject(struct StructDef *definition)
|
||||||
|
{
|
||||||
|
Object structo = newObject(TYPE_STRUCT);
|
||||||
|
structo.structObject = malloc(sizeof(struct StructObject));
|
||||||
|
structo.structObject->definition = definition;
|
||||||
|
structo.structObject->fields = malloc(sizeof(Object) * definition->fieldCount);
|
||||||
|
return structo;
|
||||||
|
}
|
||||||
|
|
||||||
// Returns a list Object starting with the given Object
|
// Returns a list Object starting with the given Object
|
||||||
inline Object startList(const Object start)
|
inline Object startList(const Object start)
|
||||||
{
|
{
|
||||||
|
@ -629,6 +684,7 @@ inline int isValidType(const Object test)
|
||||||
case TYPE_NUMBER:
|
case TYPE_NUMBER:
|
||||||
case TYPE_BOOL:
|
case TYPE_BOOL:
|
||||||
case TYPE_LIST:
|
case TYPE_LIST:
|
||||||
|
case TYPE_STRUCT:
|
||||||
case TYPE_SLIST:
|
case TYPE_SLIST:
|
||||||
case TYPE_FUNC:
|
case TYPE_FUNC:
|
||||||
case TYPE_SYMBOL:
|
case TYPE_SYMBOL:
|
||||||
|
@ -673,6 +729,8 @@ inline Object cloneOther(const Object src)
|
||||||
return src.other->clone ? src.other->clone(src.other) : src;
|
return src.other->clone ? src.other->clone(src.other) : src;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Object cloneStruct(const Object src);
|
||||||
|
|
||||||
inline Object cloneObject(const Object src)
|
inline Object cloneObject(const Object src)
|
||||||
{
|
{
|
||||||
switch (src.type) {
|
switch (src.type) {
|
||||||
|
@ -681,6 +739,8 @@ inline Object cloneObject(const Object src)
|
||||||
return cloneList(src);
|
return cloneList(src);
|
||||||
case TYPE_LAMBDA:
|
case TYPE_LAMBDA:
|
||||||
return cloneLambda(src);
|
return cloneLambda(src);
|
||||||
|
case TYPE_STRUCT:
|
||||||
|
return cloneStruct(src);
|
||||||
case TYPE_STRING:
|
case TYPE_STRING:
|
||||||
case TYPE_SYMBOL:
|
case TYPE_SYMBOL:
|
||||||
return cloneString(src);
|
return cloneString(src);
|
||||||
|
@ -696,6 +756,16 @@ inline Object cloneObject(const Object src)
|
||||||
return src;
|
return src;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Object cloneStruct(const Object src)
|
||||||
|
{
|
||||||
|
Object structo = structObject(src.structObject->definition);
|
||||||
|
struct StructObject* so = structo.structObject;
|
||||||
|
for (int i = 0; i < so->definition->fieldCount; i++) {
|
||||||
|
so->fields[i] = cloneObject(src.structObject->fields[i]);
|
||||||
|
}
|
||||||
|
return structo;
|
||||||
|
}
|
||||||
|
|
||||||
inline Object numberObject(int num)
|
inline Object numberObject(int num)
|
||||||
{
|
{
|
||||||
Object o = newObject(TYPE_NUMBER);
|
Object o = newObject(TYPE_NUMBER);
|
||||||
|
|
16
src/object.h
16
src/object.h
|
@ -72,6 +72,7 @@ typedef enum Type {
|
||||||
TYPE_BOOL,
|
TYPE_BOOL,
|
||||||
TYPE_LIST,
|
TYPE_LIST,
|
||||||
TYPE_SLIST,
|
TYPE_SLIST,
|
||||||
|
TYPE_STRUCT,
|
||||||
TYPE_FUNC,
|
TYPE_FUNC,
|
||||||
TYPE_SYMBOL,
|
TYPE_SYMBOL,
|
||||||
TYPE_LAMBDA,
|
TYPE_LAMBDA,
|
||||||
|
@ -81,6 +82,7 @@ typedef enum Type {
|
||||||
} Type;
|
} Type;
|
||||||
|
|
||||||
typedef struct Object Object;
|
typedef struct Object Object;
|
||||||
|
|
||||||
struct Lambda;
|
struct Lambda;
|
||||||
struct Environment;
|
struct Environment;
|
||||||
struct Slice;
|
struct Slice;
|
||||||
|
@ -101,6 +103,7 @@ struct Object {
|
||||||
|
|
||||||
Object (*func)(Object, Object, struct Environment *);
|
Object (*func)(Object, Object, struct Environment *);
|
||||||
|
|
||||||
|
struct StructObject *structObject;
|
||||||
struct Lambda *lambda;
|
struct Lambda *lambda;
|
||||||
struct Other *other;
|
struct Other *other;
|
||||||
#ifdef SIMPLE_ERRORS
|
#ifdef SIMPLE_ERRORS
|
||||||
|
@ -111,6 +114,17 @@ struct Object {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct StructDef {
|
||||||
|
int fieldCount;
|
||||||
|
char* name;
|
||||||
|
const char** names;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct StructObject {
|
||||||
|
struct StructDef *definition;
|
||||||
|
struct Object* fields; // Order should match that in the definition.
|
||||||
|
};
|
||||||
|
|
||||||
struct Lambda {
|
struct Lambda {
|
||||||
Object params;
|
Object params;
|
||||||
Object body;
|
Object body;
|
||||||
|
@ -204,6 +218,8 @@ Object boolObject(int b);
|
||||||
|
|
||||||
Object numberObject(int num);
|
Object numberObject(int num);
|
||||||
|
|
||||||
|
Object structObject(struct StructDef *definition);
|
||||||
|
|
||||||
Object otherObject();
|
Object otherObject();
|
||||||
|
|
||||||
Object errorObject(enum errorCode err);
|
Object errorObject(enum errorCode err);
|
||||||
|
|
|
@ -43,6 +43,52 @@ Object evalDefArgs(const Object* symbol, const Object* value,
|
||||||
return cloneObject(*symbol);
|
return cloneObject(*symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void printStructDef(const struct StructDef *def)
|
||||||
|
{
|
||||||
|
printf("%s: {\n", def->name);
|
||||||
|
for (int i = 0; i < def->fieldCount; i++) {
|
||||||
|
printf(" %s,\n", def->names[i]);
|
||||||
|
}
|
||||||
|
printf("}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a struct to the environment with a given name and fields.
|
||||||
|
*
|
||||||
|
* (struct point (x y))
|
||||||
|
*/
|
||||||
|
Object evalStructArgs(const Object* symbol, const Object* fields, struct Environment* env)
|
||||||
|
{
|
||||||
|
const char* name = symbol->string;
|
||||||
|
|
||||||
|
if (!isListy(*fields)) {
|
||||||
|
return errorObject(NOT_A_LIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct StructDef def;
|
||||||
|
//def.name = name;
|
||||||
|
def.name = malloc(sizeof(char) * (strlen(name) + 1));
|
||||||
|
strcpy(def.name, name);
|
||||||
|
def.fieldCount = listLength(fields);
|
||||||
|
def.names = malloc(sizeof(char*) * def.fieldCount);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
FOR_POINTER_IN_LIST(fields) {
|
||||||
|
def.names[i] = POINTER->string;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (env->outer) {
|
||||||
|
env = env->outer;
|
||||||
|
}
|
||||||
|
env->structDefs = malloc(sizeof(struct StructDef) * 1);
|
||||||
|
env->structCount = 1;
|
||||||
|
env->structDefs[0] = def;
|
||||||
|
printStructDef(&env->structDefs[0]);
|
||||||
|
|
||||||
|
return boolObject(1);
|
||||||
|
}
|
||||||
|
|
||||||
Object evalIfArgs(const Object* argForms, struct Environment* env)
|
Object evalIfArgs(const Object* argForms, struct Environment* env)
|
||||||
{
|
{
|
||||||
Object condition = eval(argForms, env);
|
Object condition = eval(argForms, env);
|
||||||
|
@ -118,6 +164,8 @@ Object evalBuiltIns(const Object* first, const Object* rest,
|
||||||
return evalLambdaArgs(rest);
|
return evalLambdaArgs(rest);
|
||||||
} else if (strcmp(first->string, "map") == 0) {
|
} else if (strcmp(first->string, "map") == 0) {
|
||||||
return evalMapArgs(rest, env);
|
return evalMapArgs(rest, env);
|
||||||
|
} else if (strcmp(first->string, "struct") == 0) {
|
||||||
|
return evalStructArgs(rest, rest->forward, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
return errorObject(BUILT_IN_NOT_FOUND);
|
return errorObject(BUILT_IN_NOT_FOUND);
|
||||||
|
@ -246,7 +294,6 @@ Object evalList(const Object* obj, struct Environment* env)
|
||||||
}
|
}
|
||||||
|
|
||||||
Object* first_form = obj->list;
|
Object* first_form = obj->list;
|
||||||
|
|
||||||
{ // Try to eval built-ins
|
{ // Try to eval built-ins
|
||||||
Object builtIn = evalBuiltIns(first_form, first_form->forward, env);
|
Object builtIn = evalBuiltIns(first_form, first_form->forward, env);
|
||||||
|
|
||||||
|
@ -257,6 +304,36 @@ Object evalList(const Object* obj, struct Environment* env)
|
||||||
cleanObject(&builtIn);
|
cleanObject(&builtIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct StructDef *def = NULL;
|
||||||
|
if (first_form->type == TYPE_SYMBOL) {
|
||||||
|
struct Environment* outerEnv = env;
|
||||||
|
while (outerEnv->outer) {
|
||||||
|
outerEnv = outerEnv->outer;
|
||||||
|
}
|
||||||
|
//printf("evalList firstElementName: %s\n", first_form->string);
|
||||||
|
//printf("checking for struct `%s`\n", first_form->string);
|
||||||
|
//printf("%d structs available\n", outerEnv->structCount);
|
||||||
|
for (int i = 0; i < outerEnv->structCount; i++) {
|
||||||
|
//printf("struct[%d] - `%s`\n", i, outerEnv->structDefs[i].name);
|
||||||
|
if (strcmp(first_form->string, outerEnv->structDefs[i].name) == 0) {
|
||||||
|
def = &outerEnv->structDefs[i];
|
||||||
|
printf("Found struct definition for %s!\n", first_form->string);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (def) {
|
||||||
|
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
|
// Evaluate the list based on the first element's type
|
||||||
Object first_eval = eval(first_form, env);
|
Object first_eval = eval(first_form, env);
|
||||||
switch (first_eval.type) {
|
switch (first_eval.type) {
|
||||||
|
@ -273,6 +350,9 @@ Object evalList(const Object* obj, struct Environment* env)
|
||||||
nf_addToList(&list, first_eval);
|
nf_addToList(&list, first_eval);
|
||||||
FOR_POINTER_IN_LIST(obj) {
|
FOR_POINTER_IN_LIST(obj) {
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
|
if (isStringy(*POINTER)) {
|
||||||
|
printf("evalList elementName: %s\n", POINTER->string);
|
||||||
|
}
|
||||||
nf_addToList(&list, eval(POINTER, env));
|
nf_addToList(&list, eval(POINTER, env));
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
@ -291,6 +371,7 @@ Object eval(const Object* obj, struct Environment* env)
|
||||||
case TYPE_NUMBER:
|
case TYPE_NUMBER:
|
||||||
case TYPE_BOOL:
|
case TYPE_BOOL:
|
||||||
case TYPE_STRING:
|
case TYPE_STRING:
|
||||||
|
case TYPE_STRUCT:
|
||||||
return cloneObject(*obj);
|
return cloneObject(*obj);
|
||||||
|
|
||||||
case TYPE_SYMBOL:
|
case TYPE_SYMBOL:
|
||||||
|
|
Loading…
Reference in New Issue