diff --git a/src/calc.c b/src/calc.c index 20bccff..8307309 100644 --- a/src/calc.c +++ b/src/calc.c @@ -54,7 +54,7 @@ static int8_t selected_token = 1; const char* func_tokens[] = { "window ", "sc ", "cw ", "pw ", "rw ", "atl ", "utl ", - "sec ", "mnt ", "hr ", "hrt ", "vibe ", "sub " + "sec ", "mnt ", "hr ", "hrt ", "vibe ", "sub ", "time " }; bool using_func_tokens = false; @@ -96,7 +96,7 @@ static void updateText() const char* token = getToken(selected_token); const char* add = - token[0] == ' ' ? "_" : // Display space as underscore + token[0] == ' ' ? " " : // Display space as underscore token[0] == '\n' ? "\\n" : // Display newline as \n token; // Display others literally @@ -224,8 +224,8 @@ static void calculate() text_layer_set_font(s_result_text_layer, fonts_get_system_font(FONT_KEY_GOTHIC_14_BOLD)); } else { - text_layer_set_font(s_result_text_layer, - fonts_get_system_font(FONT_KEY_GOTHIC_18_BOLD)); + text_layer_set_font(s_result_text_layer, tiny_font); + //fonts_get_system_font(FONT_KEY_GOTHIC_18_BOLD)); } snprintf(result_text, RESULT_LENGTH, RESULT_PREFIX "%s", temp); free(temp); @@ -344,10 +344,10 @@ void debug_result(const char* d) psleep(300); } -static Object run_script(Object script_num, Object obj, +static Object run_script(Object* params, int length, struct Environment* e) { - int n = script_num.number - 1; + int n = params[0].number - 1; if (persist_exists(n)) { char* code = malloc(sizeof(char) * SMAX_LENGTH); persist_read_string(n, code, SMAX_LENGTH); @@ -467,12 +467,12 @@ static void custom_load(Window* window) window_stack_push(s_custom_window, true); } -Object add_window(Object obj1, Object _, struct Environment* env) +Object add_window(Object* params, int length, struct Environment* env) { printf("ADD_WINDOW\n"); - size_t length; - char* temp = stringObj(&obj1, &length); - sprintf(header, "%s", temp); + size_t l; + char* temp = stringObj(¶ms[0], &l); + strcpy(header, temp); if (!s_custom_window) { s_custom_window = window_create(); @@ -503,23 +503,25 @@ static void inbox_received_callback(DictionaryIterator* iter, void* context) } /** General **/ +void af(const char* name, Object (* func)(Object*, int, struct Environment*), struct Environment* env) +{ + Object o = newObject(TYPE_FUNC); + o.func = func; + addToEnv(env, name, o); +} static struct Environment pebbleEnv() { struct Environment e = defaultEnv(); - addFunc("window", &add_window, &e); - addFunc("sc", &run_script, &e); - addFunc("cw", &createWindow, &e); - addFunc("pw", &pushWindow, &e); - addFunc("rw", &deleteWindow, &e); - addFunc("atl", &addTextLayer, &e); - addFunc("utl", &updateTextLayer, &e); - addFunc("sec", &getSeconds, &e); - addFunc("mnt", &getMinutes, &e); - addFunc("hr", &getHours, &e); - addFunc("hrt", &getTwelveHours, &e); - addFunc("vibe", &doVibe, &e); - addFunc("sub", &subscribe, &e); + af("window", &add_window, &e); + af("sc", &run_script, &e); + af("cw", &createWindow, &e); + af("pw", &pushWindow, &e); + af("rw", &deleteWindow, &e); + af("atl", &addTextLayer, &e); + af("utl", &updateTextLayer, &e); + af("vibe", &doVibe, &e); + af("sub", &subscribe, &e); return e; } diff --git a/src/env.c b/src/env.c index dbe78a6..8954a40 100644 --- a/src/env.c +++ b/src/env.c @@ -8,6 +8,8 @@ #include "web.h" #include "plfunc.h" +#define printd(...) ; + struct Environment* globalEnv; struct Environment* global() @@ -145,6 +147,7 @@ void addToEnv(struct Environment* env, const char* name, const Object obj) addToEnvAt(old_size, env, name, obj); } +#ifdef STANDALONE void printEnv(struct Environment* env, int printPointers) { if (!env) { @@ -182,6 +185,8 @@ void printEnv(struct Environment* env, int printPointers) } } +#endif + void addFunc(const char* name, Object (* func)(Object*, int, struct Environment*), struct Environment* env, @@ -232,6 +237,7 @@ struct symFunc { Object (* func)(Object*, int, struct Environment*); }; +#ifdef STANDALONE struct helpText { const char* symbol; const char* help; @@ -244,7 +250,9 @@ struct helpText helpTexts[100]; /// For any instances (e.g. segfault recovery) where defaultEnv() may be called /// multiple times. int helpInitialized = 0; +#endif +#ifdef STANDALONE struct symFunc buildFuncSym(const char* symbol, Object (* func)(Object*, int, struct Environment*), const char* help, const char* const* tests, size_t testLength) { @@ -261,7 +269,17 @@ struct symFunc buildFuncSym(const char* symbol, Object (* func)(Object*, int, st .sym = symbol, }; } +#else +struct symFunc buildFuncSym(const char* symbol, Object (* func)(Object*, int, struct Environment*)) +{ + return (struct symFunc) { + .func = func, + .sym = symbol, + }; +} +#endif +#ifdef STANDALONE const int black = 30; const int red = 31; const int green = 32; @@ -350,14 +368,6 @@ fn(help, "?", return nullTerminated("Help not found!"); } -fn(segfault, "seg", - "Induces a segfault." -) -{ - int* p = NULL; - return numberObject(*p); -} - // Returns number of failures int runTests(int detailed) { @@ -409,11 +419,27 @@ int runTests(int detailed) // fprintf(stderr, "TOTAL BYTES: %zu\n", getBytes()); return failureCount; } +#endif +fn(segfault, "seg", + "Induces a segfault." +) +{ + int* p = NULL; + return numberObject(*p); +} + +#ifdef STANDALONE #define pf(_func) buildFuncSym(_func ## Symbol, &(_func), _func ## Doc, _func ## Tests, array_length(_func ## Tests)) +#else +#define pf(_func) buildFuncSym(_func ## Symbol, &(_func)) +#endif struct Environment defaultEnv() { +#ifndef STANDALONE + int helpInitialized = 0; +#endif if (!helpInitialized) { dictionary = (struct Dictionary) { .structCount = 0, @@ -484,12 +510,12 @@ struct Environment defaultEnv() #endif }; - int i; + unsigned i; for (i = 0; i < sizeof(symFuncs) / sizeof(symFuncs[0]); i++) { addFunc(symFuncs[i].sym, symFuncs[i].func, &e, i); } - for (; i < e.capacity; i++) { - e.strings[i] = NULL; + for (int j = i; j < e.capacity; j++) { + e.strings[j] = NULL; } helpInitialized = 1; diff --git a/src/object.c b/src/object.c index 0dd03ae..6ca6cb9 100644 --- a/src/object.c +++ b/src/object.c @@ -285,14 +285,14 @@ int stringNObj(struct string* s, const Object* obj) case TYPE_LAMBDA: { #ifdef STANDALONE #ifdef DEBUG - s->cursor += sprintf(s->cursor, len, "\\x%d", obj->number); + s->cursor += sprintf(s->cursor, "\\x%d", obj->number); #endif stringNObj(s, &obj->lambda->params); s->cursor += sprintf(s->cursor, " -> "); stringNObj(s, &obj->lambda->body); s->cursor += sprintf(s->cursor, ">"); #else - s->cursor += sprintf(s->cursor, len, "\\x%d", obj->number); + s->cursor += sprintf(s->cursor, "\\x%d", obj->number); #endif break; } diff --git a/src/object.h b/src/object.h index 4a5b1b7..b9b7984 100644 --- a/src/object.h +++ b/src/object.h @@ -5,9 +5,11 @@ #ifndef STANDALONE #include -#undef printf -#define printf(...) APP_LOG(APP_LOG_LEVEL_DEBUG, __VA_ARGS__) +#undef sprintf +#define sprintf(_dest, args...) snprintf(_dest, 999, args) + #else +#define xprintf(_dest, _format, ...) sprintf(_dest, _format, __VA_ARGS__) #ifdef DEBUG #define printd(...) printf(__VA_ARGS__) #else @@ -243,6 +245,7 @@ struct Error noError(); Object constructLambda(const Object* params, const Object* body, struct Environment* env); +#ifdef STANDALONE int getAllocations(); size_t getBytes(); @@ -254,4 +257,6 @@ void* smalloc(size_t size); #define malloc(x) smalloc(x) #define calloc(x, y) scalloc(x, y) +#endif // STANDALONE + #endif diff --git a/src/pebbleobject.c b/src/pebbleobject.c index df79d6d..e26a712 100644 --- a/src/pebbleobject.c +++ b/src/pebbleobject.c @@ -43,7 +43,7 @@ void custom_window_unload(Window* window) window_destroy(window); } -Object createWindow(Object o1, Object o2, struct Environment* env) +Object createWindow(Object* params, int length, struct Environment* env) { Window* window = window_create(); WindowHandlers wh = {.load = custom_window_load, @@ -52,8 +52,9 @@ Object createWindow(Object o1, Object o2, struct Environment* env) return pebbleOther(WINDOW, window, NULL, NULL); } -Object deleteWindow(Object window, Object o2, struct Environment* env) +Object deleteWindow(Object* params, int length, struct Environment* env) { + Object window = params[0]; /* Maintain a list of layers to delete? */ if (getPebbleType(window) == WINDOW) { window_stack_remove(accessPebbleObject(window)->window, true); @@ -62,8 +63,9 @@ Object deleteWindow(Object window, Object o2, struct Environment* env) return falseObject(); } -Object pushWindow(Object window, Object o2, struct Environment* env) +Object pushWindow(Object* params, int length, struct Environment* env) { + Object window = params[0]; if (getPebbleType(window) == WINDOW) { window_stack_push(accessPebbleObject(window)->window, true); return trueObject(); @@ -71,19 +73,26 @@ Object pushWindow(Object window, Object o2, struct Environment* env) return falseObject(); } -Object updateTextLayer(Object textLayer, Object text, struct Environment* env) +Object updateTextLayer(Object* params, int length, struct Environment* env) { + Object textLayer = params[0]; + Object text = params[1]; if (getPebbleType(textLayer) == TEXT_LAYER) { struct PebbleObject* po = accessPebbleObject(textLayer); - stringObj(po->textLayer->text, &text); + size_t l; + char* string = stringObj(&text, &l); + snprintf(po->textLayer->text, 999, "%s", string); + free(string); text_layer_set_text(po->textLayer->layer, po->textLayer->text); return trueObject(); } return falseObject(); } -Object addTextLayer(Object window, Object text, struct Environment* env) +Object addTextLayer(Object* params, int length, struct Environment* env) { + Object window = params[0]; + Object text = params[1]; if (getPebbleType(window) != WINDOW) { return errorObject(0); } @@ -95,7 +104,10 @@ Object addTextLayer(Object window, Object text, struct Environment* env) textLayer->text = calloc(sizeof(char), 100); textLayer->layer = text_layer_create(bounds); - stringObj(textLayer->text, &text); + size_t l; + char* string = stringObj(&text, &l); + snprintf(textLayer->text, 999, "%s", string); + free(string); text_layer_set_text(textLayer->layer, textLayer->text); text_layer_set_font(textLayer->layer, fonts_get_system_font(FONT_KEY_BITHAM_42_BOLD)); @@ -112,8 +124,10 @@ static void subscriptionHandler(struct tm* tick_time, TimeUnits changed) eval(&subscription, subscriptionEnv); } -Object subscribe(Object function, Object time, struct Environment* env) +Object subscribe(Object* params, int length, struct Environment* env) { + Object function = params[0]; + Object time = params[1]; if (function.type == TYPE_LAMBDA) { subscription = cloneObject(function); subscriptionEnv = env; diff --git a/src/pebbleobject.h b/src/pebbleobject.h index cfcd65e..b294a0c 100644 --- a/src/pebbleobject.h +++ b/src/pebbleobject.h @@ -21,14 +21,14 @@ struct PebbleObject { }; }; -Object createWindow(Object o1, Object o2, struct Environment* env); +Object createWindow(Object* params, int length, struct Environment* env); -Object deleteWindow(Object window, Object o2, struct Environment* env); +Object deleteWindow(Object* params, int length, struct Environment* env); -Object pushWindow(Object o1, Object o2, struct Environment* env); +Object pushWindow(Object* params, int length, struct Environment* env); -Object addTextLayer(Object window, Object text, struct Environment* env); +Object addTextLayer(Object* params, int length, struct Environment* env); -Object updateTextLayer(Object textLayer, Object text, struct Environment* env); +Object updateTextLayer(Object* params, int length, struct Environment* env); -Object subscribe(Object function, Object time, struct Environment* env); +Object subscribe(Object* params, int length, struct Environment* env); diff --git a/src/pebblisp.c b/src/pebblisp.c index 6dc4f8c..175309d 100644 --- a/src/pebblisp.c +++ b/src/pebblisp.c @@ -500,8 +500,10 @@ Object parseEval(const char* input, struct Environment* env) Object parsed = parse(tok).obj; if (parsed.type == TYPE_ERROR) { obj = parsed; // TODO Check necessity +#ifdef STANDALONE obj.error->plContext = malloc(sizeof(struct Slice)); *obj.error->plContext = *lastOpen; +#endif break; } if (tok[i].text[0] == ')') { diff --git a/src/pebblisp.h b/src/pebblisp.h index 1128755..534d1e2 100644 --- a/src/pebblisp.h +++ b/src/pebblisp.h @@ -12,6 +12,7 @@ #define UNPACK(...) __VA_ARGS__ +#ifdef STANDALONE #define fnn(_name, _docs, ...) \ static const char * const _name ## Doc = _docs; \ unused static const char * const _name ## Tests[] = {__VA_ARGS__}; \ @@ -27,6 +28,19 @@ fnn(_name, _docs, __VA_ARGS__) static const char * const _name ## Symbol = _symbol; \ fnn(_name, _docs, __VA_ARGS__) +#else +#define fnn(_name, _docs, ...) \ +Object _name(Object* params, int length, struct Environment* env) + +#define tfn(_name, _symbol, _type, _docs, ...) \ +static const char * const _name ## Symbol = _symbol; \ +fnn(_name, _docs, __VA_ARGS__) + +#define fn(_name, _symbol, _docs, ...) \ +static const char * const _name ## Symbol = _symbol; \ +fnn(_name, _docs, __VA_ARGS__) +#endif + #define trueObject() boolObject(1) #define falseObject() boolObject(0) @@ -64,6 +78,10 @@ Object simpleFuncEval(Object func, Object arg1, Object arg2, struct Environment* Object typeCheck(const char* funcName, Object* params, int length, int (* typeChecks[])(Object), int typeLength, int* failed); +#ifndef STANDALONE +#define DISABLE_TYPE_CHECKS +#endif + #ifndef DISABLE_TYPE_CHECKS #define checkTypes(FUNC) int FAILED; Object ERROR = typeCheck(#FUNC, params, length, FUNC ## TypeChecks, array_length(FUNC ## TypeChecks), &FAILED); \ if (FAILED) { \ @@ -99,4 +117,4 @@ tfn(structAccess, "poss", "p.title", "TI" ); -#endif \ No newline at end of file +#endif diff --git a/src/pebcom.c b/src/pebcom.c index 0e2d4b6..a8ac25e 100644 --- a/src/pebcom.c +++ b/src/pebcom.c @@ -2,11 +2,12 @@ #include -Object doVibe(Object patternList, Object o2, struct Environment* env) +Object doVibe(Object* params, int length, struct Environment* env) { - int length = listLength(&patternList); - uint32_t pattern[length]; - if (length > 0) { + Object patternList = params[0]; + int l = listLength(&patternList); + uint32_t pattern[l]; + if (l > 0) { int i = 0; Object* pl = &patternList; FOR_POINTER_IN_LIST(pl) { @@ -16,7 +17,7 @@ Object doVibe(Object patternList, Object o2, struct Environment* env) i++; } vibes_enqueue_custom_pattern( - (VibePattern) {.durations = pattern, .num_segments = length}); + (VibePattern) {.durations = pattern, .num_segments = l}); return trueObject(); } else { return errorObject(NOT_A_LIST); diff --git a/src/pebcom.h b/src/pebcom.h index 351a54b..5cc029e 100644 --- a/src/pebcom.h +++ b/src/pebcom.h @@ -1,11 +1,3 @@ #include "pebblisp.h" -Object getSeconds(Object o1, Object o2, struct Environment* env); - -Object getMinutes(Object o1, Object o2, struct Environment* env); - -Object getHours(Object o1, Object o2, struct Environment* env); - -Object getTwelveHours(Object o1, Object o2, struct Environment* env); - -Object doVibe(Object patternList, Object o2, struct Environment* env); +Object doVibe(Object* params, int length, struct Environment* env); diff --git a/src/plfunc.c b/src/plfunc.c index a9e624b..3de4522 100644 --- a/src/plfunc.c +++ b/src/plfunc.c @@ -1,5 +1,6 @@ #include #include +#include #include "plfunc.h" @@ -344,6 +345,23 @@ BASIC_COMPARISON(lessThan, <) BASIC_COMPARISON(and, &&) +int timeStructDefinition = -1; + +Object getTime(unused Object* params, unused int length, struct Environment* env) +{ + if (timeStructDefinition == -1) { + parseEval("(struct Time (minute hour sec))", env); + } + timeStructDefinition = getStructIndex("Time"); + time_t t = time(NULL); + struct tm tm = *localtime(&t); + Object o = structObject(timeStructDefinition); + o.structObject->fields[0] = numberObject(tm.tm_min); + o.structObject->fields[1] = numberObject(tm.tm_hour); + o.structObject->fields[2] = numberObject(tm.tm_sec); + return o; +} + #ifdef STANDALONE #include @@ -465,24 +483,4 @@ Object getEnvVar(Object* params, unused int length, unused struct Environment* e checkTypes(getEnvVar) return nullTerminated(getenv(params[0].string)); } - -#include - -int timeStructDefinition = -1; - -Object getTime(unused Object* params, unused int length, struct Environment* env) -{ - if (timeStructDefinition == -1) { - parseEval("(struct Time (minute hour sec))", env); - } - timeStructDefinition = getStructIndex("Time"); - time_t t = time(NULL); - struct tm tm = *localtime(&t); - Object o = structObject(timeStructDefinition); - o.structObject->fields[0] = numberObject(tm.tm_min); - o.structObject->fields[1] = numberObject(tm.tm_hour); - o.structObject->fields[2] = numberObject(tm.tm_sec); - return o; -} - #endif // STANDALONE diff --git a/src/plfunc.h b/src/plfunc.h index 1e4f56c..01f9ab0 100644 --- a/src/plfunc.h +++ b/src/plfunc.h @@ -189,6 +189,11 @@ fn(parseEvalO, "eval", "(eval '(+ 5 5))", "10", ); +tfn(getTime, "time", + ({ isStruct }), + "Get a struct of the current time with fields (minute hour sec)." +); + #ifdef STANDALONE fn(print, "prn", "Prints the string representation of the given object to stdout."); @@ -253,11 +258,6 @@ tfn(getEnvVar, "env", "(env HOME) => /home/sagevaillancourt" ); -tfn(getTime, "time", - ({ isStruct }), - "Get a struct of the current time with fields (minute hour sec)." -); - #endif // STANDALONE -#endif // PEBBLISP_PLFUNC_H \ No newline at end of file +#endif // PEBBLISP_PLFUNC_H diff --git a/src/web.c b/src/web.c index fe26b8d..535105a 100644 --- a/src/web.c +++ b/src/web.c @@ -1,3 +1,5 @@ +#ifdef STANDALONE + #include #include #include @@ -185,4 +187,6 @@ Object startServer(Object* params, int length, struct Environment* env) port = portObject.number; } return numberObject(start(port)); -} \ No newline at end of file +} + +#endif // STANDALONE diff --git a/src/web.h b/src/web.h index ec715c2..87209e1 100644 --- a/src/web.h +++ b/src/web.h @@ -1,3 +1,5 @@ +#ifdef STANDALONE + #include "pebblisp.h" fn(startServer, "serve", @@ -22,3 +24,5 @@ fn(addPostRoute, "post", " (serve)\n" "Also see: (serve)\n" ); + +#endif