Multiple implementations (JS, Wasm, C) of a Lisp.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

264 lines
6.9 KiB

#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