#ifndef LISP_H #define LISP_H #include <stdio.h> #include <stdbool.h> #include <stdarg.h> typedef enum { CHAR, // 0 SYMBOL, // 1 NUMBER, // 2 NATIVE_FUNC, // 3 SPECIAL_FORM, // 4 STREAM, // 5 FUNC, // 6 MACRO, // 7 STRING, // 8 TABLE, // 9 ARRAY, // 10 CONS, // 11 ERROR, // 12 TYPE_ALL // 13 } Type; typedef unsigned Pointer; typedef unsigned Char; typedef struct { Pointer car, cdr; } Cons; typedef double Number; typedef struct { unsigned length; char data[]; } Symbol; typedef struct { unsigned length; char data[]; } String; typedef struct { unsigned length; char data[]; } Error; typedef struct { unsigned length, size; Pointer data[]; } Array; typedef struct { Pointer code, env; } Func; typedef struct { unsigned offset, length; } TableHash; typedef struct { Pointer key, value; } TablePair; typedef union { TableHash hash; TablePair pair; } TableData; typedef struct { unsigned length, size; TableData data[]; } Table; /* CHANGER POUR TABLEAU DE FONCTIONS */ typedef Pointer (*NativeFunc)(Pointer params, Pointer env); typedef Pointer (*SpecialForm)(Pointer params, Pointer env); typedef FILE* Stream; typedef union { Cons cons; Symbol symbol; Number number; Table table; NativeFunc nativeFunc; SpecialForm specialForm; Func func; String string; Stream stream; Array array; Char c; Error error; Pointer next; } Data; typedef struct { /* Header header; */ Type type: 4; bool garbage: 1; size_t size: sizeof(size_t) * 8 - 5; Data data[]; } Block; // 16 Bytes typedef struct Memory { Block* buffer; Pointer freelist; size_t used, size; // Actual bytes } Memory; extern Pointer NIL; extern Pointer UNDEFINED; extern Pointer T; extern Pointer STANDARD_INPUT; extern Pointer STANDARD_OUTPUT; extern Pointer BODY; extern Pointer REST; /** UTILS **/ void init(void); void memory_init(size_t); void symbol_init(void); void reader_init(void); void environment_init(void); void memory_free(void); Block* memory_get(Pointer); Pointer memory_new(Type, size_t); void memory_destroy(Pointer); Pointer memory_resize(Pointer, size_t); void repl(void); Pointer array_push(Pointer, Pointer); Pointer array_pop(Pointer); Pointer array_set(Pointer, size_t, Pointer); Pointer array_get(Pointer, size_t); size_t array_length(Pointer); Pointer table_get(Pointer, Pointer); Pointer table_set(Pointer, Pointer, Pointer); Pointer string_push(Pointer str, char c); Pointer string_clear(Pointer str); Pointer environment_get(Pointer env, Pointer key); Pointer environment_set(Pointer env, Pointer key, Pointer value); Char get_utf8(FILE* s); Char unget_utf8(Char c, FILE* s); Char peek_char(Pointer type, Stream stream); Pointer read_char_macro(Pointer args, Pointer env); Pointer read_list_macro(Pointer args, Pointer env); Pointer read_right_paren_macro(Pointer args, Pointer env); Pointer prin1(Pointer data, Stream stream); Pointer print(Pointer data, Stream stream); Pointer eval(Pointer data, Pointer env); /* CONSTRUCTORS */ Pointer array(size_t size); Pointer table(size_t size); Pointer symbol(char* string, size_t size); #define symbol1(s) symbol(s, sizeof(s) - 1) Pointer string(char* string, size_t size); Pointer cons(Pointer car, Pointer cdr); Pointer number(Number num); Pointer func(Pointer code, Pointer env); Pointer macro(Pointer code, Pointer env); Pointer native_func(NativeFunc func); Pointer special_form(SpecialForm func); Pointer character(Char c); Pointer stream(FILE* s); /* FUNCTIONS */ Pointer eval_fn(Pointer args, Pointer env); Pointer cons_fn(Pointer args, Pointer env); Pointer car_fn(Pointer args, Pointer env); Pointer cdr_fn(Pointer args, Pointer env); Pointer reduce_fn(Pointer args, Pointer env); Pointer list_fn(Pointer args, Pointer env); Pointer add_fn(Pointer args, Pointer env); Pointer sub_fn(Pointer args, Pointer env); Pointer mul_fn(Pointer args, Pointer env); Pointer div_fn(Pointer args, Pointer env); Pointer pow_fn(Pointer args, Pointer env); Pointer sqrt_fn(Pointer args, Pointer env); Pointer logand_fn(Pointer args, Pointer env); Pointer logor_fn(Pointer args, Pointer env); Pointer logxor_fn(Pointer args, Pointer env); Pointer lognot_fn(Pointer args, Pointer env); Pointer peek_char_fn(Pointer args, Pointer env); Pointer read_char_fn(Pointer args, Pointer env); Pointer read_fn(Pointer args, Pointer env); Pointer set_reader_macro_fn(Pointer args, Pointer env); Pointer print_fn(Pointer args, Pointer env); Pointer not_fn(Pointer args, Pointer env); Pointer exit_fn(Pointer args, Pointer env); Pointer eq_fn(Pointer args, Pointer env); Pointer lt_fn(Pointer args, Pointer env); Pointer gt_fn(Pointer args, Pointer env); Pointer le_fn(Pointer args, Pointer env); Pointer ge_fn(Pointer args, Pointer env); /* SPECIAL FORMS */ Pointer if_fn(Pointer args, Pointer env); Pointer let_fn(Pointer args, Pointer env); Pointer quote_fn(Pointer args, Pointer env); Pointer and_fn(Pointer args, Pointer env); Pointer or_fn(Pointer args, Pointer env); Pointer def_fn(Pointer args, Pointer env); Pointer set_fn(Pointer args, Pointer env); Pointer fn_fn(Pointer args, Pointer env); Pointer defmacro_fn(Pointer args, Pointer env); #define TYPE(p) memory_get(p)->type #define SIZE(p) memory_get(p)->size #define GET(p) memory_get(p)->data #define NEXT(p) GET(p)->next #define CONS(p) GET(p)->cons #define NUMBER(p) GET(p)->number #define SYMBOL(p) GET(p)->symbol #define STRING(p) GET(p)->string #define CHAR(p) GET(p)->c #define ARRAY(p) GET(p)->array #define TABLE(p) GET(p)->table #define SPECIAL_FORM(p) GET(p)->specialForm #define NATIVE_FUNC(p) GET(p)->nativeFunc #define FUNC(p) GET(p)->func #define STREAM(p) GET(p)->stream #define CAR(p) (p == NIL ? NIL : CONS(p).car) #define CDR(p) (p == NIL ? NIL : CONS(p).cdr) #define ELEVENTH_ARGUMENT(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, ...) a11 #define COUNT_ARGUMENTS(...) ELEVENTH_ARGUMENT(dummy, ## __VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) /* #define LIST(...) list_new(COUNT_ARGUMENTS(__VA_ARGS__), __VA_ARGS__) */ #define LIST_0 NIL #define LIST_1(a) cons(a, LIST_0) #define LIST_2(a, ...) cons(a, LIST_1(__VA_ARGS__)) #define LIST_3(a, ...) cons(a, LIST_2(__VA_ARGS__)) #define LIST_4(a, ...) cons(a, LIST_3(__VA_ARGS__)) #define LIST_5(a, ...) cons(a, LIST_4(__VA_ARGS__)) #define LIST_6(a, ...) cons(a, LIST_5(__VA_ARGS__)) #define LIST_7(a, ...) cons(a, LIST_6(__VA_ARGS__)) #define LIST_8(a, ...) cons(a, LIST_7(__VA_ARGS__)) #define LIST_9(a, ...) cons(a, LIST_8(__VA_ARGS__)) #define LIST__(n, ...) LIST_##n(__VA_ARGS__) #define LIST_(n, ...) LIST__(n, __VA_ARGS__) #define LIST(...) LIST_(COUNT_ARGUMENTS(__VA_ARGS__), __VA_ARGS__) #define REDUCE(list, reducer, previous) \ while(list != NIL) { \ previous = reducer; \ list = CDR(list); \ } #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) #define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) #endif