From 3d8e2d30d48ddab360a59b1c091b683a459dc55a Mon Sep 17 00:00:00 2001 From: = <=> Date: Wed, 21 Jul 2021 19:31:40 +0100 Subject: [PATCH] Add LOW_MEM and SIMPLE_ERRORS flags for aplite. LOW_MEM drops some functionality (like `defe`) for very low memory devices like aplite. SIMPLE_ERRORS is enabled when compiling with LOW_MEM, and overrides the new error-with-context functionality with older, less intensive methods. Also marked more code for standalone compilation only. --- src/calc.c | 8 ++++---- src/env.c | 7 +++++-- src/object.c | 40 +++++++++++++++++++++++++++++++++------- src/object.h | 31 +++++++++++++++++++++++++------ src/pebblisp.c | 21 +++++++++++++++------ src/pebblisp.h | 4 ++-- 6 files changed, 84 insertions(+), 27 deletions(-) diff --git a/src/calc.c b/src/calc.c index ad88870..28be130 100644 --- a/src/calc.c +++ b/src/calc.c @@ -258,10 +258,10 @@ static void code_click_subscribe(void *context) } #define FORCE_TEXT \ - "(def time (fn () ((def m (mnt)) (utl tt \n"\ - " (cat \"Hey, it's \"\n"\ - " (hrt) \":\" (if (< m 10) \"0\" \"\") m)\n"\ - "))))\n" \ + "(def time (fn () (utl tt \n"\ + " (cat \"Hey, it's \" \n"\ + " (hrt) \":\" (mnt))\n"\ + ")))\n" \ "(def ww (cw))\n" \ "(def tt (atl ww \":\"))\n" \ "(pw ww)\n" \ diff --git a/src/env.c b/src/env.c index 2959295..a6909fb 100644 --- a/src/env.c +++ b/src/env.c @@ -216,11 +216,14 @@ struct Environment defaultEnv() {"=", &equ}, {">", >h}, {"<", <h}, {"cat", &catObjects}, {"fil", &filter}, {"len", &len}, {"ap", &append}, {"pre", &prepend}, - {"at", &at}, {"rest", &rest}, {"rev", &reverse}, + {"at", &at}, {"rest", &rest}, +#ifndef LOW_MEM + {"rev", &reverse}, +#endif {"isnum", &isNum}, {"isstr", &isString}, {"iserr", &isErr}, - {"prn", &print}, {"pch", &pChar}, {"penv", &printEnvO}, {"eval", &parseEvalO}, #ifdef STANDALONE + {"prn", &print}, {"pch", &pChar}, {"penv", &printEnvO}, {"loadfile", &loadFile}, {"inp", &takeInput}, #endif diff --git a/src/object.c b/src/object.c index 749d703..4f9cc67 100644 --- a/src/object.c +++ b/src/object.c @@ -5,13 +5,15 @@ #ifdef DEBUG #define printd(...) printf(__VA_ARGS__) #else -#define printd(...) stringObj(NULL, NULL) +#define printd(...) ; #endif #ifndef STANDALONE #include #undef printf -#define printf(...) APP_LOG(APP_LOG_LEVEL_DEBUG, __VA_ARGS__) +#undef printd +#define printf(...) ; +#define printd(...) APP_LOG(APP_LOG_LEVEL_DEBUG, __VA_ARGS__) #endif /** @@ -105,7 +107,7 @@ inline int isEmpty(const Object *obj) case TYPE_OTHER: return obj->other == NULL; case TYPE_ERROR: - return obj->error->code == 0; + return getErrorCode(*obj); } return 0; @@ -290,13 +292,17 @@ char* stringNObj(char *dest, const Object *obj, const size_t len) { stringList(dest, obj); break; case TYPE_ERROR: { - int code = obj->error->code; + int code = getErrorCode(*obj); + #ifdef SIMPLE_ERRORS + snprintf(dest, len, "%s", errorText[code]); + #else if (obj->error->context && obj->error->context[0] != '\0') { snprintf(dest, len, "'%s': %s", errorText[code], obj->error->context); } else { snprintf(dest, len, "%s", errorText[code]); } + #endif break; } case TYPE_FUNC: @@ -330,6 +336,7 @@ void debugObj(const Object *obj) return; } +#if defined(DEBUG) || defined(STANDALONE) void printType(const Object *obj) { switch(obj->type) { @@ -419,6 +426,7 @@ void printList(const Object *list) { _printList(list, 1); } +#endif /** * Performs appropriate free() on a given Object and NULLs its ->forward @@ -432,7 +440,6 @@ void printList(const Object *list) */ void cleanObject(Object *target) { - //printf("CLEANING:"); if(target == NULL) return; @@ -451,9 +458,11 @@ void cleanObject(Object *target) free(target->lambda); break; case TYPE_ERROR: +#ifndef SIMPLE_ERRORS free(target->error->context); free(target->error); target->error = NULL; +#endif break; case TYPE_OTHER: if(target->other->cleanup) { @@ -473,11 +482,13 @@ void cleanObject(Object *target) * Print the given object with a newline, then clean it * @param target The object to print and clean */ +#ifdef STANDALONE void printAndClean(Object *target) { printObj(target); cleanObject(target); } +#endif /** * Frees all objects in a given list @@ -653,7 +664,7 @@ inline Object cloneObject(const Object src) case TYPE_SYMBOL: return cloneString(src); case TYPE_ERROR: - return errorWithContext(src.error->code, src.error->context); + return errorWithContext(getErrorCode(src), src.error->context); case TYPE_BOOL: case TYPE_NUMBER: case TYPE_FUNC: @@ -718,7 +729,7 @@ inline Object constructLambda(const Object *params, const Object *body) inline int isError(const Object obj, const enum errorCode err) { - return obj.type == TYPE_ERROR && obj.error->code == err; + return obj.type == TYPE_ERROR && getErrorCode(obj) == err; } inline int bothAre(const enum Type type, const Object *obj1, const Object *obj2) @@ -746,13 +757,27 @@ inline Object otherObject() inline Object errorObject(enum errorCode err) { Object o = newObject(TYPE_ERROR); +#ifdef SIMPLE_ERRORS + o.error = err; +#else o.error = malloc(sizeof(struct Error)); o.error->code = err; o.error->context = NULL; +#endif return o; } +inline enum errorCode getErrorCode(const Object obj) +{ +#ifdef SIMPLE_ERRORS + return obj.error; +#else + return obj.error->code; +#endif +} + +#ifndef SIMPLE_ERRORS inline void errorAddContext(Object *o, const char* context) { o->error->context = calloc(sizeof(char), RESULT_LENGTH); @@ -765,6 +790,7 @@ inline Object errorWithContext(enum errorCode err, const char* context) errorAddContext(&o, context); return o; } +#endif inline Object toBool(const Object test) { diff --git a/src/object.h b/src/object.h index b69cd20..db1adf8 100644 --- a/src/object.h +++ b/src/object.h @@ -21,6 +21,14 @@ #define P1 POINTER #define P2 _element2 +#ifdef PBL_PLATFORM_APLITE + #define LOW_MEM +#endif + +#ifdef LOW_MEM + #define SIMPLE_ERRORS +#endif + enum errorCode { MISMATCHED_PARENS, BAD_LIST_OF_SYMBOL_STRINGS, @@ -64,7 +72,12 @@ struct Lambda; struct Environment; struct Slice; struct Other; -struct Error; +#ifndef SIMPLE_ERRORS +struct Error { + enum errorCode code; + char* context; +}; +#endif struct Object { Type type; @@ -76,15 +89,14 @@ struct Object { Object (*func)(Object, Object, struct Environment *); struct Lambda *lambda; struct Other *other; + #ifdef SIMPLE_ERRORS + enum errorCode error; + #else struct Error *error; + #endif }; }; -struct Error { - enum errorCode code; - char* context; -}; - struct Lambda { Object params; Object body; @@ -143,8 +155,15 @@ Object boolObject(int b); Object numberObject(int num); Object otherObject(); Object errorObject(enum errorCode err); +enum errorCode getErrorCode(const Object obj); +#ifdef SIMPLE_ERRORS + #define errorWithContext(code, context) errorObject(code) + #define errorAddContext(x, y) ; +#else Object errorWithContext(enum errorCode err, const char* context); void errorAddContext(Object *o, const char* context); +#endif + Object constructLambda(const Object *params, const Object *body); // Object version of listLength() diff --git a/src/pebblisp.c b/src/pebblisp.c index ca027e9..14fb3cf 100644 --- a/src/pebblisp.c +++ b/src/pebblisp.c @@ -7,6 +7,7 @@ #ifndef STANDALONE #undef printf #define printf(...) APP_LOG(APP_LOG_LEVEL_DEBUG, __VA_ARGS__) +#include #endif /** @@ -108,11 +109,13 @@ Object evalBuiltIns(const Object *first, const Object *rest, if(strcmp(first->string, "def") == 0) { return evalDefArgs(rest, rest->forward, env); + #ifndef LOW_MEM } else if(strcmp(first->string, "defe") == 0) { Object symbol = eval(rest, env); Object e = evalDefArgs(&symbol, rest->forward, env); cleanObject(&symbol); return e; + #endif } else if(strcmp(first->string, "if") == 0) { return evalIfArgs(rest, env); } else if(strcmp(first->string, "fn") == 0) { @@ -511,22 +514,23 @@ Object reverse(Object _list, Object ignore, struct Environment *ignore2) Object isNum(Object test, Object ignore, struct Environment *ignore2) { - return test.type == TYPE_NUMBER ? - boolObject(1) : boolObject(0); + return test.type == TYPE_NUMBER ? + boolObject(1) : boolObject(0); } Object isString(Object test, Object ignore, struct Environment *ignore2) { - return test.type == TYPE_STRING ? - boolObject(1) : boolObject(0); + return test.type == TYPE_STRING ? + boolObject(1) : boolObject(0); } Object isErr(Object test, Object ignore, struct Environment *ignore2) { - return test.type == TYPE_ERROR ? - boolObject(1) : boolObject(0); + return test.type == TYPE_ERROR ? + boolObject(1) : boolObject(0); } +#ifdef STANDALONE Object print(Object p, Object ignore, struct Environment *env) { p = cloneObject(p); @@ -552,6 +556,7 @@ Object printEnvO(Object i1, Object i2, struct Environment *env) { printEnv(env); return numberObject(0); } +#endif Object parseEvalO(Object text, Object ignore, struct Environment *env) { @@ -586,6 +591,7 @@ void copySlice(char * dest, struct Slice *src) void debugSlice(struct Slice *s) { +#ifdef DEBUG if(!s) { printf("NULL SLICE\n"); return; @@ -599,6 +605,7 @@ void debugSlice(struct Slice *s) } printf("'\n"); printf(" length: %d\n", s->length); +#endif } Result parse(struct Slice *slices) @@ -687,10 +694,12 @@ Object parseAtom(struct Slice *s) if(isDigit(c)) { if(c != '0' || s->length == 1) { return parseDecimal(s); + #ifndef LOW_MEM } else if(c == '0' && s->text[1] == 'x') { return parseHex(s); } else if(c == '0' && s->text[1] == 'b') { return parseBin(s); + #endif } else { return errorObject(UNSUPPORTED_NUMBER_TYPE); } diff --git a/src/pebblisp.h b/src/pebblisp.h index f188bf1..072fcec 100644 --- a/src/pebblisp.h +++ b/src/pebblisp.h @@ -6,13 +6,13 @@ #ifndef STANDALONE #include -#define printd(...) copySlice(NULL, NULL) +#define printd(...) ; #endif #ifdef DEBUG #define printd(...) printf(__VA_ARGS__) #else -#define printd(...) copySlice(NULL, NULL) +#define printd(...) ; #endif struct Slice {