Initial commit
This commit is contained in:
		
							
								
								
									
										24
									
								
								include/lisp/array.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								include/lisp/array.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| #ifndef INCLUDED_ARRAY_H | ||||
| #define INCLUDED_ARRAY_H | ||||
|  | ||||
| #include "lisp/object.h" | ||||
| #include "lisp/util.h" | ||||
|  | ||||
| LISP_BEGIN_DECLS | ||||
|  | ||||
| DECLARE_CLASS(Array); | ||||
|  | ||||
| struct Array { | ||||
|     Object base; | ||||
|     size_t length; | ||||
|     void *value; | ||||
| }; | ||||
| struct ArrayClass { | ||||
|     Class base; | ||||
|     Object *(*length)(Object *self); | ||||
|     Object *(*elt)(Object *self, Object *index); | ||||
|     Object *(*aset)(Object *self, Object *index, Object *value); | ||||
| }; | ||||
|  | ||||
| LISP_END_DECLS | ||||
| #endif | ||||
							
								
								
									
										24
									
								
								include/lisp/function.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								include/lisp/function.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| #ifndef INCLUDED_FUNCTION_H | ||||
| #define INCLUDED_FUNCTION_H | ||||
|  | ||||
| #include "lisp/hashtable.h" | ||||
| #include "lisp/object.h" | ||||
| #include "lisp/util.h" | ||||
|  | ||||
| LISP_BEGIN_DECLS | ||||
|  | ||||
| DECLARE_CLASS(Function); | ||||
|  | ||||
| struct Function { | ||||
|     Object base; | ||||
|     Object *req_args; | ||||
|     Object *opt_args; | ||||
|     Object *kw_args; | ||||
|     Hashtable *arg_props; | ||||
| }; | ||||
| struct FunctionClass { | ||||
|     Class base; | ||||
| }; | ||||
|  | ||||
| LISP_END_DECLS | ||||
| #endif | ||||
							
								
								
									
										20
									
								
								include/lisp/hashtable.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								include/lisp/hashtable.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| #ifndef INCLUDED_HASHTABLE_H | ||||
| #define INCLUDED_HASHTABLE_H | ||||
|  | ||||
| #include "lisp/object.h" | ||||
| #include "lisp/util.h" | ||||
|  | ||||
| LISP_BEGIN_DECLS | ||||
|  | ||||
| DECLARE_CLASS(Hashtable); | ||||
|  | ||||
| struct Hashtable { | ||||
|     Object base; | ||||
|     HTTable *table; | ||||
| }; | ||||
| struct HashtableClass { | ||||
|     Class base; | ||||
| }; | ||||
|  | ||||
| LISP_END_DECLS | ||||
| #endif | ||||
							
								
								
									
										139
									
								
								include/lisp/method_macro.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								include/lisp/method_macro.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,139 @@ | ||||
| #ifndef INCLUDED_METHOD_MACRO_H | ||||
| #define INCLUDED_METHOD_MACRO_H | ||||
|  | ||||
| #if __has_attribute(always_inline) | ||||
| #    define always_inline inline __attribute__((always_inline)) | ||||
| #else | ||||
| #    define always_inline inline | ||||
| #endif | ||||
|  | ||||
| #if __has_attribute(unused) | ||||
| #    define UNUSED __attribute__((unused)) | ||||
| #else | ||||
| #    define UNUSED | ||||
| #endif | ||||
|  | ||||
| // clang-format off | ||||
| #define _ELEVENTH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, ...) a11 | ||||
| #define _COUNT_ARGS(...) _ELEVENTH(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) | ||||
| #define _GLUE(a, b) a##b | ||||
| #define _GLUE2(a, b) _GLUE(a, b) | ||||
| #define _IGNORE(...) | ||||
| #define _REMOVE_FIRST(a1, ...) __VA_ARGS__ | ||||
| #define _EVAL(...) __VA_ARGS__ | ||||
| // clang-format on | ||||
|  | ||||
| // This is needed because C11 doesn't allow empty __VA_ARGS__ | ||||
| #define _GET_1_1(a1)                     a1 | ||||
| #define _GET_1_2(a1, a2)                 a1 | ||||
| #define _GET_1_3(a1, a2, a3)             a1 | ||||
| #define _GET_1_4(a1, a2, a3, a4)         a1 | ||||
| #define _GET_1_5(a1, a2, a3, a4, a5)     a1 | ||||
| #define _GET_1_6(a1, a2, a3, a4, a5, a6) a1 | ||||
|  | ||||
| #define _GET_2_2(a1, a2)                 a2 | ||||
| #define _GET_2_3(a1, a2, a3)             a2 | ||||
| #define _GET_2_4(a1, a2, a3, a4)         a2 | ||||
| #define _GET_2_5(a1, a2, a3, a4, a5)     a2 | ||||
| #define _GET_2_6(a1, a2, a3, a4, a5, a6) a2 | ||||
|  | ||||
| #define _GET_3_3(a1, a2, a3)             a3 | ||||
| #define _GET_3_4(a1, a2, a3, a4)         a3 | ||||
| #define _GET_3_5(a1, a2, a3, a4, a5)     a3 | ||||
| #define _GET_3_6(a1, a2, a3, a4, a5, a6) a3 | ||||
|  | ||||
| #define _GET_4_4(a1, a2, a3, a4)         a4 | ||||
| #define _GET_4_5(a1, a2, a3, a4, a5)     a4 | ||||
| #define _GET_4_6(a1, a2, a3, a4, a5, a6) a4 | ||||
|  | ||||
| #define _GET_5_5(a1, a2, a3, a4, a5)     a5 | ||||
| #define _GET_5_6(a1, a2, a3, a4, a5, a6) a5 | ||||
|  | ||||
| #define _GET_6_6(a1, a2, a3, a4, a5, a6) a6 | ||||
|  | ||||
| #define _GET_NTH(n, args) \ | ||||
|     _EVAL(_GLUE2(_GLUE2(_GLUE2(_GET_, n), _), _COUNT_ARGS args) args) | ||||
|  | ||||
| #define METHOD_CALLBACK_NAME(name) _##name##__as_callback | ||||
|  | ||||
| #define _CB_DECL_ARGS_1        Object * | ||||
| #define _CB_DECL_ARGS_2        Object *, _CB_DECL_ARGS_1 | ||||
| #define _CB_DECL_ARGS_3        Object *, _CB_DECL_ARGS_2 | ||||
| #define _CB_DECL_ARGS_4        Object *, _CB_DECL_ARGS_3 | ||||
| #define _CB_DECL_ARGS_5        Object *, _CB_DECL_ARGS_4 | ||||
| #define _CB_DECL_ARGS_6        Object *, _CB_DECL_ARGS_5 | ||||
| #define _CB_DECL_ARGS_N(count) (_GLUE(_CB_DECL_ARGS_, count)) | ||||
| #define _CB_DECL_ARGS_FOR(...) _CB_DECL_ARGS_N(_COUNT_ARGS(__VA_ARGS__)) | ||||
| #define _GEN_CB_DECL(name, args)       \ | ||||
|     Object *METHOD_CALLBACK_NAME(name) \ | ||||
|     _CB_DECL_ARGS_FOR args | ||||
|  | ||||
| #define _ARG_NAME_1(args)    _IGNORE _GET_NTH(1, args) | ||||
| #define _ARG_NAME_2(args)    _IGNORE _GET_NTH(2, args) | ||||
| #define _ARG_NAME_3(args)    _IGNORE _GET_NTH(3, args) | ||||
| #define _ARG_NAME_4(args)    _IGNORE _GET_NTH(4, args) | ||||
| #define _ARG_NAME_5(args)    _IGNORE _GET_NTH(5, args) | ||||
| #define _ARG_NAME_6(args)    _IGNORE _GET_NTH(6, args) | ||||
| #define _ARG_NAME_N(n, args) _EVAL(_GLUE(_ARG_NAME_, n)(args)) | ||||
|  | ||||
| #define _VOID_ARG_N(n, args)  (void *) _ARG_NAME_N(n, args) | ||||
| #define _CALL_ARGS_1(args)    _VOID_ARG_N(1, args) | ||||
| #define _CALL_ARGS_2(args)    _CALL_ARGS_1(args), _VOID_ARG_N(2, args) | ||||
| #define _CALL_ARGS_3(args)    _CALL_ARGS_2(args), _VOID_ARG_N(3, args) | ||||
| #define _CALL_ARGS_4(args)    _CALL_ARGS_3(args), _VOID_ARG_N(4, args) | ||||
| #define _CALL_ARGS_5(args)    _CALL_ARGS_4(args), _VOID_ARG_N(5, args) | ||||
| #define _CALL_ARGS_6(args)    _CALL_ARGS_5(args), _VOID_ARG_N(6, args) | ||||
| #define _CALL_ARGS_N(n, args) _GLUE(_CALL_ARGS_, n)(args) | ||||
| #define _GEN_REAL_CALL(name, args) \ | ||||
|     METHOD_CALLBACK_NAME(name)(_CALL_ARGS_N(_COUNT_ARGS args, args)) | ||||
|  | ||||
| #define _UNWRAP_TYPE(arg)       _EVAL arg | ||||
| #define _UNWRAP_ARG_N(n, args)  _UNWRAP_TYPE(_GET_NTH(n, args)) | ||||
| #define _UNWRAP_ARGS_1(args)    _UNWRAP_ARG_N(1, args) | ||||
| #define _UNWRAP_ARGS_2(args)    _UNWRAP_ARGS_1(args), _UNWRAP_ARG_N(2, args) | ||||
| #define _UNWRAP_ARGS_3(args)    _UNWRAP_ARGS_2(args), _UNWRAP_ARG_N(3, args) | ||||
| #define _UNWRAP_ARGS_4(args)    _UNWRAP_ARGS_3(args), _UNWRAP_ARG_N(4, args) | ||||
| #define _UNWRAP_ARGS_5(args)    _UNWRAP_ARGS_4(args), _UNWRAP_ARG_N(5, args) | ||||
| #define _UNWRAP_ARGS_6(args)    _UNWRAP_ARGS_5(args), _UNWRAP_ARG_N(6, args) | ||||
| #define _UNWRAP_ARGS_N(n, args) _GLUE(_UNWRAP_ARGS_, n)(args) | ||||
| #define _UNWRAP_ARGS(args)      _UNWRAP_ARGS_N(_COUNT_ARGS args, args) | ||||
|  | ||||
| #define _METHOD_RAW(rtype, ret_stmt, name, args)          \ | ||||
|     _GEN_CB_DECL(name, args);                             \ | ||||
|     static always_inline rtype name(_UNWRAP_ARGS(args)) { \ | ||||
|         ret_stmt _GEN_REAL_CALL(name, args);              \ | ||||
|     }                                                     \ | ||||
|     struct __dummy_struct | ||||
|  | ||||
| #define METHOD(rtype, name, args) _METHOD_RAW(rtype, return (rtype), name, args) | ||||
| #define VOID_METHOD(name, args)   _METHOD_RAW(void, , name, args) | ||||
|  | ||||
| #define _CB_DEF_ARGS_1        Object *_internal_arg1 | ||||
| #define _CB_DEF_ARGS_2        _CB_DEF_ARGS_1, Object *_internal_arg2 | ||||
| #define _CB_DEF_ARGS_3        _CB_DEF_ARGS_2, Object *_internal_arg3 | ||||
| #define _CB_DEF_ARGS_4        _CB_DEF_ARGS_3, Object *_internal_arg4 | ||||
| #define _CB_DEF_ARGS_5        _CB_DEF_ARGS_4, Object *_internal_arg5 | ||||
| #define _CB_DEF_ARGS_6        _CB_DEF_ARGS_5, Object *_internal_arg6 | ||||
| #define _CB_DEF_ARGS_N(count) (_GLUE(_CB_DEF_ARGS_, count)) | ||||
| #define _CB_DEF_ARGS_FOR(...) _CB_DEF_ARGS_N(_COUNT_ARGS(__VA_ARGS__)) | ||||
| #define _GEN_CB_DEF(name, args)        \ | ||||
|     Object *METHOD_CALLBACK_NAME(name) \ | ||||
|     _CB_DEF_ARGS_FOR args | ||||
|  | ||||
| #define _SET_NTH_ARG(n, args) \ | ||||
|     UNUSED _GET_NTH(n, args) = (void *) _internal_arg##n; | ||||
| #define _SET_ARGS_1(args)    _SET_NTH_ARG(1, args) | ||||
| #define _SET_ARGS_2(args)    _SET_ARGS_1(args) _SET_NTH_ARG(2, args) | ||||
| #define _SET_ARGS_3(args)    _SET_ARGS_2(args) _SET_NTH_ARG(3, args) | ||||
| #define _SET_ARGS_4(args)    _SET_ARGS_3(args) _SET_NTH_ARG(4, args) | ||||
| #define _SET_ARGS_5(args)    _SET_ARGS_4(args) _SET_NTH_ARG(5, args) | ||||
| #define _SET_ARGS_6(args)    _SET_ARGS_5(args) _SET_NTH_ARG(6, args) | ||||
| #define _SET_ARGS_N(n, args) _GLUE(_SET_ARGS_, n)(args) | ||||
|  | ||||
| #define DEFINE_METHOD(rtype, name, args, body) \ | ||||
|     _GEN_CB_DEF(name, args) {                  \ | ||||
|         _SET_ARGS_N(_COUNT_ARGS args, args)    \ | ||||
|         body                                   \ | ||||
|     } | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										42
									
								
								include/lisp/number.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								include/lisp/number.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | ||||
| #ifndef INCLUDED_NUMBER_H | ||||
| #define INCLUDED_NUMBER_H | ||||
|  | ||||
| #include "lisp/object.h" | ||||
| #include "lisp/util.h" | ||||
|  | ||||
| LISP_BEGIN_DECLS | ||||
|  | ||||
| DECLARE_CLASS(Number); | ||||
| DECLARE_CLASS(Float); | ||||
| DECLARE_CLASS(Integer); | ||||
|  | ||||
| struct Number { | ||||
|     Object base; | ||||
| }; | ||||
| struct NumberClass { | ||||
|     Class base; | ||||
|  | ||||
|     Object *(*add)(Object *self, Object *other); | ||||
|     Object *(*sub)(Object *self, Object *other); | ||||
| }; | ||||
|  | ||||
| struct Float { | ||||
|     Number base; | ||||
|  | ||||
|     double value; | ||||
| }; | ||||
| struct FloatClass { | ||||
|     NumberClass base; | ||||
| }; | ||||
|  | ||||
| struct Integer { | ||||
|     Number base; | ||||
|  | ||||
|     int64_t value; | ||||
| }; | ||||
| struct IntegerClass { | ||||
|     NumberClass base; | ||||
| }; | ||||
|  | ||||
| LISP_END_DECLS | ||||
| #endif | ||||
							
								
								
									
										73
									
								
								include/lisp/object.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								include/lisp/object.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,73 @@ | ||||
| #ifndef INCLUDED_OBJECT_H | ||||
| #define INCLUDED_OBJECT_H | ||||
|  | ||||
| #include "lisp/method_macro.h" | ||||
| #include "lisp/util.h" | ||||
|  | ||||
| #include <ht.h> | ||||
| #include <refcount/refcount.h> | ||||
| #include <stddef.h> | ||||
|  | ||||
| LISP_BEGIN_DECLS | ||||
|  | ||||
| #define DECLARE_CLASS(Name)   \ | ||||
|     typedef struct Name Name; \ | ||||
|     typedef struct Name##Class Name##Class | ||||
|  | ||||
| // clang-format off | ||||
| #define ELEVENTH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, ...) a11 | ||||
| #define COUNT_ARGS(...) ELLEVENTH(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) | ||||
| // clang-format on | ||||
|  | ||||
| #undef COUNT_ARGS | ||||
| #undef TENTH | ||||
|  | ||||
| typedef struct Object Object; | ||||
| typedef struct Class Class; | ||||
|  | ||||
| struct Object { | ||||
|     RefcountEntry refcount; | ||||
|     Class *class; | ||||
|  | ||||
|     Object **slots; | ||||
| }; | ||||
|  | ||||
| struct Class { | ||||
|     Object base; | ||||
|     Class *superclass; | ||||
|     HTTable *subclasses; | ||||
|     size_t object_size; | ||||
|  | ||||
|     HTTable *slots_indicies; | ||||
|     uint64_t nslots; | ||||
|     HTTable *methods; | ||||
|  | ||||
|     Object *(*construct)(Object *self, Object *args); | ||||
| }; | ||||
|  | ||||
| Object *make_object(Object *class, Object *args); | ||||
|  | ||||
| DECLARE_CLASS(Pair); | ||||
|  | ||||
| struct Pair { | ||||
|     Object base; | ||||
|  | ||||
|     Object *head; | ||||
|     Object *tail; | ||||
| }; | ||||
| struct PairClass { | ||||
|     Class base; | ||||
|  | ||||
|     Object *(*head)(Object *self); | ||||
|     Object *(*sethead)(Object *self, Object *new_head); | ||||
|     Object *(*tail)(Object *self); | ||||
|     Object *(*settail)(Object *self, Object *new_tail); | ||||
| }; | ||||
|  | ||||
| METHOD(Object *, head, ((Pair *) self)); | ||||
| VOID_METHOD(sethead, ((Pair *) self)); | ||||
| METHOD(Object *, tail, ((Pair *) self)); | ||||
| VOID_METHOD(settail, ((Pair *) self)); | ||||
|  | ||||
| LISP_END_DECLS | ||||
| #endif | ||||
							
								
								
									
										20
									
								
								include/lisp/string.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								include/lisp/string.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| #ifndef INCLUDED_STRING_H | ||||
| #define INCLUDED_STRING_H | ||||
|  | ||||
| #include "lisp/array.h" | ||||
| #include "lisp/util.h" | ||||
|  | ||||
| LISP_BEGIN_DECLS | ||||
|  | ||||
| DECLARE_CLASS(String); | ||||
|  | ||||
| struct String { | ||||
|     Array base; | ||||
|     bool borrowed; | ||||
| }; | ||||
| struct StringClass { | ||||
|     ArrayClass base; | ||||
| }; | ||||
|  | ||||
| LISP_END_DECLS | ||||
| #endif | ||||
							
								
								
									
										32
									
								
								include/lisp/symbol.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								include/lisp/symbol.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | ||||
| #ifndef INCLUDED_SYMBOL_H | ||||
| #define INCLUDED_SYMBOL_H | ||||
|  | ||||
| #include "lisp/function.h" | ||||
| #include "lisp/object.h" | ||||
| #include "lisp/string.h" | ||||
| #include "lisp/util.h" | ||||
|  | ||||
| LISP_BEGIN_DECLS | ||||
|  | ||||
| DECLARE_CLASS(Symbol); | ||||
|  | ||||
| struct Symbol { | ||||
|     Object base; | ||||
|     String *name; | ||||
|  | ||||
|     Object *value; | ||||
|     Class *class; | ||||
|     Function *func; | ||||
|     Object *plist; | ||||
| }; | ||||
| struct SymbolClass { | ||||
|     Class base; | ||||
|  | ||||
|     Object *(*value)(Object *self); | ||||
|     Object *(*class)(Object *self); | ||||
|     Object *(*function)(Object *self); | ||||
|     Object *(*plist)(Object *self); | ||||
| }; | ||||
|  | ||||
| LISP_END_DECLS | ||||
| #endif | ||||
							
								
								
									
										12
									
								
								include/lisp/util.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								include/lisp/util.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| #ifndef INCLUDED_UTIL_H | ||||
| #define INCLUDED_UTIL_H | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| #    define LISP_BEGIN_DECLS extern "C" { | ||||
| #    define LISP_END_DECLS   } | ||||
| #else | ||||
| #    define LISP_BEGIN_DECLS | ||||
| #    define LISP_END_DECLS | ||||
| #endif | ||||
|  | ||||
| #endif | ||||
		Reference in New Issue
	
	Block a user