klisp

an open source interpreter for the Kernel Programming Language.
git clone http://git.hanabi.in/repos/klisp.git
Log | Files | Refs | README

commit b6859d87dfca3b9db76ddd9a25e477c44501a566
parent c3b0290830bfa29735f712d150571b07775042c8
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Mon, 18 Apr 2011 18:32:08 -0300

Added Table object definition (hashtables from lua). Changed flag in header to kflag to avoid naming conflict with the like named field in tables.

Diffstat:
Msrc/kgc.c | 6+++---
Msrc/kobject.h | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
2 files changed, 74 insertions(+), 27 deletions(-)

diff --git a/src/kgc.c b/src/kgc.c @@ -756,13 +756,13 @@ void klispC_barrierback (lua_State *L, Table *t) { } #endif -/* NOTE: flags is added for klisp */ -void klispC_link (klisp_State *K, GCObject *o, uint8_t tt, uint8_t flags) { +/* NOTE: kflags is added for klisp */ +void klispC_link (klisp_State *K, GCObject *o, uint8_t tt, uint8_t kflags) { o->gch.next = K->rootgc; K->rootgc = o; o->gch.gct = klispC_white(K); o->gch.tt = tt; - o->gch.flags = flags; + o->gch.kflags = kflags; /* NOTE that o->gch.gclist doesn't need to be setted */ } diff --git a/src/kobject.h b/src/kobject.h @@ -44,11 +44,11 @@ typedef union GCObject GCObject; ** Common Header for all collectible objects (in macro form, to be ** included in other objects) */ -#define CommonHeader GCObject *next; uint8_t tt; uint8_t flags; \ +#define CommonHeader GCObject *next; uint8_t tt; uint8_t kflags; \ uint16_t gct; uint32_t padding; GCObject *gclist; /* NOTE: the gc flags are called marked in lua, but we reserve that them - for marks used in cycle traversal. The field flags is also missing + for marks used in cycle traversal. The field kflags is also missing from lua, they serve as compact bool fields for certain types */ /* @@ -160,6 +160,7 @@ typedef struct __attribute__ ((__packed__)) GCheader { #define K_TENCAPSULATION 37 #define K_TPROMISE 38 #define K_TPORT 39 +#define K_TTABLE 40 /* this is used to test for numbers, as returned by ttype */ #define K_LAST_NUMBER_TYPE K_TCOMPLEX @@ -202,6 +203,7 @@ typedef struct __attribute__ ((__packed__)) GCheader { #define K_TAG_ENCAPSULATION K_MAKE_VTAG(K_TENCAPSULATION) #define K_TAG_PROMISE K_MAKE_VTAG(K_TPROMISE) #define K_TAG_PORT K_MAKE_VTAG(K_TPORT) +#define K_TAG_TABLE K_MAKE_VTAG(K_TTABLE) /* @@ -254,6 +256,7 @@ typedef struct __attribute__ ((__packed__)) GCheader { #define ttisencapsulation(o) (tbasetype_(o) == K_TAG_ENCAPSULATION) #define ttispromise(o) (tbasetype_(o) == K_TAG_PROMISE) #define ttisport(o) (tbasetype_(o) == K_TAG_PORT) +#define ttistable(o) (tbasetype_(o) == K_TAG_TABLE) /* macros to easily check boolean values */ #define kis_true(o_) (tv_equal((o_), KTRUE)) @@ -384,7 +387,7 @@ typedef struct __attribute__ ((__packed__)) { sharing the pair */ } Promise; -/* input/output direction and open/close status are in flags */ +/* input/output direction and open/close status are in kflags */ typedef struct __attribute__ ((__packed__)) { CommonHeader; TValue name; @@ -393,6 +396,47 @@ typedef struct __attribute__ ((__packed__)) { FILE *file; } Port; +/* input/output direction and open/close status are in kflags */ + +/* +** Hashtables +*/ + +typedef union TKey { + struct { + TValue this; /* different from lua because of the tagging scheme */ + struct Node *next; /* for chaining */ + } nk; + TValue tvk; +} TKey; + +typedef struct Node { + TValue i_val; + TKey i_key; +} Node; + +typedef struct __attribute__ ((__packed__)) { + CommonHeader; + uint8_t flags; /* 1<<p means tagmethod(p) is not present */ + uint8_t lsizenode; /* log2 of size of `node' array */ + uint16_t tpadding; /* to avoid disturbing the alignment */ + struct Table *metatable; /* is this necessary in klisp? */ + TValue *array; /* array part */ + Node *node; + Node *lastfree; /* any free position is before this position */ + int32_t sizearray; /* size of `array' array */ +} Table; + +/* +** `module' operation for hashing (size is always a power of 2) +*/ +#define lmod(s,size) \ + (check_exp((size&(size-1))==0, (cast(int32_t, (s) & ((size)-1))))) + + +#define twoto(x) (1<<(x)) +#define sizenode(t) (twoto((t)->lsizenode)) + /* ** RATIONALE: ** @@ -433,6 +477,7 @@ union GCObject { Encapsulation enc; Promise prom; Port port; + Table table; }; @@ -504,6 +549,7 @@ const TValue knewline; #define gc2enc(o_) (gc2tv(K_TAG_ENCAPSULATION, o_)) #define gc2prom(o_) (gc2tv(K_TAG_PROMISE, o_)) #define gc2port(o_) (gc2tv(K_TAG_PORT, o_)) +#define gc2table(o_) (gc2tv(K_TAG_TABLE, o_)) /* Macro to convert a TValue into a specific heap allocated object */ #define tv2bigint(v_) ((Bigint *) gcvalue(v_)) @@ -517,6 +563,7 @@ const TValue knewline; #define tv2enc(v_) ((Encapsulation *) gcvalue(v_)) #define tv2prom(v_) ((Promise *) gcvalue(v_)) #define tv2port(v_) ((Port *) gcvalue(v_)) +#define tv2table(v_) ((Table *) gcvalue(v_)) #define tv2gch(v_) ((GCheader *) gcvalue(v_)) #define tv2mgch(v_) ((MGCheader *) gcvalue(v_)) @@ -568,48 +615,48 @@ int32_t kmark_count; #define kis_marked(p_) (!kis_unmarked(p_)) #define kis_unmarked(p_) (tv_equal(kget_mark(p_), KFALSE)) -/* Macros to access flags & type in GCHeader */ +/* Macros to access kflags & type in GCHeader */ #define gch_get_type(o_) (obj2gch(o_)->tt) -#define gch_get_flags(o_) (obj2gch(o_)->flags) -#define tv_get_flags(o_) (gch_get_flags(tv2gch(o_))) +#define gch_get_kflags(o_) (obj2gch(o_)->kflags) +#define tv_get_kflags(o_) (gch_get_kflags(tv2gch(o_))) -/* Flags for symbols */ +/* KFlags for symbols */ /* has external representation (identifiers) */ #define K_FLAG_EXT_REP 0x01 -#define khas_ext_rep(s_) ((tv_get_flags(s_) & K_FLAG_EXT_REP) != 0) +#define khas_ext_rep(s_) ((tv_get_kflags(s_) & K_FLAG_EXT_REP) != 0) -/* Flags for marking continuations */ +/* KFlags for marking continuations */ #define K_FLAG_OUTER 0x01 #define K_FLAG_INNER 0x02 #define K_FLAG_DYNAMIC 0x04 #define K_FLAG_BOOL_CHECK 0x08 /* evaluate c_ more than once */ -#define kset_inner_cont(c_) (tv_get_flags(c_) |= K_FLAG_INNER) -#define kset_outer_cont(c_) (tv_get_flags(c_) |= K_FLAG_OUTER) -#define kset_dyn_cont(c_) (tv_get_flags(c_) |= K_FLAG_DYNAMIC) -#define kset_bool_check_cont(c_) (tv_get_flags(c_) |= K_FLAG_BOOL_CHECK) +#define kset_inner_cont(c_) (tv_get_kflags(c_) |= K_FLAG_INNER) +#define kset_outer_cont(c_) (tv_get_kflags(c_) |= K_FLAG_OUTER) +#define kset_dyn_cont(c_) (tv_get_kflags(c_) |= K_FLAG_DYNAMIC) +#define kset_bool_check_cont(c_) (tv_get_kflags(c_) |= K_FLAG_BOOL_CHECK) -#define kis_inner_cont(c_) ((tv_get_flags(c_) & K_FLAG_INNER) != 0) -#define kis_outer_cont(c_) ((tv_get_flags(c_) & K_FLAG_OUTER) != 0) -#define kis_dyn_cont(c_) ((tv_get_flags(c_) & K_FLAG_DYNAMIC) != 0) -#define kis_bool_check_cont(c_) ((tv_get_flags(c_) & K_FLAG_BOOL_CHECK) != 0) +#define kis_inner_cont(c_) ((tv_get_kflags(c_) & K_FLAG_INNER) != 0) +#define kis_outer_cont(c_) ((tv_get_kflags(c_) & K_FLAG_OUTER) != 0) +#define kis_dyn_cont(c_) ((tv_get_kflags(c_) & K_FLAG_DYNAMIC) != 0) +#define kis_bool_check_cont(c_) ((tv_get_kflags(c_) & K_FLAG_BOOL_CHECK) != 0) #define K_FLAG_IMMUTABLE 0x01 -#define kis_mutable(o_) ((tv_get_flags(o_) & K_FLAG_IMMUTABLE) == 0) +#define kis_mutable(o_) ((tv_get_kflags(o_) & K_FLAG_IMMUTABLE) == 0) #define kis_immutable(o_) (!kis_mutable(o_)) #define K_FLAG_OUTPUT_PORT 0x01 #define K_FLAG_INPUT_PORT 0x02 #define K_FLAG_CLOSED_PORT 0x04 -#define kport_set_input(o_) (tv_get_flags(o_) |= K_FLAG_INPUT_PORT) -#define kport_set_output(o_) (tv_get_flags(o_) |= K_FLAG_INPUT_PORT) -#define kport_set_closed(o_) (tv_get_flags(o_) |= K_FLAG_CLOSED_PORT) +#define kport_set_input(o_) (tv_get_kflags(o_) |= K_FLAG_INPUT_PORT) +#define kport_set_output(o_) (tv_get_kflags(o_) |= K_FLAG_INPUT_PORT) +#define kport_set_closed(o_) (tv_get_kflags(o_) |= K_FLAG_CLOSED_PORT) -#define kport_is_input(o_) ((tv_get_flags(o_) & K_FLAG_INPUT_PORT) != 0) -#define kport_is_output(o_) ((tv_get_flags(o_) & K_FLAG_OUTPUT_PORT) != 0) -#define kport_is_closed(o_) ((tv_get_flags(o_) & K_FLAG_CLOSED_PORT) != 0) +#define kport_is_input(o_) ((tv_get_kflags(o_) & K_FLAG_INPUT_PORT) != 0) +#define kport_is_output(o_) ((tv_get_kflags(o_) & K_FLAG_OUTPUT_PORT) != 0) +#define kport_is_closed(o_) ((tv_get_kflags(o_) & K_FLAG_CLOSED_PORT) != 0) /* can't be inline because we also use pointers to them, (at least gcc doesn't bother to create them and the linker fails) */