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.
This commit is contained in:
parent
c142730837
commit
3d8e2d30d4
|
@ -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" \
|
||||
|
|
|
@ -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
|
||||
|
|
40
src/object.c
40
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 <pebble.h>
|
||||
#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)
|
||||
{
|
||||
|
|
31
src/object.h
31
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()
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#ifndef STANDALONE
|
||||
#undef printf
|
||||
#define printf(...) APP_LOG(APP_LOG_LEVEL_DEBUG, __VA_ARGS__)
|
||||
#include <pebble.h>
|
||||
#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);
|
||||
}
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
|
||||
#ifndef STANDALONE
|
||||
#include <pebble.h>
|
||||
#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 {
|
||||
|
|
Loading…
Reference in New Issue