Fixed some parsing (tests pass!). Some clean up.
This commit is contained in:
parent
45cbf51f50
commit
1c82c6f726
|
@ -41,9 +41,6 @@ Object fetchFromEnvironment(const char *name, struct Environment *env)
|
|||
struct Environment envForLambda(const Object *params, const Object *arg_forms,
|
||||
struct Environment *outer)
|
||||
{
|
||||
printd("envForLambda()\n");
|
||||
debugObj(arg_forms);
|
||||
|
||||
int paramCount = listLength(params);
|
||||
|
||||
struct Environment env = {
|
||||
|
@ -60,12 +57,9 @@ struct Environment envForLambda(const Object *params, const Object *arg_forms,
|
|||
env.objects = malloc(sizeof(Object) * paramCount + 1);
|
||||
|
||||
const Object *march = arg_forms;
|
||||
printd("Param count: %d\n", paramCount);
|
||||
for(int i = 0; i < paramCount; i++) {
|
||||
const char *newObjName = itemAt(params, i)->name;
|
||||
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?
|
||||
march = march->forward;
|
||||
}
|
||||
|
|
68
src/object.c
68
src/object.c
|
@ -28,9 +28,7 @@ int listLength(const Object *listObj)
|
|||
return -1;
|
||||
|
||||
int len = 0;
|
||||
FOR_POINTER_IN_LIST(listObj) {
|
||||
len++;
|
||||
}
|
||||
FOR_POINTER_IN_LIST(listObj) { len++; }
|
||||
return len;
|
||||
}
|
||||
|
||||
|
@ -48,13 +46,12 @@ Object *itemAt(const Object *listObj, int n)
|
|||
if(!listObj || listObj->type != TYPE_LIST)
|
||||
return NULL;
|
||||
|
||||
Object *march = listObj->list;
|
||||
for(int i = 0; i < n; i++) {
|
||||
if(march == NULL)
|
||||
FOR_POINTER_IN_LIST(listObj) {
|
||||
if(POINTER == 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)
|
||||
return NULL;
|
||||
|
||||
Object *march = listObj->list;
|
||||
while(march->forward != NULL) {
|
||||
march = march->forward;
|
||||
Object *tail = NULL;
|
||||
FOR_POINTER_IN_LIST(listObj) {
|
||||
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)
|
||||
{
|
||||
// Only work with non-null list types
|
||||
if(!dest || dest->type != TYPE_LIST)
|
||||
return;
|
||||
|
||||
if(isEmpty(dest)) {
|
||||
allocObject(&dest->list, src);
|
||||
// Merely append, when possible
|
||||
if(ind >= listLength(dest)) {
|
||||
nf_addToList(dest, src);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO Check for off-by-one errors
|
||||
// ensure pointers connect old and new
|
||||
Object *march = dest->list;
|
||||
for(unsigned i = 1; i < ind; i++) {
|
||||
if(march->forward == NULL) {
|
||||
allocObject(&march->forward, src);
|
||||
return;
|
||||
}
|
||||
march = march->forward;
|
||||
}
|
||||
// The objects to preceed and follow the new one
|
||||
Object *beforeNew = itemAt(dest, ind - 1);
|
||||
Object *afterNew = beforeNew->forward;
|
||||
|
||||
// Save and re-apply current march->forward
|
||||
Object *oldForward = march->forward;
|
||||
allocObject(&march->forward, src);
|
||||
march->forward->forward = oldForward;
|
||||
// Replace the `before` object's pointer
|
||||
allocObject(&beforeNew->forward, src);
|
||||
beforeNew->forward->forward = afterNew;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -174,9 +163,10 @@ void replaceListing(Object *list, int i, const Object src)
|
|||
if(!list || list->type != TYPE_LIST)
|
||||
return;
|
||||
Object *replace = itemAt(list, i);
|
||||
Object *oldForward = replace->forward;
|
||||
cleanObject(replace);
|
||||
*replace = src;
|
||||
replace->forward = NULL;
|
||||
replace->forward = oldForward;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -211,13 +201,11 @@ void stringList(char *dest, const Object *obj)
|
|||
dest[0] = '(';
|
||||
dest[1] = '\0';
|
||||
|
||||
const Object *tail = obj->list;
|
||||
while(tail != NULL) {
|
||||
FOR_POINTER_IN_LIST(obj) {
|
||||
strcat(dest, " ");
|
||||
char tok[90] = "";
|
||||
stringObj(tok, tail);
|
||||
stringObj(tok, POINTER);
|
||||
strcat(dest, tok);
|
||||
tail = tail->forward;
|
||||
}
|
||||
strcat(dest, " )");
|
||||
}
|
||||
|
@ -363,7 +351,8 @@ void deleteList(Object *dest)
|
|||
dest->list = NULL;
|
||||
}
|
||||
|
||||
void _copyList(Object *dest, const Object *src, int delete) {
|
||||
void _copyList(Object *dest, const Object *src, int delete)
|
||||
{
|
||||
if(!dest || !src) {
|
||||
printd("NULL\n");
|
||||
return;
|
||||
|
@ -377,7 +366,6 @@ void _copyList(Object *dest, const Object *src, int delete) {
|
|||
deleteList(dest);
|
||||
|
||||
FOR_POINTER_IN_LIST(src) {
|
||||
debugObj(POINTER);
|
||||
nf_addToList(dest, *POINTER);
|
||||
if(POINTER->type == TYPE_LIST) {
|
||||
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 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)
|
||||
{
|
||||
_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`
|
||||
inline Object newObject(Type type)
|
||||
{
|
||||
|
|
|
@ -80,7 +80,7 @@ struct Object {
|
|||
Object *list;
|
||||
char name[MAX_TOK_LEN];
|
||||
char *string;
|
||||
Object (*func)(Object, Object, struct Environment *env);
|
||||
Object (*func)(Object, Object, struct Environment *);
|
||||
struct Lambda *lambda; // Maybe better as not a pointer?
|
||||
enum errorCode err;
|
||||
};
|
||||
|
@ -97,7 +97,6 @@ void printList(const Object *list);
|
|||
void printObj(const Object *obj);
|
||||
void debugObj(const Object *obj);
|
||||
void printErr(const Object *obj);
|
||||
int wasMalloc(const Object *obj);
|
||||
int getType(const Object *obj);
|
||||
|
||||
int isEmpty(const Object *obj);
|
||||
|
@ -114,6 +113,7 @@ void copyList(Object *dest, const Object *src);
|
|||
void cleanObject(Object *target);
|
||||
void printAndClean(Object *target);
|
||||
void allocObject(Object **spot, const Object src);
|
||||
void appendList(Object *dest, const Object *src);
|
||||
|
||||
Object newObject(Type type);
|
||||
Object listObject();
|
||||
|
|
|
@ -20,17 +20,17 @@ void copySlice(char * dest, struct Slice *src)
|
|||
void debugSlice(struct Slice *s)
|
||||
{
|
||||
if(!s) {
|
||||
printd("NULL SLICE\n");
|
||||
printf("NULL SLICE\n");
|
||||
return;
|
||||
}
|
||||
printd("Debug Slice\n text:'");
|
||||
printf("Debug Slice\n text:'");
|
||||
for(int i = 0; i < s->length; i++) {
|
||||
printd("%c", s->text[i]);
|
||||
printf("%c", s->text[i]);
|
||||
if(s->text[i] == '\0')
|
||||
printd("NULLCHAR\n");
|
||||
printf("NULLCHAR\n");
|
||||
}
|
||||
printd("'\n");
|
||||
printd(" length: %d\n", s->length);
|
||||
printf("'\n");
|
||||
printf(" length: %d\n", s->length);
|
||||
}
|
||||
|
||||
Result parse(struct Slice *slices)
|
||||
|
@ -220,7 +220,10 @@ Object eval(const Object *obj, struct Environment *env)
|
|||
return ret;
|
||||
|
||||
} else {
|
||||
return *obj;
|
||||
Object newList = listObject();
|
||||
copyList(&newList, obj);
|
||||
return newList;
|
||||
//return *obj;
|
||||
}
|
||||
}
|
||||
case TYPE_LAMBDA:
|
||||
|
@ -356,6 +359,11 @@ Object parseEval(const char *input, struct Environment *env)
|
|||
int parens = 0;
|
||||
Object obj;
|
||||
struct Slice *tok = tokens;
|
||||
if(tok[i].text[0] != '(') {
|
||||
Object parsed = parse(tok).obj;
|
||||
obj = eval(&parsed, env);
|
||||
cleanObject(&parsed);
|
||||
} else {
|
||||
while(tok[i].text != NULL) {
|
||||
if(tok[i].text[0] == '(') {
|
||||
parens++;
|
||||
|
@ -366,10 +374,12 @@ Object parseEval(const char *input, struct Environment *env)
|
|||
tok = &tok[i + 1];
|
||||
i = -1;
|
||||
obj = eval(&parsed, env);
|
||||
cleanObject(&parsed);
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
free(tokens);
|
||||
return obj;
|
||||
}
|
||||
|
@ -394,11 +404,13 @@ int main(int argc, const char* argv[])
|
|||
for(int i = 1; i < argc; i++) {
|
||||
// cleanObject(&r);
|
||||
r = parseEval(argv[i], &env);
|
||||
printAndClean(&r);
|
||||
}
|
||||
printObj(&r);
|
||||
// printAndClean(&r);
|
||||
// printObj(&r);
|
||||
//printAndClean(&r);
|
||||
} else {
|
||||
repl(&env);
|
||||
}
|
||||
// deleteEnv(&env);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -49,13 +49,13 @@ Result result(Object obj, struct Slice *slices);
|
|||
void copySlice(char * dest, struct Slice *src);
|
||||
void debugSlice(struct Slice *s);
|
||||
|
||||
#define bopf(_name) \
|
||||
#define BASIC_OP(_name) \
|
||||
Object _name(Object obj1, Object obj2, struct Environment *env);
|
||||
bopf(add); bopf(sub);
|
||||
bopf(mul); bopf(dvi);
|
||||
bopf(mod); bopf(equ);
|
||||
bopf(gth); bopf(lth);
|
||||
#undef bopf
|
||||
BASIC_OP(add); BASIC_OP(sub);
|
||||
BASIC_OP(mul); BASIC_OP(dvi);
|
||||
BASIC_OP(mod); BASIC_OP(equ);
|
||||
BASIC_OP(gth); BASIC_OP(lth);
|
||||
#undef BASIC_OP
|
||||
Object catObjects(const Object obj1, const Object obj2, struct Environment *env);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -80,12 +80,12 @@ struct Slice *nf_tokenize(const char *input)
|
|||
i++;
|
||||
|
||||
} else if(input[i] == '"') {
|
||||
while(input[++i] != '"') {
|
||||
while(input[++i] != '"' && input[i] != '\0') {
|
||||
l++;
|
||||
}
|
||||
i++;
|
||||
} else {
|
||||
while(!isWhitespace(input[++i]) && !isSingle(input[i])) {
|
||||
while(!isWhitespace(input[++i]) && !isSingle(input[i]) && input[i] != '\0') {
|
||||
l++;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue