248 lines
4.8 KiB
C
248 lines
4.8 KiB
C
#ifndef OBJECT_H
|
|
#define OBJECT_H
|
|
|
|
#include <stdlib.h>
|
|
|
|
#ifndef STANDALONE
|
|
#include <pebble.h>
|
|
#undef printf
|
|
#define printf(...) APP_LOG(APP_LOG_LEVEL_DEBUG, __VA_ARGS__)
|
|
#else
|
|
#ifdef DEBUG
|
|
#define printd(...) printf(__VA_ARGS__)
|
|
#else
|
|
#define printd(...) (0)
|
|
#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;
|
|
Object *forward;
|
|
|
|
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
|
|
};
|
|
};
|
|
|
|
struct StructDef {
|
|
int fieldCount;
|
|
char* name;
|
|
const char** names;
|
|
};
|
|
|
|
struct StructObject {
|
|
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(struct StructDef *definition);
|
|
|
|
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
|
|
|
|
struct Error noError();
|
|
|
|
Object constructLambda(const Object *params, const Object *body);
|
|
|
|
// Object version of listLength()
|
|
Object len(Object obj1, Object, struct Environment *);
|
|
|
|
#endif
|