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
						
					
					
				
			
		
		
	
	
							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
 | 
						|
 |