#ifndef OBJECT_H #define OBJECT_H #include #ifndef STANDALONE #include #undef printf #define printf(...) APP_LOG(APP_LOG_LEVEL_DEBUG, __VA_ARGS__) #else #ifdef DEBUG #define printd(...) printf(__VA_ARGS__) #else #define printd(...) ; #endif #endif #define MAX_TOK_CNT 1024 #define MAX_ENV_ELM 100 #define RESULT_LENGTH 128 #define FOR_POINTER_IN_LIST(_list) \ for(Object *_element = (_list)->list; \ _element != NULL;\ _element = _element->forward) #define POINTER _element #define FOR_POINTERS_IN_LISTS(_list, _list2) \ for(Object *_element = (_list)->list, *_element2 = (_list2)->list; \ _element != NULL && _element2 != NULL; \ _element = _element->forward, _element2 = _element2->forward) #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, TYPE_LIST_NOT_CAUGHT, NULL_ENV, EMPTY_ENV, BUILT_IN_NOT_FOUND, NULL_PARSE, NULL_LAMBDA_LIST, NULL_MAP_ARGS, LAMBDA_ARGS_NOT_LIST, DID_NOT_FIND_SYMBOL, BAD_TYPE, UNEXPECTED_FORM, LISTS_NOT_SAME_SIZE, BAD_NUMBER, UNSUPPORTED_NUMBER_TYPE, NOT_A_SYMBOL, ONLY_ONE_ARGUMENT, NOT_A_LIST, SCRIPT_NOT_FOUND, NO_CLONE_SPECIFIED, CAN_ONLY_EVAL_STRINGS, UNEXPECTED_EOF, INDEX_PAST_END, }; typedef enum Type { TYPE_NUMBER, TYPE_BOOL, TYPE_LIST, TYPE_SLIST, TYPE_STRUCT, TYPE_FUNC, TYPE_SYMBOL, TYPE_LAMBDA, TYPE_STRING, TYPE_OTHER, TYPE_ERROR } Type; typedef struct Object Object; struct Lambda; struct Environment; struct Slice; struct Other; struct Error { enum errorCode code; char *context; }; struct Object { Type type; union { int number; Object *list; char *string; Object (*func)(Object, Object, struct Environment *); struct StructObject *structObject; struct Lambda *lambda; struct Other *other; #ifdef SIMPLE_ERRORS enum errorCode error; #else struct Error *error; #endif }; Object *forward; }; struct StructDef { int fieldCount; char* name; char** names; }; struct StructObject { int definition; //struct StructDef *definition; struct Object* fields; // Order should match that in the definition. }; struct Lambda { Object params; Object body; }; struct Other { void (*cleanup)(Object *); Object (*clone)(struct Other *); void *data; }; char *stringNObj(char *dest, const Object *obj, size_t len); char *stringObj(char *dest, const Object *obj); void printList(const Object *list); void printType(const Object *obj); void printObj(const Object *obj); void _printObj(const Object *obj, int newline); void debugObj(const Object *obj); void printErr(const Object *obj); int isEmpty(const Object *obj); Object *tail(const Object *listObj); void insertIntoList(Object *dest, int ind, const Object src); void replaceListing(Object *list, int i, const Object src); void nf_addToList(Object *dest, Object src); void deleteList(Object *dest); int listLength(const Object *listObj); Object *itemAt(const Object *listObj, int n); void copyList(Object *dest, const Object *src); void cleanObject(Object *target); void printAndClean(Object *target); void allocObject(Object **spot, const Object src); void appendList(Object *dest, const Object *src); int isListy(const Object test); int isStringy(const Object test); int isValidType(const Object test); int isError(const Object obj, const enum errorCode err); int bothAre(const enum Type type, const Object *obj1, const Object *obj2); int eitherIs(const enum Type type, const Object *obj1, const Object *obj2); int areSameType(const Object *obj1, const Object *obj2); Object cloneList(const Object src); Object cloneString(Object obj); Object cloneLambda(const Object old); Object cloneObject(const Object src); Object newObject(Type type); Object listObject(); Object startList(const Object start); Object objFromSlice(const char *string, int len); Object stringFromSlice(const char *string, int len); Object symFromSlice(const char *string, int len); Object boolObject(int b); Object numberObject(int num); Object structObject(int definition); Object otherObject(); Object errorObject(enum errorCode err); enum errorCode getErrorCode(const Object obj); Object errorWithContextLineNo(enum errorCode code, const char* context, int lineNo, const char* fileName); #ifdef SIMPLE_ERRORS #define errorWithContext(code, context) errorObject(code) #define errorAddContext(x, y, z, a) ; #else #define errorWithContext(_code, _context) errorWithContextLineNo(_code, _context, __LINE__, __FILE__) void errorAddContext(Object* o, const char* context, int lineNo, const char* fileName); #endif struct Error noError(); Object constructLambda(const Object *params, const Object *body, struct Environment* env); // Object version of listLength() Object len(Object obj1, Object, struct Environment *); int getAllocations(); int getBytes(); #endif