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 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;
|
||||||
}
|
}
|
||||||
|
|
68
src/object.c
68
src/object.c
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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,6 +359,11 @@ 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;
|
||||||
|
if(tok[i].text[0] != '(') {
|
||||||
|
Object parsed = parse(tok).obj;
|
||||||
|
obj = eval(&parsed, env);
|
||||||
|
cleanObject(&parsed);
|
||||||
|
} else {
|
||||||
while(tok[i].text != NULL) {
|
while(tok[i].text != NULL) {
|
||||||
if(tok[i].text[0] == '(') {
|
if(tok[i].text[0] == '(') {
|
||||||
parens++;
|
parens++;
|
||||||
|
@ -366,10 +374,12 @@ Object parseEval(const char *input, struct Environment *env)
|
||||||
tok = &tok[i + 1];
|
tok = &tok[i + 1];
|
||||||
i = -1;
|
i = -1;
|
||||||
obj = eval(&parsed, env);
|
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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue