268 lines
4.9 KiB
C
268 lines
4.9 KiB
C
#ifndef OBJECT_H
|
|
#define OBJECT_H
|
|
|
|
#include <stdlib.h>
|
|
|
|
#ifndef STANDALONE
|
|
#include <pebble.h>
|
|
#undef sprintf
|
|
#define sprintf(_dest, args...) snprintf(_dest, 999, args)
|
|
|
|
#else
|
|
|
|
#ifdef DEBUG
|
|
#define printd(...) printf(__VA_ARGS__)
|
|
#else
|
|
#define printd(...) do { } while (0)
|
|
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
|
|
#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
|
|
|
|
#ifdef PBL_PLATFORM_APLITE
|
|
#define LOW_MEM
|
|
#endif
|
|
|
|
#ifdef LOW_MEM
|
|
#define SIMPLE_ERRORS
|
|
#endif
|
|
|
|
enum errorCode {
|
|
MISMATCHED_PARENS,
|
|
NULL_ENV,
|
|
EMPTY_ENV,
|
|
NULL_PARSE,
|
|
NULL_LAMBDA_LIST,
|
|
NULL_MAP_ARGS,
|
|
LAMBDA_ARGS_NOT_LIST,
|
|
DID_NOT_FIND_SYMBOL,
|
|
BAD_TYPE,
|
|
BAD_PARAMS,
|
|
BAD_NUMBER,
|
|
UNSUPPORTED_NUMBER_TYPE,
|
|
NOT_ENOUGH_ARGUMENTS,
|
|
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_PROMISE,
|
|
TYPE_OTHER,
|
|
TYPE_ERROR
|
|
} Type;
|
|
|
|
typedef struct Object Object;
|
|
|
|
struct Lambda;
|
|
struct Environment;
|
|
struct Promise;
|
|
struct Other;
|
|
struct Error {
|
|
enum errorCode code;
|
|
char* context;
|
|
struct Slice* plContext;
|
|
};
|
|
|
|
struct Object {
|
|
Type type;
|
|
|
|
union {
|
|
int number;
|
|
Object* list;
|
|
char* string;
|
|
|
|
Object (* func)(Object*, int, struct Environment*);
|
|
|
|
struct StructObject* structObject;
|
|
struct Lambda* lambda;
|
|
struct Other* other;
|
|
struct Promise* promise;
|
|
#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 Object* fields; // Order should match that in the definition.
|
|
};
|
|
|
|
struct Lambda {
|
|
int refs;
|
|
Object params;
|
|
Object body;
|
|
};
|
|
|
|
struct Other {
|
|
void (* cleanup)(Object*);
|
|
|
|
Object (* clone)(struct Other*);
|
|
|
|
void* data;
|
|
};
|
|
|
|
struct string {
|
|
char* allocPoint;
|
|
char* cursor;
|
|
size_t capacity;
|
|
};
|
|
|
|
/**
|
|
* Returns a dynamically-sized string representation of the given object.
|
|
*
|
|
* _Adds_ the length of the new string to the `length` parameter.
|
|
*/
|
|
char* stringObj(const Object* obj, size_t* length);
|
|
|
|
const char* getTypeName(const Object* obj);
|
|
|
|
void printObj(const Object* obj);
|
|
|
|
void _printObj(const Object* obj, int newline);
|
|
|
|
void debugObj(const Object* obj);
|
|
|
|
int isEmpty(const Object* obj);
|
|
|
|
Object* tail(const Object* listObj);
|
|
|
|
Object* nf_addToList(Object* dest, Object src);
|
|
|
|
void deleteList(Object* dest);
|
|
|
|
int listLength(const Object* listObj);
|
|
|
|
Object* itemAt(const Object* listObj, int n);
|
|
|
|
Object copyList(const Object* src);
|
|
|
|
void cleanObject(Object* target);
|
|
|
|
void printAndClean(Object* target);
|
|
|
|
void allocObject(Object** spot, Object src);
|
|
|
|
void appendList(Object* dest, const Object* src);
|
|
|
|
int isNumber(Object test);
|
|
|
|
int isListy(Object test);
|
|
|
|
int isStringy(Object test);
|
|
|
|
int isBool(Object test);
|
|
|
|
int isStruct(Object test);
|
|
|
|
int isFuncy(Object test);
|
|
|
|
int isValidType(Object test);
|
|
|
|
int isError(Object obj, enum errorCode err);
|
|
|
|
int bothAre(enum Type type, const Object* obj1, const Object* obj2);
|
|
|
|
int areSameType(const Object* obj1, const Object* obj2);
|
|
|
|
Object cloneList(Object src);
|
|
|
|
Object cloneString(Object obj);
|
|
|
|
Object cloneLambda(Object old);
|
|
|
|
Object cloneObject(Object src);
|
|
|
|
Object newObject(Type type);
|
|
|
|
Object listObject();
|
|
|
|
Object startList(Object start);
|
|
|
|
Object objFromSlice(const char* string, int len);
|
|
|
|
Object nullTerminated(const char* string);
|
|
|
|
Object stringFromSlice(const char* string, int len);
|
|
|
|
Object symFromSlice(const char* string, int len);
|
|
|
|
Object withLen(size_t len, enum Type type);
|
|
|
|
Object boolObject(int b);
|
|
|
|
Object numberObject(int num);
|
|
|
|
Object structObject(int definition);
|
|
|
|
Object otherObject();
|
|
|
|
Object errorObject(enum errorCode err);
|
|
|
|
enum errorCode getErrorCode(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);
|
|
|
|
#ifdef STANDALONE
|
|
|
|
int getAllocations();
|
|
|
|
size_t getBytes();
|
|
|
|
void* scalloc(size_t size, size_t count);
|
|
|
|
void* smalloc(size_t size);
|
|
|
|
#define malloc(x) smalloc(x)
|
|
#define calloc(x, y) scalloc(x, y)
|
|
|
|
#endif // STANDALONE
|
|
|
|
#endif
|