From 359d8ed43999efb9d6944e902e23cbe9f8ca944f Mon Sep 17 00:00:00 2001 From: Sage Vaillancourt Date: Tue, 5 May 2020 18:42:28 +0100 Subject: [PATCH] Lambdas begin to work! --- src/.pebblisp.c.swp | Bin 28672 -> 28672 bytes src/object.c | 215 ++++++++++++++++++++++++++++++++++++++++++++ src/object.h | 64 +++++++++++++ src/pebblisp.c | 175 +++++++++++++++++++++++++++++------- src/pebblisp.h | 5 ++ src/tags | 29 +++++- 6 files changed, 450 insertions(+), 38 deletions(-) create mode 100644 src/object.c create mode 100644 src/object.h diff --git a/src/.pebblisp.c.swp b/src/.pebblisp.c.swp index 30bc5b07c1ad5a137dc662ef5fda2efcb0b8e146..95b393d31a82f8bd32c571b9c08fb82bbd6038a5 100644 GIT binary patch literal 28672 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 Dq5pwg diff --git a/src/object.c b/src/object.c new file mode 100644 index 0000000..a0ca4e2 --- /dev/null +++ b/src/object.c @@ -0,0 +1,215 @@ +#include "object.h" +#include +#include +#include + +#ifndef STANDALONE +#define printf(...) stringObj(NULL, NULL) +#endif + +int listLength(const Object *listObj) +{ + if(!listObj || listObj->type != TYPE_LIST) + return -1; + + Object *t = listObj->list; + if(t == NULL) + return 0; + + int len = 1; + while(t->forward != NULL) { + t = t->forward; + len++; + } + return len; +} + +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++) { + march = march->forward; + + if(march == NULL) + return NULL; + } + return march; +} + +// Returns last object in list (->forward == NULL) +Object *tail(const Object *listObj) +{ + if(!listObj || listObj->type != TYPE_LIST) + return NULL; + + Object *t = listObj->list; + while(t->forward != NULL) { + t = t->forward; + } + return t; +} + +// Adds an object to the end of a list object +void addToList(Object *dest, const Object src) +{ + if(!dest || dest->type != TYPE_LIST) + return; + + if(dest->list == NULL) { + dest->list = malloc(sizeof(struct Object)); + *dest->list = src; + dest->list->forward = NULL; + return; + } + + Object *end = tail(dest); + end->forward = malloc(sizeof(struct Object)); + *end->forward = src; + end->forward->forward = NULL; +} + +// Puts a string version of the given object into a given string +char* stringObj(char *dest, const Object *obj) +{ + if(!dest || !obj) + return NULL; + + if(obj->type == TYPE_NUMBER) { + snprintf(dest, MAX_TOK_LEN, "%d", obj->number); + } else if(obj->type == TYPE_SYMBOL) { + snprintf(dest, MAX_TOK_LEN, "%s", obj->name); + } else if(obj->type == TYPE_BOOL) { + snprintf(dest, MAX_TOK_LEN, "%s", obj->number ? "T" : "F"); + } else if(obj->type == TYPE_ERROR) { + snprintf(dest, MAX_TOK_LEN, "E%d", obj->err); + } else { + snprintf(dest, MAX_TOK_LEN, "%d", obj->number); + } + + return dest; +} + +int depth = 0; + +// Prints the given object +void printObj(const Object *obj) +{ + for(int i = 0; i < depth; i++) + printf(" "); + depth++; + + if(obj->type == TYPE_NUMBER) { + printf("TYPE_NUMBER"); + } else if(obj->type == TYPE_BOOL) { + printf("TYPE_BOOL"); + } else if(obj->type == TYPE_LIST) { + printf("TYPE_LIST\n"); + printList(obj); + depth--; + return; + } else if(obj->type == TYPE_FUNC) { + printf("TYPE_FUNC"); + } else if(obj->type == TYPE_SYMBOL) { + printf("TYPE_SYMBOL"); + } else if(obj->type == TYPE_LAMBDA) { + printf("TYPE_LAMBDA Params:\n"); + depth++; + printObj(&obj->lambda->params); + for(int i = 1; i < depth; i++) + printf(" "); + printf("Lambda Body: \n"); + printObj(&obj->lambda->body); + } else if(obj->type == TYPE_ERROR) { + printf("TYPE_ERROR: "); + } else { + printf("TYPE_OTHER (as int)"); + } + depth--; + char temp[20] = ""; + stringObj(temp, obj); + printf(": %s\n", temp); +} + +void printList(const Object *list) +{ + const Object *tail = list->list; + if(tail == NULL) { + for(int i = 0; i < depth; i++) + printf(" "); + printf("EMPTY LIST\n"); + return; + } + while(tail != NULL) { + depth++; + printObj(tail); + depth--; + tail = tail->forward; + } +} + +// Frees all objects in a list +void deleteList(const Object *dest) +{ + if(dest->type != TYPE_LIST) { + printf("Tried to delete something other than a list\n"); + return; + } + + Object *tail = dest->list; + while(tail != NULL) { + Object *prevTail = tail; + tail = tail->forward; + free(prevTail); + } +} + +inline Object listObject() +{ + Object list; + list.forward = NULL; + list.type = TYPE_LIST; + list.list = NULL; + return list; +} + +void copyList(Object *dest, const Object *src) +{ + if(!dest || !src || dest->type != TYPE_LIST || src->type != TYPE_LIST) + return; + + // deleteList(dest); + const Object *march = src->list; + while(march != NULL) { + addToList(dest, *march); + march = march->forward; + } +} + +inline Object numberObject(int num) +{ + Object o; + o.forward = NULL; + o.type = TYPE_NUMBER; + return o; +} + +inline Object lambdaObject() +{ + Object o; + o.forward = NULL; + o.type = TYPE_LAMBDA; + o.lambda = malloc(sizeof(struct Lambda)); + return o; +} + +inline Object errorObject(enum errorCode err) +{ + Object o; + o.forward = NULL; + o.type = TYPE_ERROR; + o.err = err; + return o; +} diff --git a/src/object.h b/src/object.h new file mode 100644 index 0000000..4821bf8 --- /dev/null +++ b/src/object.h @@ -0,0 +1,64 @@ +#ifndef OBJECT_H +#define OBJECT_H + +#define MAX_TOK_LEN 4 // 11 +#define MAX_TOK_CNT 128 // 128 +#define MAX_ENV_ELM 15 // 50 + +enum errorCode { + BAD_LIST_OF_SYMBOL_STRINGS, + TYPE_LIST_NOT_CAUGHT, + NULL_ENV, + BUILT_IN_NOT_FOUND, + NULL_PARSE +}; + +typedef enum Type { + TYPE_NUMBER, + TYPE_BOOL, + TYPE_LIST, + TYPE_FUNC, + TYPE_SYMBOL, + TYPE_LAMBDA, + TYPE_ERROR // Currently unused +} Type; + +typedef struct Object Object; +struct Lambda; + +struct Object { + Type type; + Object *forward; + union { + int number; + Object *list; + char name[MAX_TOK_LEN]; + Object (*func)(Object, Object); + struct Lambda *lambda; // Maybe better as not a pointer + enum errorCode err; + }; +}; + +// Maybe better as pointers +struct Lambda { + Object params; + Object body; +}; + +char* stringObj(char *dest, const Object *obj); +void printList(const Object *list); +void printObj(const Object *obj); + +Object *tail(const Object *listObj); +void addToList(Object *dest, Object src); +void deleteList(const Object *dest); +int listLength(const Object *listObj); +Object *itemAt(const Object *listObj, int n); +void copyList(Object *dest, const Object *src); + +Object listObject(); +Object numberObject(int num); +Object lambdaObject(); +Object errorObject(); + +#endif diff --git a/src/pebblisp.c b/src/pebblisp.c index 4a7f91f..518f105 100644 --- a/src/pebblisp.c +++ b/src/pebblisp.c @@ -28,7 +28,11 @@ void debugSlice(struct Slice *s) Object fetchFromEnvironment(const char *name, struct Environment *env) { + if(!env) + return errorObject(NULL_ENV); + printf("Fetching '%s' from env\n", name); + printEnv(env); int i = 0; const char *next = env->strings[i]; while(next != NULL) { @@ -37,6 +41,10 @@ Object fetchFromEnvironment(const char *name, struct Environment *env) } next = env->strings[++i]; } + printf("Trying outer\n"); + if(env->outer) { + return fetchFromEnvironment(name, env->outer); + } printf("DID NOT FIND SYMBOL\n"); Object o; o.type = TYPE_ERROR; @@ -51,7 +59,7 @@ Result parse(struct Slice *slices) rest = &slices[1]; } else { printf("Assigning null...\n"); - rest = NULL; + return R(errorObject(NULL_PARSE), NULL); } if(token->text[0] == '(') { @@ -103,8 +111,6 @@ Object parseAtom(struct Slice *s) Object evalDefArgs(const Object *arg_forms, struct Environment *env) { - printf("evalDefArgs()\n"); - const Object *first_form = &arg_forms[0]; const char *name = first_form->name; @@ -122,69 +128,151 @@ Object evalIfArgs(const Object *arg_forms, struct Environment *env) eval(arg_forms->forward->forward, env); } -Object evalBuiltIns(const Object *first, const Object *rest, int *found, +Object evalLambdaArgs(const Object *arg_forms) +{ + const Object *params_expr = &arg_forms[0]; + const Object *body_expr = &arg_forms[1]; + + Object o = lambdaObject(); + o.lambda->params = listObject(); + copyList(&o.lambda->params, params_expr); + + o.lambda->body = listObject(); + copyList(&o.lambda->body, arg_forms->forward); + return o; +} + +void parseListOfSymbolStrings(const Object *form, const char **symbolStrings, + int len) +{ + if(!form || form->type != TYPE_LIST) + return; + + for(int i = 0; i < len; i++) + symbolStrings[i] = itemAt(form, i)->name; +} + +struct Environment envForLambda(const Object *params, const Object *arg_forms, + struct Environment *outer) +{ + printf("\n#####################\nenvForLambda()\n"); + printObj(arg_forms); + struct Environment env; + env.outer = outer; + env.strings = NULL; + env.objects = NULL; + + int length = listLength(params); + + if(length == 0) + return env; + + env.strings = calloc(sizeof(char*), length); + env.objects = malloc(sizeof(Object) * length); + + Object vs[length]; + eval_forms(vs, arg_forms, outer); + + for(int i = 0; i < length; i++) { + const char *n = itemAt(params, i)->name; + addToEnv(&env, n, eval(&arg_forms[i], outer)); // May not need eval? + } // Something is segfaulting, anyway + env.strings[length] = NULL; + + printf("envForLambda env IT BROKE HERE()\n"); + printf("envForLambda length=%d\n", length); + printEnv(&env); + printf("END envForLambda()\n\n"); + return env; +} + +Object evalBuiltIns(const Object *first, const Object *rest, struct Environment *env) { if(strcmp(first->name, "def") == 0) { - *found = 0; return evalDefArgs(rest, env); }else if(strcmp(first->name, "if") == 0) { - *found = 0; return evalIfArgs(rest, env); + }else if(strcmp(first->name, "fn") == 0) { + // printf("EVALBUILTINS first:\n"); + // printObj(first); + // printf("\nEVALBUILTINS rest:\n"); + // printObj(rest); + return evalLambdaArgs(rest); } - Object o; - *found = -1; - return o; + return errorObject(BUILT_IN_NOT_FOUND); +} + +void eval_forms(Object *destList, const Object *src, struct Environment *env) +{ + int length = listLength(src) - 1; // Not counting first_form + for(int i = 0; i < length; i++) { // Evaluates all in list + destList[i] = eval(itemAt(src, i + 1), env); // Skip the first + } } Object eval(const Object *obj, struct Environment *env) { - // printf("eval(): "); - // printObj(obj); - Object o = *obj; + printf("eval():\n"); + printObj(obj); switch(obj->type) { case TYPE_NUMBER: case TYPE_BOOL: - return o; + return *obj; case TYPE_SYMBOL: - o = fetchFromEnvironment(obj->name, env); - printf("fetched object '%s':\n", obj->name); - printObj(&o); - return o; + return fetchFromEnvironment(obj->name, env); case TYPE_LIST: { - if(listLength(obj) == 1) { - o = *obj->list; - return o; + if(listLength(obj) == 0) { + printf("empty list\n"); return *obj; } - Object first_form = *obj->list; + + if(listLength(obj) == 1) + return eval(obj->list, env); + + Object *first_form = obj->list; { // Try to eval built-ins - int i = -1; Object built_in = - evalBuiltIns(&first_form, first_form.forward, &i, env); + evalBuiltIns(first_form, first_form->forward, env); - if(i == 0) + if(built_in.type != TYPE_ERROR) return built_in; } - printf("\nNo built-ins found\n"); - Object first_eval = eval(&first_form, env); - Object arg1 = eval(first_form.forward, env); - Object arg2 = eval(first_form.forward->forward, env); + Object first_eval = eval(first_form, env); + if(first_eval.type == TYPE_FUNC) { + int length = listLength(obj) - 1; // Not counting first_form + Object rest[length]; + eval_forms(rest, obj, env); - printf("Evaluating func\n"); - Object func_eval = first_eval.func(arg1, arg2); - deleteList(obj); - return func_eval; + printf("Evaluating func\n"); + Object func_eval = first_eval.func(rest[0], rest[1]); + // deleteList(obj); + return func_eval; + } else if (first_eval.type == TYPE_LAMBDA) { + printf("lammy\n"); + struct Environment newEnv = + envForLambda(&first_eval.lambda->params, first_form->forward, env); + return eval(&first_eval.lambda->body, &newEnv); + } else { + return errorObject(TYPE_LIST_NOT_CAUGHT); + } + } + case TYPE_LAMBDA: + { + Object o; + o.type = TYPE_ERROR; + printf("UNEXPECTED FORM\n"); + return o; } default: ; } - return o; + return *obj; } Result resultFromObjAndSlices(Object obj, struct Slice *slices) @@ -206,6 +294,20 @@ void addToEnv(struct Environment *env, const char *name, const Object obj) env->objects[i] = obj; break; } + if(strcmp(env->strings[i], name) == 0) { + env->objects[i] = obj; + break; + } + } +} + +void printEnv(struct Environment *env) +{ + for(int i = 0; i < MAX_ENV_ELM; i++) { + if(env->strings[i] == NULL) + return; + printf("env[%d]: '%s'\n ", i, env->strings[i]); + printObj(&env->objects[i]); } } @@ -290,6 +392,7 @@ void deleteEnv(struct Environment *e) struct Environment defaultEnv() { struct Environment e; + e.outer = NULL; e.strings = malloc(sizeof(char*) * MAX_ENV_ELM); for(int i = 0; i < MAX_ENV_ELM; i++) { e.strings[i] = NULL; @@ -317,11 +420,15 @@ Object parseEval(const char *input, struct Environment *env) while(debug->text) { char tok[MAX_TOK_LEN]; copySlice(tok, debug); + //printf("slice: '%s'\n", tok); debug++; } } #endif Object parsed = parse(tokens).obj; + // printf("PARSEEVAL() PRINTLIST():\n"); + // printObj(&parsed); + // printf("end PARSEEVAL() PRINTLIST():\n\n"); free(tokens); return eval(&parsed, env); } @@ -335,7 +442,7 @@ int repl(struct Environment *env) fgets(input, 100, stdin); Object obj = parseEval(input, env); printObj(&obj); - //break; + // printEnv(env); } } diff --git a/src/pebblisp.h b/src/pebblisp.h index ffd575e..59ffdb9 100644 --- a/src/pebblisp.h +++ b/src/pebblisp.h @@ -19,6 +19,7 @@ typedef struct Result { struct Environment { char **strings; Object *objects; + struct Environment *outer; }; Object eval(const Object *obj, struct Environment *env); @@ -27,9 +28,13 @@ Result readSeq(struct Slice *slices); Object parseAtom(struct Slice *slice); void copySlice(char * dest, struct Slice *src); Object parseEval(const char *input, struct Environment *env); +void eval_forms(Object *destList, const Object *src, struct Environment *env); + struct Environment defaultEnv(); void deleteEnv(struct Environment *e); void addToEnv(struct Environment *env, const char *name, const Object obj); +Object fetchFromEnvironment(const char *name, struct Environment *env); +void printEnv(struct Environment *env); Result resultFromObjAndSlices(Object obj, struct Slice *slices); Object add(Object obj1, Object obj2); diff --git a/src/tags b/src/tags index 09ae243..bf39104 100644 --- a/src/tags +++ b/src/tags @@ -4,19 +4,23 @@ !_TAG_PROGRAM_NAME Exuberant Ctags // !_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/ !_TAG_PROGRAM_VERSION 5.9~svn20110310 // +BAD_LIST_OF_SYMBOL_STRINGS object.h /^ BAD_LIST_OF_SYMBOL_STRINGS,$/;" e enum:errorCode +BUILT_IN_NOT_FOUND object.h /^ BUILT_IN_NOT_FOUND$/;" e enum:errorCode CALC_H calc.h 2;" d CODE_PKEY calc.h 11;" d END_PHRASE calc.h 9;" d Environment pebblisp.h /^struct Environment {$/;" s +Lambda object.h /^struct Lambda {$/;" s MAX_ENV_ELM object.h 6;" d MAX_LENGTH calc.h 8;" d MAX_TOK_CNT object.h 5;" d MAX_TOK_LEN object.h 4;" d +NULL_ENV object.h /^ NULL_ENV,$/;" e enum:errorCode OBJECT_H object.h 2;" d Object object.h /^struct Object {$/;" s Object object.h /^typedef struct Object Object;$/;" t typeref:struct:Object PEBBLISP_H pebblisp.h 2;" d -R pebblisp.h 41;" d +R pebblisp.h 45;" d Result pebblisp.h /^typedef struct Result {$/;" s Result pebblisp.h /^} Result;$/;" t typeref:struct:Result SMAX_LENGTH calc.h 7;" d @@ -24,9 +28,11 @@ Slice pebblisp.h /^struct Slice {$/;" s TOKENS_H tokens.h 2;" d TOKEN_END calc.h 42;" d TYPE_BOOL object.h /^ TYPE_BOOL,$/;" e enum:Type -TYPE_ERROR object.h /^ TYPE_ERROR$/;" e enum:Type +TYPE_ERROR object.h /^ TYPE_ERROR \/\/ Currently unused$/;" e enum:Type TYPE_FUNC object.h /^ TYPE_FUNC,$/;" e enum:Type +TYPE_LAMBDA object.h /^ TYPE_LAMBDA,$/;" e enum:Type TYPE_LIST object.h /^ TYPE_LIST,$/;" e enum:Type +TYPE_LIST_NOT_CAUGHT object.h /^ TYPE_LIST_NOT_CAUGHT,$/;" e enum:errorCode TYPE_NUMBER object.h /^ TYPE_NUMBER,$/;" e enum:Type TYPE_SYMBOL object.h /^ TYPE_SYMBOL,$/;" e enum:Type Type object.h /^typedef enum Type {$/;" g @@ -36,9 +42,11 @@ addToEnv pebblisp.c /^void addToEnv(struct Environment *env, const char *name, c addToList object.c /^void addToList(Object *dest, const Object src)$/;" f back_handler calc.c /^static void back_handler(ClickRecognizerRef recognizer, void *context) {$/;" f file: basicOp pebblisp.c /^Object basicOp(Object *obj1, Object *obj2, const char op)$/;" f -bopf pebblisp.c 264;" d file: +body object.h /^ Object body;$/;" m struct:Lambda +bopf pebblisp.c 365;" d file: calculate calc.c /^static void calculate(){$/;" f file: click_config_provider calc.c /^static void click_config_provider(void *context) {$/;" f file: +copyList object.c /^void copyList(Object *dest, const Object *src)$/;" f copySlice pebblisp.c /^void copySlice(char * dest, struct Slice *src)$/;" f debugSlice pebblisp.c /^void debugSlice(struct Slice *s)$/;" f defaultEnv pebblisp.c /^struct Environment defaultEnv() {$/;" f @@ -47,10 +55,16 @@ deleteEnv pebblisp.c /^void deleteEnv(struct Environment *e)$/;" f deleteList object.c /^void deleteList(const Object *dest)$/;" f enter calc.c /^static void enter(){$/;" f file: env calc.h /^static struct Environment env;$/;" v typeref:struct:Environment +envForLambda pebblisp.c /^struct Environment envForLambda(const Object *params, const Object *arg_forms,$/;" f +err object.h /^ enum errorCode err;$/;" m union:Object::__anon1 typeref:enum:Object::__anon1::errorCode +errorCode object.h /^enum errorCode {$/;" g +errorObject object.c /^inline Object errorObject(enum errorCode err)$/;" f eval pebblisp.c /^Object eval(const Object *obj, struct Environment *env)$/;" f -evalBuiltIns pebblisp.c /^Object evalBuiltIns(const Object *first, const Object *rest, int *found,$/;" f +evalBuiltIns pebblisp.c /^Object evalBuiltIns(const Object *first, const Object *rest,$/;" f evalDefArgs pebblisp.c /^Object evalDefArgs(const Object *arg_forms, struct Environment *env)$/;" f evalIfArgs pebblisp.c /^Object evalIfArgs(const Object *arg_forms, struct Environment *env)$/;" f +evalLambdaArgs pebblisp.c /^Object evalLambdaArgs(const Object *arg_forms, struct Environment *env)$/;" f +eval_forms pebblisp.c /^void eval_forms(Object *destList, const Object *src, struct Environment *env)$/;" f fetchFromEnvironment pebblisp.c /^Object fetchFromEnvironment(const char *name, struct Environment *env)$/;" f forward object.h /^ Object *forward;$/;" m struct:Object func object.h /^ Object (*func)(Object, Object);$/;" m union:Object::__anon1 @@ -59,6 +73,9 @@ init calc.c /^static void init(void) {$/;" f file: isDigit tokens.c /^int isDigit(const char c) {$/;" f isSingle tokens.c /^int isSingle(const char c) {$/;" f isWhitespace tokens.c /^int isWhitespace(const char c) {$/;" f +itemAt object.c /^Object *itemAt(const Object *listObj, int n)$/;" f +lambda object.h /^ struct Lambda *lambda; \/\/ Maybe better as not a pointer$/;" m union:Object::__anon1 typeref:struct:Object::__anon1::Lambda +lambdaObject object.c /^inline Object lambdaObject()$/;" f length pebblisp.h /^ char length;$/;" m struct:Slice list object.h /^ Object *list;$/;" m union:Object::__anon1 listLength object.c /^int listLength(const Object *listObj)$/;" f @@ -73,9 +90,13 @@ number object.h /^ int number;$/;" m union:Object::__anon1 numberObject object.c /^inline Object numberObject(int num)$/;" f obj pebblisp.h /^ Object obj;$/;" m struct:Result objects pebblisp.h /^ Object *objects;$/;" m struct:Environment +outer pebblisp.h /^ struct Environment *outer;$/;" m struct:Environment typeref:struct:Environment::Environment +params object.h /^ Object params;$/;" m struct:Lambda parse pebblisp.c /^Result parse(struct Slice *slices)$/;" f parseAtom pebblisp.c /^Object parseAtom(struct Slice *s)$/;" f parseEval pebblisp.c /^Object parseEval(const char *input, struct Environment *env)$/;" f +parseListOfSymbolStrings pebblisp.c /^void parseListOfSymbolStrings(const Object *form, const char **symbolStrings,$/;" f +printEnv pebblisp.c /^void printEnv(struct Environment *env)$/;" f printList object.c /^void printList(const Object *list)$/;" f printObj object.c /^void printObj(const Object *obj)$/;" f printf object.c 7;" d file: