pebblisp/src/object.h

263 lines
4.8 KiB
C
Raw Normal View History

2020-05-05 13:42:28 -04:00
#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
2022-03-31 14:12:52 -04:00
#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
2020-05-05 13:42:28 -04:00
#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
2020-05-05 13:42:28 -04:00
enum errorCode {
2020-05-08 02:29:06 -04:00
MISMATCHED_PARENS,
2020-05-05 13:42:28 -04:00
NULL_ENV,
EMPTY_ENV,
2020-05-05 19:21:54 -04:00
NULL_PARSE,
NULL_LAMBDA_LIST,
2020-05-07 20:32:01 -04:00
NULL_MAP_ARGS,
LAMBDA_ARGS_NOT_LIST,
DID_NOT_FIND_SYMBOL,
2020-05-07 20:32:01 -04:00
BAD_TYPE,
BAD_PARAMS_ON,
BAD_NUMBER,
UNSUPPORTED_NUMBER_TYPE,
NOT_ENOUGH_ARGUMENTS,
NOT_A_LIST,
SCRIPT_NOT_FOUND,
NO_CLONE_SPECIFIED,
2021-07-05 01:13:45 -04:00
CAN_ONLY_EVAL_STRINGS,
UNEXPECTED_EOF,
2021-07-05 01:13:45 -04:00
INDEX_PAST_END,
2020-05-05 13:42:28 -04:00
};
typedef enum Type {
TYPE_NUMBER,
TYPE_BOOL,
TYPE_LIST,
TYPE_SLIST,
TYPE_STRUCT,
2020-05-05 13:42:28 -04:00
TYPE_FUNC,
TYPE_SYMBOL,
TYPE_LAMBDA,
TYPE_STRING,
TYPE_OTHER,
2020-05-07 20:32:01 -04:00
TYPE_ERROR
2020-05-05 13:42:28 -04:00
} Type;
typedef struct Object Object;
2020-05-05 13:42:28 -04:00
struct Lambda;
struct Environment;
struct Other;
struct Error {
enum errorCode code;
2022-03-19 22:25:20 -04:00
char* context;
struct Slice* plContext;
};
2020-05-05 13:42:28 -04:00
struct Object {
Type type;
2022-03-19 22:25:20 -04:00
2020-05-05 13:42:28 -04:00
union {
int number;
2022-03-19 22:25:20 -04:00
Object* list;
char* string;
Object (* func)(Object*, int, struct Environment*);
2022-03-19 22:25:20 -04:00
struct StructObject* structObject;
struct Lambda* lambda;
struct Other* other;
#ifdef SIMPLE_ERRORS
enum errorCode error;
#else
2022-03-19 22:25:20 -04:00
struct Error* error;
#endif
2020-05-05 13:42:28 -04:00
};
2022-03-19 22:25:20 -04:00
Object* forward;
2020-05-05 13:42:28 -04:00
};
struct StructDef {
int fieldCount;
char* name;
char** names;
};
struct StructObject {
int definition;
struct Object* fields; // Order should match that in the definition.
};
2020-05-05 13:42:28 -04:00
struct Lambda {
int refs;
2020-05-05 13:42:28 -04:00
Object params;
Object body;
};
struct Other {
2022-03-19 22:25:20 -04:00
void (* cleanup)(Object*);
2022-03-19 22:25:20 -04:00
Object (* clone)(struct Other*);
2022-03-19 22:25:20 -04:00
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);
2022-03-19 22:25:20 -04:00
void printType(const Object* obj);
2022-03-19 22:25:20 -04:00
void printObj(const Object* obj);
2022-03-19 22:25:20 -04:00
void _printObj(const Object* obj, int newline);
2022-03-19 22:25:20 -04:00
void debugObj(const Object* obj);
2022-03-19 22:25:20 -04:00
int isEmpty(const Object* obj);
2022-03-19 22:25:20 -04:00
Object* tail(const Object* listObj);
Object* nf_addToList(Object* dest, Object src);
2022-03-19 22:25:20 -04:00
void deleteList(Object* dest);
2022-03-19 22:25:20 -04:00
int listLength(const Object* listObj);
2022-03-19 22:25:20 -04:00
Object* itemAt(const Object* listObj, int n);
Object copyList(const Object* src);
2020-05-05 13:42:28 -04:00
2022-03-19 22:25:20 -04:00
void cleanObject(Object* target);
2022-03-19 22:25:20 -04:00
void printAndClean(Object* target);
2022-03-19 22:25:20 -04:00
void allocObject(Object** spot, Object src);
2022-03-19 22:25:20 -04:00
void appendList(Object* dest, const Object* src);
2020-05-05 19:21:54 -04:00
int isNumber(Object test);
2022-03-19 22:25:20 -04:00
int isListy(Object test);
2022-03-19 22:25:20 -04:00
int isStringy(Object test);
int isBool(Object test);
int isStruct(Object test);
int isFuncy(Object test);
2022-03-19 22:25:20 -04:00
int isValidType(Object test);
2022-03-19 22:25:20 -04:00
int isError(Object obj, enum errorCode err);
2022-03-19 22:25:20 -04:00
int bothAre(enum Type type, const Object* obj1, const Object* obj2);
2022-03-19 22:25:20 -04:00
int areSameType(const Object* obj1, const Object* obj2);
2022-03-19 22:25:20 -04:00
Object cloneList(Object src);
Object cloneString(Object obj);
2022-03-19 22:25:20 -04:00
Object cloneLambda(Object old);
2022-03-19 22:25:20 -04:00
Object cloneObject(Object src);
2020-05-05 19:21:54 -04:00
Object newObject(Type type);
2020-05-05 13:42:28 -04:00
Object listObject();
2022-03-19 22:25:20 -04:00
Object startList(Object start);
2022-03-19 22:25:20 -04:00
Object objFromSlice(const char* string, int len);
Object nullTerminated(const char* string);
2022-03-19 22:25:20 -04:00
Object stringFromSlice(const char* string, int len);
2022-03-19 22:25:20 -04:00
Object symFromSlice(const char* string, int len);
Object withLen(size_t len, enum Type type);
2022-03-28 09:56:24 -04:00
Object boolObject(int b);
Object numberObject(int num);
Object structObject(int definition);
Object otherObject();
2020-05-05 19:21:54 -04:00
Object errorObject(enum errorCode err);
2022-03-19 22:25:20 -04:00
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__)
2022-03-19 22:25:20 -04:00
void errorAddContext(Object* o, const char* context, int lineNo, const char* fileName);
2022-03-19 22:25:20 -04:00
#endif
struct Error noError();
2022-03-19 22:25:20 -04:00
Object constructLambda(const Object* params, const Object* body, struct Environment* env);
2020-05-05 13:42:28 -04:00
#ifdef STANDALONE
int getAllocations();
2022-03-19 22:25:20 -04:00
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
2020-05-05 13:42:28 -04:00
#endif