splink/source/compute.h

230 lines
4.7 KiB
C

/* date = July 8th 2020 7:11 am */
#ifndef COMPUTE_H
#define COMPUTE_H
typedef enum{
C_TokenKind_NULL,
C_TokenKind_Space,
C_TokenKind_Newline,
C_TokenKind_Comment,
#define C_TokenKind_FIRST_HARD C_TokenKind_OpenParen
C_TokenKind_OpenParen,
C_TokenKind_CloseParen,
C_TokenKind_Quote,
C_TokenKind_Label,
#define C_TokenKind_LAST_HARD C_TokenKind_Label
C_TokenKind_COUNT,
} C_TokenKind;
typedef struct C_Token C_Token;
struct C_Token{
C_TokenKind kind;
STR_Index string;
};
typedef struct C_TokenArray C_TokenArray;
struct C_TokenArray{
C_Token *vals;
u64 count;
};
////////////////////////////////
typedef u64 C_Id;
typedef struct C_Deferred C_Deferred;
struct C_Deferred{
void *user_ptr;
struct C_Cell *env;
struct C_Cell *cell;
b32 doing_eval;
b32 finished_eval;
};
#define C_BUILT_IN_SIG(name) struct C_Cell* name(struct C_EvalCtx *ctx, struct C_Cell *cell, struct C_Cell **env)
typedef C_BUILT_IN_SIG(C_BuiltInFunctionType);
typedef enum{
C_CellKind_Nil,
C_CellKind_Constructed,
C_CellKind_F64,
C_CellKind_Id,
C_CellKind_Identifier,
// NOTE(allen): Used in eval but not emitted by parser
C_CellKind_BuiltIn,
C_CellKind_Environment,
C_CellKind_Function,
C_CellKind_Macro,
C_CellKind_FunctionV,
C_CellKind_MacroV,
C_CellKind_Register,
C_CellKind_Deferred,
C_CellKind_Space,
// NOTE(allen): Used in memory allocation strategy,
// a correctly functioning lisp eval should not encounter this.
// If it does it will be treated as Nil.
C_CellKind_BlockHeader,
} C_CellKind;
// NOTE(allen): Forming verbs (functions, macros, variadics):
// first_child -> constructed list of parameters
// -> identifier for variadics
// next -> expression forming body of function
// env -> environment inherited from enclosing scope
typedef struct C_Cell C_Cell;
struct C_Cell{
C_CellKind kind;
C_Cell *next;
union{
C_Cell *first_child;
C_BuiltInFunctionType *built_in;
};
union{
u64 x;
struct C_CellBucket *bucket;
void *space;
f64 f;
STR_Index identifier;
C_Cell *env;
C_Deferred *deferred;
C_Id id;
u64 depth_counter;
};
};
// NOTE(allen): We want fast divides on whatever size we pick here.
#define C_BLOCK_CAP 256
typedef struct C_CellMemory C_CellMemory;
struct C_CellMemory{
M_Arena arena;
C_Cell *cells;
C_Cell *free_block;
};
typedef struct C_CellBucket C_CellBucket;
struct C_CellBucket{
C_CellMemory *memory;
C_Cell *first_block;
C_Cell *last_block;
u64 cursor;
};
typedef struct C_ListBuilder C_ListBuilder;
struct C_ListBuilder{
C_Cell *f;
C_Cell **u;
u64 c;
};
////////////////////////////////
typedef struct C_ParseError C_ParseError;
struct C_ParseError{
String8 message;
C_Token *token;
};
typedef struct C_ParseCtx C_ParseCtx;
struct C_ParseCtx{
struct C_Statics *statics;
C_CellBucket *bucket;
C_Token *token;
C_Token *opl;
u64 error_count;
u64 error_max;
C_ParseError *errors;
};
////////////////////////////////
#define C_BuiltInXList(X) \
X("define", Define) \
X("function", Function) \
X("function...", FunctionV) \
X("macro", Macro) \
X("macro...", MacroV) \
X("write-reg", WriteRegister) \
X("read-reg", ReadRegister) \
X("get-thread-local-reg", GetUniqueRegister) \
X("block", Block) \
X("first", First) \
X("next", Next) \
X("push", Push) \
X("list", List) \
X("list-count", ListCount) \
X("id", Id) \
X("all-ids", AllIds) \
X("quote", Quote) \
X("eval", Eval) \
X("apply", Apply) \
X("far-eval", FarEval) \
X("kind", Kind) \
X("if", If) \
X("switch", Switch) \
X("loop", Loop) \
X("+1", Increment) \
X("-1", Decrement) \
X("+", Add) \
X("-", Sub) \
X("*", Mul) \
X("/", Div) \
X("%", Mod) \
X("^", Pow) \
X("<", Ls) \
X(">", Gr) \
X("<=", LsEq) \
X(">=", GrEq) \
X("==", Eq) \
X("!=", NotEq) \
X("not", Not) \
X("and", And) \
X("or", Or) \
X("ceil", Ceil) \
X("floor", Floor) \
X("round", Round)
typedef enum{
C_BuiltInIndex_Nil,
#define EnumMember(N,F) C_BuiltInIndex_##F,
C_BuiltInXList(EnumMember)
#undef EnumMember
C_BuiltInIndex_COUNT,
} C_BuiltInIndex;
typedef struct C_Statics C_Statics;
struct C_Statics{
union{
struct{
C_Cell *Nil;
#define StaticMember(N,F) C_Cell *F;
C_BuiltInXList(StaticMember)
#undef StaticMember
};
C_Cell *built_in[C_BuiltInIndex_COUNT];
};
C_Cell *env;
};
////////////////////////////////
typedef struct C_EvalCtx C_EvalCtx;
struct C_EvalCtx{
C_Statics *statics;
C_CellBucket *bucket;
C_Cell *id_env;
C_Cell *regs;
u64 max_depth;
u64 depth;
u64 loop_lim;
C_Id reg_id_counter;
};
#endif //COMPUTE_H