Busted `map` with less malloc

This commit is contained in:
= 2020-05-08 01:32:01 +01:00
parent 4bc3337dcd
commit a286943984
7 changed files with 245 additions and 110 deletions

View File

@ -3,3 +3,6 @@ all:
debug: debug:
gcc -g -O0 -o pebblisp -D STANDALONE -D DEBUG pebblisp.c tokens.c object.c gcc -g -O0 -o pebblisp -D STANDALONE -D DEBUG pebblisp.c tokens.c object.c
phrase:
gcc -g -O0 -o pebblisp -D STANDALONE -D DEBUG -D NO_REPL pebblisp.c tokens.c object.c

View File

@ -1,6 +1,5 @@
#include <stdio.h> #include <stdio.h>
#include <limits.h> #include <limits.h>
//#include "fixed.h"
#include "calc.h" #include "calc.h"
static inline int8_t tokenCount() { static inline int8_t tokenCount() {
@ -71,10 +70,10 @@ static void enter(){
// Calculate result, display it and reset // Calculate result, display it and reset
static void calculate(){ static void calculate(){
Object obj = parseEval(mytext, &env); Object obj = parseEval(mytext, &env);
char temp[MAX_LENGTH-2] = ""; char temp[RESULT_LENGTH-2] = "";
stringObj(temp, &obj); stringObj(temp, &obj);
snprintf(resulttext, MAX_LENGTH, "R:%s", temp); snprintf(resulttext, RESULT_LENGTH, "R:%s", temp);
selected_token = 0; selected_token = 0;
text_layer_set_text(s_result_text_layer, resulttext); text_layer_set_text(s_result_text_layer, resulttext);
} }
@ -191,6 +190,14 @@ void code_window_load(Window *window)
window_stack_push(s_code_window, true); window_stack_push(s_code_window, true);
// If possible, load the previous code text // If possible, load the previous code text
Object obj = parseEval("(def ad (fn (a) (+ 1 a)))", &env);
Object obj2 = parseEval("(map ad (1 2 3))", &env);
printObj(&obj);
printObj(&obj2);
cleanObject(&obj);
cleanObject(&obj2);
if(1)
return;
if(persist_exists(current_code)) { if(persist_exists(current_code)) {
persist_read_string(current_code, mytext, SMAX_LENGTH); persist_read_string(current_code, mytext, SMAX_LENGTH);
updateText(); updateText();

View File

@ -5,7 +5,7 @@
#include "pebblisp.h" #include "pebblisp.h"
#define SMAX_LENGTH 256 #define SMAX_LENGTH 256
#define MAX_LENGTH 11 #define RESULT_LENGTH 20
#define END_PHRASE "END" #define END_PHRASE "END"
#define NUM_ROWS 5 #define NUM_ROWS 5
@ -33,7 +33,7 @@ char mytext[SMAX_LENGTH] = "";
char temptext[SMAX_LENGTH] = ""; char temptext[SMAX_LENGTH] = "";
// The result of execution // The result of execution
char resulttext[MAX_LENGTH] = ""; char resulttext[RESULT_LENGTH] = "";
char *tokens[] = { char *tokens[] = {
" ", "(", ")", " ", "(", ")",
@ -43,7 +43,7 @@ char *tokens[] = {
"7","8","9", "0", "7","8","9", "0",
"a", "b", "c", "d", "e", "a", "b", "c", "d", "e",
"= ", "< ", "> ", "= ", "< ", "> ",
"fn", "def", "if", "\n", "map", "fn", "def", "if", "\n",
END_PHRASE END_PHRASE
}; };

View File

@ -3,6 +3,8 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#define RESULT_LENGTH 20
#ifdef DEBUG #ifdef DEBUG
#define printd(...) printf(__VA_ARGS__) #define printd(...) printf(__VA_ARGS__)
#else #else
@ -10,7 +12,9 @@
#endif #endif
#ifndef STANDALONE #ifndef STANDALONE
#define printf(...) stringObj(NULL, NULL) #include <pebble.h>
#undef printf
#define printf(...) APP_LOG(APP_LOG_LEVEL_DEBUG, __VA_ARGS__)
#endif #endif
int listLength(const Object *listObj) int listLength(const Object *listObj)
@ -126,8 +130,16 @@ void insertIntoList(Object *dest, int ind, const Object src)
march->forward->forward = oldForward; march->forward->forward = oldForward;
} }
void replaceListing(Object *list, int i, const Object src)
{
if(!list)
return;
list[i] = src;
list[i].forward = NULL;
}
// Adds an object to the end of a list object // Adds an object to the end of a list object
void addToList(Object *dest, const Object src) void nf_addToList(Object *dest, const Object src)
{ {
if(!dest || dest->type != TYPE_LIST) if(!dest || dest->type != TYPE_LIST)
return; return;
@ -143,38 +155,57 @@ void addToList(Object *dest, const Object src)
void printErr(const Object *obj) void printErr(const Object *obj)
{ {
#ifdef STANDALONE //#ifdef STANDALONE
if(!obj || obj->type != TYPE_ERROR) if(!obj || obj->type != TYPE_ERROR)
return; return;
printf("%s\n", errorText[(int)(obj->err)]); printf("%s\n", errorText[(int)(obj->err)]);
#endif //#endif
return; return;
} }
void stringList(char *dest, const Object *obj)
{
dest[0] = '(';
dest[1] = '\0';
const Object *tail = obj->list;
while(tail != NULL) {
printf("%s\n", dest);
strcat(dest, " ");
char tok[90] = "";
stringObj(tok, tail);
strcat(dest, tok);
tail = tail->forward;
}
strcat(dest, " )");
}
// Puts a string version of the given object into a given string // Puts a string version of the given object into a given string
char* stringObj(char *dest, const Object *obj) char* stringObj(char *dest, const Object *obj)
{ {
if(!dest || !obj) if(!dest || !obj)
return NULL; return NULL;
if(obj->type == TYPE_NUMBER) { const Type t = obj->type;
snprintf(dest, MAX_TOK_LEN, "%d", obj->number);
} else if(obj->type == TYPE_SYMBOL) { if(t == TYPE_NUMBER) {
snprintf(dest, MAX_TOK_LEN, "%s", obj->name); snprintf(dest, RESULT_LENGTH, "%d", obj->number);
} else if(obj->type == TYPE_BOOL) { } else if(t == TYPE_SYMBOL) {
snprintf(dest, MAX_TOK_LEN, "%s", obj->number ? "T" : "F"); snprintf(dest, RESULT_LENGTH, "%s", obj->name);
} else if(obj->type == TYPE_ERROR) { } else if(t == TYPE_BOOL) {
snprintf(dest, MAX_TOK_LEN, "E%d", obj->err); snprintf(dest, RESULT_LENGTH, "%s", obj->number ? "T" : "F");
} else if(t == TYPE_ERROR) {
snprintf(dest, RESULT_LENGTH, "E%d", obj->err);
} else if(t == TYPE_LIST) {
stringList(dest, obj);
} else { } else {
snprintf(dest, MAX_TOK_LEN, "%d", obj->number); snprintf(dest, RESULT_LENGTH, "%d", obj->number);
} }
return dest; return dest;
} }
int depth = 0;
void debugObj(const Object *obj) void debugObj(const Object *obj)
{ {
#ifdef DEBUG #ifdef DEBUG
@ -186,38 +217,28 @@ void debugObj(const Object *obj)
void _printList(const Object *list, int newline); void _printList(const Object *list, int newline);
void _printObj(const Object *obj, int newline) void _printObj(const Object *obj, int newline)
{ {
for(int i = 0; i < depth; i++)
printd(" ");
depth++;
if(obj->type == TYPE_NUMBER) { if(obj->type == TYPE_NUMBER) {
printd("TYPE_NUMBER"); printd("TYPE_NUMBER");
} else if(obj->type == TYPE_BOOL) { } else if(obj->type == TYPE_BOOL) {
printd("TYPE_BOOL"); printd("TYPE_BOOL");
} else if(obj->type == TYPE_LIST) { } else if(obj->type == TYPE_LIST) {
printd("TYPE_LIST\n"); printd("TYPE_LIST\n");
_printList(obj, newline);
depth--;
return;
} else if(obj->type == TYPE_FUNC) { } else if(obj->type == TYPE_FUNC) {
printd("TYPE_FUNC"); printd("TYPE_FUNC");
} else if(obj->type == TYPE_SYMBOL) { } else if(obj->type == TYPE_SYMBOL) {
printd("TYPE_SYMBOL"); printd("TYPE_SYMBOL");
} else if(obj->type == TYPE_LAMBDA) { } else if(obj->type == TYPE_LAMBDA) {
printd("TYPE_LAMBDA Params:\n"); printd("TYPE_LAMBDA Params:\n");
depth++;
printObj(&obj->lambda->params); printObj(&obj->lambda->params);
for(int i = 1; i < depth; i++)
printf(" ");
printd("Lambda Body: \n"); printd("Lambda Body: \n");
printObj(&obj->lambda->body); printObj(&obj->lambda->body);
return;
} else if(obj->type == TYPE_ERROR) { } else if(obj->type == TYPE_ERROR) {
printd("TYPE_ERROR: "); printd("TYPE_ERROR: ");
} else { } else {
printd("TYPE_OTHER (as int)"); printd("TYPE_OTHER (as int)");
} }
depth--; char temp[100] = "";
char temp[20] = "";
stringObj(temp, obj); stringObj(temp, obj);
if(newline) if(newline)
printf("%s\n", temp); printf("%s\n", temp);
@ -238,9 +259,7 @@ void _printList(const Object *list, int newline)
const Object *tail = list->list; const Object *tail = list->list;
while(tail != NULL) { while(tail != NULL) {
printf(" "); printf(" ");
depth++;
_printObj(tail, 0); _printObj(tail, 0);
depth--;
tail = tail->forward; tail = tail->forward;
} }
printf(" )"); printf(" )");
@ -261,12 +280,20 @@ void cleanObject(Object *target)
const Type t = target->type; const Type t = target->type;
if(t == TYPE_LAMBDA) { if(t == TYPE_LAMBDA) {
cleanObject(&target->lambda->params);
cleanObject(&target->lambda->body);
free(target->lambda); free(target->lambda);
} else if(t == TYPE_LIST) { } else if(t == TYPE_LIST) {
deleteList(target); deleteList(target);
} }
} }
void printAndClean(Object *target)
{
printObj(target);
cleanObject(target);
}
// Frees all objects in a list // Frees all objects in a list
void deleteList(const Object *dest) void deleteList(const Object *dest)
{ {
@ -297,7 +324,7 @@ void copyList(Object *dest, const Object *src)
deleteList(dest); deleteList(dest);
const Object *march = src->list; const Object *march = src->list;
while(march != NULL) { while(march != NULL) {
addToList(dest, *march); nf_addToList(dest, *march);
march = march->forward; march = march->forward;
} }
} }

View File

@ -12,24 +12,30 @@ enum errorCode {
BUILT_IN_NOT_FOUND, BUILT_IN_NOT_FOUND,
NULL_PARSE, NULL_PARSE,
NULL_LAMBDA_LIST, NULL_LAMBDA_LIST,
NULL_MAP_ARGS,
LAMBDA_ARGS_NOT_LIST, LAMBDA_ARGS_NOT_LIST,
DID_NOT_FIND_SYMBOL, DID_NOT_FIND_SYMBOL,
BAD_TYPE,
UNEXPECTED_FORM UNEXPECTED_FORM
}; };
#ifdef STANDALONE //#ifdef STANDALONE
static const char *errorText[] = { static const char *errorText[] = {
"BAD_LIST_OF_SYMBOL_STRINGS", "BAD_LIST_OF_SYMBOL_STRINGS",
"TYPE_LIST_NOT_CAUGHT", "TYPE_LIST_NOT_CAUGHT",
"NULL_ENV", "NULL_ENV",
"BUILT_IN_NOT_FOUND", "BUILT_IN_NOT_FOUND",
"NULL_PARSE", "NULL_PARSE",
"NULL_LAMBDA_LIST", "NULL_LAMBDA_LIST",
"LAMBDA_ARGS_NOT_LIST", "NULL_MAP_ARGS",
"DID_NOT_FIND_SYMBOL", "LAMBDA_ARGS_NOT_LIST",
"UNEXPECTED_FORM" "DID_NOT_FIND_SYMBOL",
}; "BAD_TYPE",
#endif "UNEXPECTED_FORM"
};
//#endif
#define MALLOC_FLAG 64
typedef enum Type { typedef enum Type {
TYPE_NUMBER, TYPE_NUMBER,
@ -38,7 +44,7 @@ typedef enum Type {
TYPE_FUNC, TYPE_FUNC,
TYPE_SYMBOL, TYPE_SYMBOL,
TYPE_LAMBDA, TYPE_LAMBDA,
TYPE_ERROR // Currently unused TYPE_ERROR
} Type; } Type;
typedef struct Object Object; typedef struct Object Object;
@ -67,16 +73,21 @@ char* stringObj(char *dest, const Object *obj);
void printList(const Object *list); 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);
int wasMalloc(const Object *obj);
int getType(const Object *obj);
int isEmpty(const Object *obj); int isEmpty(const Object *obj);
Object *tail(const Object *listObj); Object *tail(const Object *listObj);
void addToList(Object *dest, Object src); void replaceListing(Object *list, int i, const Object src);
void nf_addToList(Object *dest, Object src);
void deleteList(const Object *dest); void deleteList(const Object *dest);
int listLength(const Object *listObj); int listLength(const Object *listObj);
Object *itemAt(const Object *listObj, int n); Object *itemAt(const Object *listObj, int n);
void copyList(Object *dest, const Object *src); void copyList(Object *dest, const Object *src);
void cleanObject(Object *target); void cleanObject(Object *target);
void printAndClean(Object *target);
void allocObject(Object **spot, const Object src); void allocObject(Object **spot, const Object src);
Object newObject(Type type); Object newObject(Type type);

View File

@ -4,6 +4,11 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#ifndef STANDALONE
#undef printf
#define printf(...) APP_LOG(APP_LOG_LEVEL_DEBUG, __VA_ARGS__)
#endif
void copySlice(char * dest, struct Slice *src) void copySlice(char * dest, struct Slice *src)
{ {
if(!dest || !src) if(!dest || !src)
@ -29,14 +34,12 @@ Object fetchFromEnvironment(const char *name, struct Environment *env)
printd("Fetching '%s' from env\n", name); printd("Fetching '%s' from env\n", name);
printEnv(env); printEnv(env);
int i = 0; for(int i = 0; i < env->size; i++) {
const char *next = env->strings[i]; if(strcmp(name, env->strings[i]) == 0) {
while(next != NULL) {
if(strcmp(name, next) == 0) {
return env->objects[i]; return env->objects[i];
} }
next = env->strings[++i];
} }
printd("Trying outer\n"); printd("Trying outer\n");
if(env->outer) { if(env->outer) {
return fetchFromEnvironment(name, env->outer); return fetchFromEnvironment(name, env->outer);
@ -52,14 +55,14 @@ Result parse(struct Slice *slices)
if(token->text != NULL) { if(token->text != NULL) {
rest = &slices[1]; rest = &slices[1];
} else { } else {
return R(errorObject(NULL_PARSE), NULL); return result(errorObject(NULL_PARSE), NULL);
} }
if(token->text[0] == '(') { if(token->text[0] == '(') {
// todo check for null rest // todo check for null rest
return readSeq(rest); return readSeq(rest);
} else { // todo error on closed paren } else { // todo error on closed paren
return R(parseAtom(token), rest); return result(parseAtom(token), rest);
} }
} }
@ -70,10 +73,10 @@ Result readSeq(struct Slice *tokens)
struct Slice *next = &tokens[0]; struct Slice *next = &tokens[0];
struct Slice *rest = next->text? &next[1] : NULL; struct Slice *rest = next->text? &next[1] : NULL;
if(next->text[0] == ')') { if(next->text[0] == ')') {
return R(res, rest); return result(res, rest);
} }
Result r = parse(tokens); Result r = parse(tokens);
addToList(&res, r.obj); nf_addToList(&res, r.obj);
tokens = r.slices; tokens = r.slices;
} }
} }
@ -126,37 +129,100 @@ Object evalLambdaArgs(const Object *arg_forms)
return constructLambda(arg_forms, arg_forms->forward); return constructLambda(arg_forms, arg_forms->forward);
} }
Object evalMapArgs(const Object *arg_forms) //Object evalMapArgs(Object *newList, const Object *arg_forms,
void evalMapArgs(Object *newList, const Object *arg_forms,
struct Environment *env)
{ {
return listObject(); if(!arg_forms)
return; // errorObject(NULL_MAP_ARGS);
const Object lambda = eval(&arg_forms[0], env);
Object *oldList = (&arg_forms[0])->forward;
printf("lambda\n");
printObj(&lambda);
printf("oldList\n");
printObj(oldList);
printf("END oldList\n");
if(lambda.type != TYPE_LAMBDA || oldList->type != TYPE_LIST) {
return; // errorObject(BAD_TYPE);
}
// Object list = listObject();
int i = 0;
Object *oldElement = oldList->list;
while(oldElement != NULL) {
// Create a new list for each element in the list,
// since lambda evaluation looks for a list
Object tempList = listObject();
Object listBack[1] = {*oldElement};
listBack[0].forward = NULL;
tempList.list = listBack;
printObj(&tempList);
printf("END &tempList\n");
//nf_addToList(&tempList, *oldElement);
struct Environment newEnv =
envForLambda(&lambda.lambda->params, &tempList, env);
const Object evalLambda = eval(&lambda.lambda->body, &newEnv);
// cleanObject(&tempList); // Don't let tempList linger
//nf_addToList(&list, evalLambda);
newList[i++] = evalLambda;
printf("VVVVVVnewList[%d]\n", i - 1);
printObj(&newList[i-1]);
printf("^^^^^^newList[%d]\n", i - 1);
oldElement = oldElement->forward;
}
for(int j = 0; j < i - 1; j++) {
newList[j].forward = &newList[j+1];
}
newList[i-1].forward = NULL;
//printf("return list\n");
//return list;
} }
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("\n#####################\nenvForLambda()\n"); printd("\n#####################");
printf("envForLambda()\n");
debugObj(arg_forms); debugObj(arg_forms);
int length = listLength(params);
struct Environment env; struct Environment env;
env.outer = outer; env.outer = outer;
env.strings = NULL; env.strings = NULL;
env.objects = NULL; env.objects = NULL;
env.size = length;
int length = listLength(params);
if(length == 0) if(length == 0)
return env; return env;
env.strings = calloc(sizeof(char*), length); env.strings = calloc(sizeof(char*), length + 1);
env.objects = malloc(sizeof(Object) * length); env.objects = malloc(sizeof(Object) * length + 1);
Object vs[length]; Object vs[length];
eval_forms(vs, arg_forms, outer); eval_forms(vs, arg_forms, outer);
printf("WHICH/ONE\n");
for(int i = 0; i < length; i++) {
//printObj(&vs[i]);
printObj(&arg_forms[i]);
}
printf("END WHICH/ONE\n");
for(int i = 0; i < length; i++) { for(int i = 0; i < length; i++) {
const char *n = itemAt(params, i)->name; const char *n = itemAt(params, i)->name;
addToEnv(&env, n, eval(&arg_forms[i], outer)); // May not need eval? addToEnv(&env, n, eval(&arg_forms[i], outer)); // May not need eval?
// SHOULD BE `vs` not arg_forms???
} // Something is segfaulting, anyway } // Something is segfaulting, anyway
env.strings[length] = NULL; // env.strings[length] = NULL;
printd("envForLambda env IT BROKE HERE()\n"); printd("envForLambda env IT BROKE HERE()\n");
printd("envForLambda length=%d\n", length); printd("envForLambda length=%d\n", length);
@ -174,8 +240,17 @@ Object evalBuiltIns(const Object *first, const Object *rest,
return evalIfArgs(rest, env); return evalIfArgs(rest, env);
} else if(strcmp(first->name, "fn") == 0) { } else if(strcmp(first->name, "fn") == 0) {
return evalLambdaArgs(rest); return evalLambdaArgs(rest);
} else if(strcmp(first->name, "mp") == 0) { } else if(strcmp(first->name, "map") == 0) {
return evalMapArgs(rest); printf("MAP BUILT-IN\n");
int length = listLength(rest->forward);
Object newList = listObject();
//Object listBack[length];
//newList.list = listBack;
evalMapArgs(listBack, rest, env);
printf("print evalMapArgs() obj\n");
printObj(&newList);
printf("MAP BUILT-IN\n");
return newList;
} }
return errorObject(BUILT_IN_NOT_FOUND); return errorObject(BUILT_IN_NOT_FOUND);
@ -191,7 +266,7 @@ void eval_forms(Object *destList, const Object *src, struct Environment *env)
Object eval(const Object *obj, struct Environment *env) Object eval(const Object *obj, struct Environment *env)
{ {
printd("eval():\n"); printf("eval():\n");
debugObj(obj); debugObj(obj);
switch(obj->type) { switch(obj->type) {
case TYPE_NUMBER: case TYPE_NUMBER:
@ -216,8 +291,9 @@ Object eval(const Object *obj, struct Environment *env)
evalBuiltIns(first_form, first_form->forward, env); evalBuiltIns(first_form, first_form->forward, env);
// deleteList(obj); // Decreases indirectly lost memory, but fails on Pebble // deleteList(obj); // Decreases indirectly lost memory, but fails on Pebble
if(built_in.type != TYPE_ERROR) if(built_in.type != TYPE_ERROR) {
return built_in; return built_in;
}
} }
Object first_eval = eval(first_form, env); Object first_eval = eval(first_form, env);
@ -236,7 +312,9 @@ Object eval(const Object *obj, struct Environment *env)
} else if (first_eval.type == TYPE_LAMBDA) { } else if (first_eval.type == TYPE_LAMBDA) {
struct Environment newEnv = struct Environment newEnv =
envForLambda(&first_eval.lambda->params, first_form->forward, env); envForLambda(&first_eval.lambda->params, first_form->forward, env);
return eval(&first_eval.lambda->body, &newEnv); Object ret = eval(&first_eval.lambda->body, &newEnv);
deleteEnv(&newEnv);
return ret;
} else { } else {
return *obj; return *obj;
@ -251,31 +329,47 @@ Object eval(const Object *obj, struct Environment *env)
return *obj; return *obj;
} }
Result resultFromObjAndSlices(Object obj, struct Slice *slices) Result result(Object obj, struct Slice *slices)
{ {
Result r; return (Result) {
r.obj = obj; .obj = obj,
r.slices = slices; .slices = slices
return r; };
} }
// todo could include and return a starting index for faster multi-adds // todo could include and return a starting index for faster multi-adds
// Maybe extend existing environment using a malloc'd outer, instead of realloc
void addToEnv(struct Environment *env, const char *name, const Object obj) void addToEnv(struct Environment *env, const char *name, const Object obj)
{ {
int i; int i;
for(i = 0; i < MAX_ENV_ELM; i++) { //printf("sizeof(char)=%d * strlen(name)=%d\n", (int)sizeof(char), (int)strlen(name));
for(i = 0; i < env->size ; i++) {
if(env->strings[i] == NULL) { if(env->strings[i] == NULL) {
env->strings[i] = malloc(sizeof(name)); env->strings[i] = malloc(strlen(name) + 1);
strncpy(env->strings[i], name, MAX_TOK_LEN); strncpy(env->strings[i], name, strlen(name));
env->objects[i] = obj; env->objects[i] = obj;
break; return;
} }
if(strcmp(env->strings[i], name) == 0) { if(strcmp(env->strings[i], name) == 0) {
cleanObject(&env->objects[i]); cleanObject(&env->objects[i]);
env->objects[i] = obj; env->objects[i] = obj;
break; return;
} }
} }
printd("Reallocating environment\n");
const int inc = 5;
env->size += inc;
env->strings = realloc(env->strings, sizeof(char*) * env->size);
env->objects = realloc(env->objects, sizeof(Object) * env->size);
for(int j = 0; j < inc; j++) {
env->strings[i + j] = NULL;
}
env->strings[i] = malloc(strlen(name) + 1);
strncpy(env->strings[i], name, strlen(name));
env->objects[i] = obj;
} }
void printEnv(struct Environment *env) void printEnv(struct Environment *env)
@ -284,7 +378,7 @@ void printEnv(struct Environment *env)
printd("NULL env\n"); printd("NULL env\n");
return; return;
} }
for(int i = 0; i < MAX_ENV_ELM; i++) { for(int i = 0; i < env->size; i++) {
if(env->strings[i] == NULL) if(env->strings[i] == NULL)
return; return;
printd("env[%d]: '%s'\n ", i, env->strings[i]); printd("env[%d]: '%s'\n ", i, env->strings[i]);
@ -345,6 +439,7 @@ void deleteEnv(struct Environment *e)
int i = 0; int i = 0;
while(e->strings[i]) { while(e->strings[i]) {
free(e->strings[i]); free(e->strings[i]);
cleanObject(&e->objects[i]);
i++; i++;
} }
free(e->strings); free(e->strings);
@ -357,10 +452,11 @@ void deleteEnv(struct Environment *e)
struct Environment defaultEnv() { struct Environment defaultEnv() {
struct Environment e; struct Environment e;
e.outer = NULL; e.outer = NULL;
e.strings = malloc(sizeof(char*) * MAX_ENV_ELM); e.strings = calloc(sizeof(char*), MAX_ENV_ELM);
for(int i = 0; i < MAX_ENV_ELM; i++) { e.size = MAX_ENV_ELM;
e.strings[i] = NULL; // for(int i = 0; i < MAX_ENV_ELM; i++) {
} // e.strings[i] = NULL;
// }
e.objects = malloc(sizeof(Object) * MAX_ENV_ELM); e.objects = malloc(sizeof(Object) * MAX_ENV_ELM);
@ -391,7 +487,9 @@ Object parseEval(const char *input, struct Environment *env)
#endif #endif
Object parsed = parse(tokens).obj; Object parsed = parse(tokens).obj;
free(tokens); free(tokens);
return eval(&parsed, env); Object ret = eval(&parsed, env);
cleanObject(&parsed);
return ret;
} }
#ifdef STANDALONE #ifdef STANDALONE
@ -402,6 +500,7 @@ int repl(struct Environment *env)
printf("pebblisp>> "); printf("pebblisp>> ");
fgets(input, 100, stdin); fgets(input, 100, stdin);
Object obj = parseEval(input, env); Object obj = parseEval(input, env);
// printAndClean(&obj);
printObj(&obj); printObj(&obj);
// printEnv(env); // printEnv(env);
} }
@ -413,22 +512,10 @@ int main(void)
#ifndef NO_REPL #ifndef NO_REPL
repl(&env); repl(&env);
#else #else
struct Slice *tokens = nf_tokenize("(+ 10 5)"); Object r = parseEval("(def ad (fn (a) (+ 1 a)))", &env);
struct Slice *debug = tokens; printAndClean(&r);
r = parseEval("(map ad (1 2 3))", &env);
if(debug) { //printAndClean(&r);
while(debug->text) {
char tok[10];
copySlice(tok, debug);
printf("'%s', ", tok);
debug++;
}
printf("\n");
} else {
printf("parse error\n");
}
parse(tokens);
free(tokens);
#endif #endif
deleteEnv(&env); deleteEnv(&env);
} }

View File

@ -5,7 +5,6 @@
#ifndef STANDALONE #ifndef STANDALONE
#include <pebble.h> #include <pebble.h>
// #define printf(...) copySlice(NULL, NULL)
#define printd(...) copySlice(NULL, NULL) #define printd(...) copySlice(NULL, NULL)
#endif #endif
@ -29,6 +28,7 @@ struct Environment {
char **strings; char **strings;
Object *objects; Object *objects;
struct Environment *outer; struct Environment *outer;
char size;
}; };
Object eval(const Object *obj, struct Environment *env); Object eval(const Object *obj, struct Environment *env);
@ -46,14 +46,14 @@ void deleteEnv(struct Environment *e);
void addToEnv(struct Environment *env, const char *name, const Object obj); void addToEnv(struct Environment *env, const char *name, const Object obj);
Object fetchFromEnvironment(const char *name, struct Environment *env); Object fetchFromEnvironment(const char *name, struct Environment *env);
void printEnv(struct Environment *env); void printEnv(struct Environment *env);
struct Environment envForLambda(const Object *params, const Object *arg_forms,
struct Environment *outer);
Result resultFromObjAndSlices(Object obj, struct Slice *slices); Result result(Object obj, struct Slice *slices);
Object add(Object obj1, Object obj2); Object add(Object obj1, Object obj2);
// Slices // 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 R(_obj, _slices) resultFromObjAndSlices(_obj, _slices)
#endif #endif