Fixed some parsing (tests pass!). Some clean up.

This commit is contained in:
= 2020-05-15 04:51:59 +01:00
parent 45cbf51f50
commit 1c82c6f726
6 changed files with 73 additions and 73 deletions

View File

@ -41,9 +41,6 @@ Object fetchFromEnvironment(const char *name, struct Environment *env)
struct Environment envForLambda(const Object *params, const Object *arg_forms, struct Environment envForLambda(const Object *params, const Object *arg_forms,
struct Environment *outer) struct Environment *outer)
{ {
printd("envForLambda()\n");
debugObj(arg_forms);
int paramCount = listLength(params); int paramCount = listLength(params);
struct Environment env = { struct Environment env = {
@ -60,12 +57,9 @@ struct Environment envForLambda(const Object *params, const Object *arg_forms,
env.objects = malloc(sizeof(Object) * paramCount + 1); env.objects = malloc(sizeof(Object) * paramCount + 1);
const Object *march = arg_forms; const Object *march = arg_forms;
printd("Param count: %d\n", paramCount);
for(int i = 0; i < paramCount; i++) { for(int i = 0; i < paramCount; i++) {
const char *newObjName = itemAt(params, i)->name; const char *newObjName = itemAt(params, i)->name;
const Object newEnvObj = eval(march, outer); const Object newEnvObj = eval(march, outer);
printd("Adding new object '%s' to lambda env: ", newObjName);
debugObj(&newEnvObj);
addToEnv(&env, newObjName, newEnvObj); // Could use eval_forms? addToEnv(&env, newObjName, newEnvObj); // Could use eval_forms?
march = march->forward; march = march->forward;
} }

View File

@ -28,9 +28,7 @@ int listLength(const Object *listObj)
return -1; return -1;
int len = 0; int len = 0;
FOR_POINTER_IN_LIST(listObj) { FOR_POINTER_IN_LIST(listObj) { len++; }
len++;
}
return len; return len;
} }
@ -48,13 +46,12 @@ Object *itemAt(const Object *listObj, int n)
if(!listObj || listObj->type != TYPE_LIST) if(!listObj || listObj->type != TYPE_LIST)
return NULL; return NULL;
Object *march = listObj->list; FOR_POINTER_IN_LIST(listObj) {
for(int i = 0; i < n; i++) { if(POINTER == NULL)
if(march == NULL)
return NULL; return NULL;
march = march->forward; if(n-- == 0)
return POINTER;
} }
return march;
} }
/** /**
@ -67,11 +64,11 @@ Object *tail(const Object *listObj)
if(!listObj || listObj->type != TYPE_LIST) if(!listObj || listObj->type != TYPE_LIST)
return NULL; return NULL;
Object *march = listObj->list; Object *tail = NULL;
while(march->forward != NULL) { FOR_POINTER_IN_LIST(listObj) {
march = march->forward; tail = POINTER;
} }
return march; return tail;
} }
/** /**
@ -135,30 +132,22 @@ void allocObject(Object **spot, const Object src)
*/ */
void insertIntoList(Object *dest, unsigned ind, const Object src) void insertIntoList(Object *dest, unsigned ind, const Object src)
{ {
// Only work with non-null list types
if(!dest || dest->type != TYPE_LIST) if(!dest || dest->type != TYPE_LIST)
return; return;
if(isEmpty(dest)) { // Merely append, when possible
allocObject(&dest->list, src); if(ind >= listLength(dest)) {
nf_addToList(dest, src);
return; return;
} }
// TODO Check for off-by-one errors // The objects to preceed and follow the new one
// ensure pointers connect old and new Object *beforeNew = itemAt(dest, ind - 1);
Object *march = dest->list; Object *afterNew = beforeNew->forward;
for(unsigned i = 1; i < ind; i++) {
if(march->forward == NULL) {
allocObject(&march->forward, src);
return;
}
march = march->forward;
}
// Save and re-apply current march->forward // Replace the `before` object's pointer
Object *oldForward = march->forward; allocObject(&beforeNew->forward, src);
allocObject(&march->forward, src); beforeNew->forward->forward = afterNew;
march->forward->forward = oldForward;
} }
/** /**
@ -174,9 +163,10 @@ void replaceListing(Object *list, int i, const Object src)
if(!list || list->type != TYPE_LIST) if(!list || list->type != TYPE_LIST)
return; return;
Object *replace = itemAt(list, i); Object *replace = itemAt(list, i);
Object *oldForward = replace->forward;
cleanObject(replace); cleanObject(replace);
*replace = src; *replace = src;
replace->forward = NULL; replace->forward = oldForward;
} }
/** /**
@ -211,13 +201,11 @@ void stringList(char *dest, const Object *obj)
dest[0] = '('; dest[0] = '(';
dest[1] = '\0'; dest[1] = '\0';
const Object *tail = obj->list; FOR_POINTER_IN_LIST(obj) {
while(tail != NULL) {
strcat(dest, " "); strcat(dest, " ");
char tok[90] = ""; char tok[90] = "";
stringObj(tok, tail); stringObj(tok, POINTER);
strcat(dest, tok); strcat(dest, tok);
tail = tail->forward;
} }
strcat(dest, " )"); strcat(dest, " )");
} }
@ -363,7 +351,8 @@ void deleteList(Object *dest)
dest->list = NULL; dest->list = NULL;
} }
void _copyList(Object *dest, const Object *src, int delete) { void _copyList(Object *dest, const Object *src, int delete)
{
if(!dest || !src) { if(!dest || !src) {
printd("NULL\n"); printd("NULL\n");
return; return;
@ -377,7 +366,6 @@ void _copyList(Object *dest, const Object *src, int delete) {
deleteList(dest); deleteList(dest);
FOR_POINTER_IN_LIST(src) { FOR_POINTER_IN_LIST(src) {
debugObj(POINTER);
nf_addToList(dest, *POINTER); nf_addToList(dest, *POINTER);
if(POINTER->type == TYPE_LIST) { if(POINTER->type == TYPE_LIST) {
tail(dest)->list = NULL; tail(dest)->list = NULL;
@ -385,16 +373,22 @@ void _copyList(Object *dest, const Object *src, int delete) {
} }
} }
} }
/** /**
* Does a deep copy of all items from `src` to `dest` * Does a deep copy of all items from `src` to `dest`
* Does nothing if either is NULL, or not a list type * Does nothing if either is NULL, or not a list type
* Deletes all items from `dest` before copying * Does a shallow delete of items from `dest` before copying
*/ */
void copyList(Object *dest, const Object *src) void copyList(Object *dest, const Object *src)
{ {
_copyList(dest, src, 1); _copyList(dest, src, 1);
} }
void appendList(Object *dest, const Object *src)
{
_copyList(dest, src, 0);
}
// Returns a basic object with NULL forward and the given `type` // Returns a basic object with NULL forward and the given `type`
inline Object newObject(Type type) inline Object newObject(Type type)
{ {

View File

@ -80,7 +80,7 @@ struct Object {
Object *list; Object *list;
char name[MAX_TOK_LEN]; char name[MAX_TOK_LEN];
char *string; char *string;
Object (*func)(Object, Object, struct Environment *env); Object (*func)(Object, Object, struct Environment *);
struct Lambda *lambda; // Maybe better as not a pointer? struct Lambda *lambda; // Maybe better as not a pointer?
enum errorCode err; enum errorCode err;
}; };
@ -97,7 +97,6 @@ void printList(const Object *list);
void printObj(const Object *obj); void printObj(const Object *obj);
void debugObj(const Object *obj); void debugObj(const Object *obj);
void printErr(const Object *obj); void printErr(const Object *obj);
int wasMalloc(const Object *obj);
int getType(const Object *obj); int getType(const Object *obj);
int isEmpty(const Object *obj); int isEmpty(const Object *obj);
@ -114,6 +113,7 @@ void copyList(Object *dest, const Object *src);
void cleanObject(Object *target); void cleanObject(Object *target);
void printAndClean(Object *target); void printAndClean(Object *target);
void allocObject(Object **spot, const Object src); void allocObject(Object **spot, const Object src);
void appendList(Object *dest, const Object *src);
Object newObject(Type type); Object newObject(Type type);
Object listObject(); Object listObject();

View File

@ -20,17 +20,17 @@ void copySlice(char * dest, struct Slice *src)
void debugSlice(struct Slice *s) void debugSlice(struct Slice *s)
{ {
if(!s) { if(!s) {
printd("NULL SLICE\n"); printf("NULL SLICE\n");
return; return;
} }
printd("Debug Slice\n text:'"); printf("Debug Slice\n text:'");
for(int i = 0; i < s->length; i++) { for(int i = 0; i < s->length; i++) {
printd("%c", s->text[i]); printf("%c", s->text[i]);
if(s->text[i] == '\0') if(s->text[i] == '\0')
printd("NULLCHAR\n"); printf("NULLCHAR\n");
} }
printd("'\n"); printf("'\n");
printd(" length: %d\n", s->length); printf(" length: %d\n", s->length);
} }
Result parse(struct Slice *slices) Result parse(struct Slice *slices)
@ -220,7 +220,10 @@ Object eval(const Object *obj, struct Environment *env)
return ret; return ret;
} else { } else {
return *obj; Object newList = listObject();
copyList(&newList, obj);
return newList;
//return *obj;
} }
} }
case TYPE_LAMBDA: case TYPE_LAMBDA:
@ -356,19 +359,26 @@ Object parseEval(const char *input, struct Environment *env)
int parens = 0; int parens = 0;
Object obj; Object obj;
struct Slice *tok = tokens; struct Slice *tok = tokens;
while(tok[i].text != NULL) { if(tok[i].text[0] != '(') {
if(tok[i].text[0] == '(') { Object parsed = parse(tok).obj;
parens++; obj = eval(&parsed, env);
} else if(tok[i].text[0] == ')') { cleanObject(&parsed);
parens--; } else {
if(parens == 0) { while(tok[i].text != NULL) {
Object parsed = parse(tok).obj; if(tok[i].text[0] == '(') {
tok = &tok[i + 1]; parens++;
i = -1; } else if(tok[i].text[0] == ')') {
obj = eval(&parsed, env); parens--;
if(parens == 0) {
Object parsed = parse(tok).obj;
tok = &tok[i + 1];
i = -1;
obj = eval(&parsed, env);
cleanObject(&parsed);
}
} }
i++;
} }
i++;
} }
free(tokens); free(tokens);
return obj; return obj;
@ -394,11 +404,13 @@ int main(int argc, const char* argv[])
for(int i = 1; i < argc; i++) { for(int i = 1; i < argc; i++) {
// cleanObject(&r); // cleanObject(&r);
r = parseEval(argv[i], &env); r = parseEval(argv[i], &env);
printAndClean(&r);
} }
printObj(&r); // printObj(&r);
// printAndClean(&r); //printAndClean(&r);
} else { } else {
repl(&env); repl(&env);
} }
// deleteEnv(&env);
} }
#endif #endif

View File

@ -49,13 +49,13 @@ Result result(Object obj, struct Slice *slices);
void copySlice(char * dest, struct Slice *src); void copySlice(char * dest, struct Slice *src);
void debugSlice(struct Slice *s); void debugSlice(struct Slice *s);
#define bopf(_name) \ #define BASIC_OP(_name) \
Object _name(Object obj1, Object obj2, struct Environment *env); Object _name(Object obj1, Object obj2, struct Environment *env);
bopf(add); bopf(sub); BASIC_OP(add); BASIC_OP(sub);
bopf(mul); bopf(dvi); BASIC_OP(mul); BASIC_OP(dvi);
bopf(mod); bopf(equ); BASIC_OP(mod); BASIC_OP(equ);
bopf(gth); bopf(lth); BASIC_OP(gth); BASIC_OP(lth);
#undef bopf #undef BASIC_OP
Object catObjects(const Object obj1, const Object obj2, struct Environment *env); Object catObjects(const Object obj1, const Object obj2, struct Environment *env);
#endif #endif

View File

@ -80,12 +80,12 @@ struct Slice *nf_tokenize(const char *input)
i++; i++;
} else if(input[i] == '"') { } else if(input[i] == '"') {
while(input[++i] != '"') { while(input[++i] != '"' && input[i] != '\0') {
l++; l++;
} }
i++; i++;
} else { } else {
while(!isWhitespace(input[++i]) && !isSingle(input[i])) { while(!isWhitespace(input[++i]) && !isSingle(input[i]) && input[i] != '\0') {
l++; l++;
} }
} }