mirror of
https://github.com/janet-lang/janet
synced 2025-10-25 04:37:42 +00:00
Add proto field to tables to allow prototypal inheritance.
This commit is contained in:
@@ -114,14 +114,17 @@
|
||||
ret)
|
||||
})
|
||||
|
||||
(defn onerr [t e]
|
||||
(print (string t " error: " e)))
|
||||
# Compile time
|
||||
|
||||
(var *read* nil)
|
||||
(var *onvalue* identity)
|
||||
(var *env* _env)
|
||||
|
||||
(def require-loading @{})
|
||||
|
||||
(defn onerr [t e]
|
||||
(print (string t " error: " e)))
|
||||
|
||||
(defn char-stream [getchunk ondone]
|
||||
(fiber (fn [parent]
|
||||
(def buf @"")
|
||||
@@ -197,7 +200,7 @@
|
||||
(def wrapper (fiber (fn []
|
||||
(while *read*
|
||||
(def source (*read*))
|
||||
(def res (compile source _env))
|
||||
(def res (compile source *env*))
|
||||
(if (= (type res) :function)
|
||||
(*onvalue* (res))
|
||||
(onerr "compile" (get res :error)))))))
|
||||
|
||||
@@ -47,6 +47,9 @@ static const DstReg cfuns[] = {
|
||||
{"buffer", dst_core_buffer},
|
||||
{"gensym", dst_core_gensym},
|
||||
{"get", dst_core_get},
|
||||
{"rawget", dst_core_rawget},
|
||||
{"getproto", dst_core_getproto},
|
||||
{"setproto", dst_core_setproto},
|
||||
{"put", dst_core_put},
|
||||
{"length", dst_core_length},
|
||||
{"gccollect", dst_core_gccollect},
|
||||
|
||||
@@ -172,6 +172,33 @@ int dst_core_get(DstArgs args) {
|
||||
return dst_return(args, ds);
|
||||
}
|
||||
|
||||
int dst_core_rawget(DstArgs args) {
|
||||
if (args.n != 2) return dst_throw(args, "expected 2 arguments");
|
||||
if (!dst_checktype(args.v[0], DST_TABLE)) return dst_throw(args, "expected table");
|
||||
return dst_return(args, dst_table_rawget(dst_unwrap_table(args.v[0]), args.v[1]));
|
||||
}
|
||||
|
||||
int dst_core_getproto(DstArgs args) {
|
||||
DstTable *t;
|
||||
if (args.n != 1) return dst_throw(args, "expected 1 argument");
|
||||
if (!dst_checktype(args.v[0], DST_TABLE)) return dst_throw(args, "expected table");
|
||||
t = dst_unwrap_table(args.v[0]);
|
||||
return dst_return(args, t->proto
|
||||
? dst_wrap_table(t->proto)
|
||||
: dst_wrap_nil());
|
||||
}
|
||||
|
||||
int dst_core_setproto(DstArgs args) {
|
||||
if (args.n != 2) return dst_throw(args, "expected 2 arguments");
|
||||
if (!dst_checktype(args.v[0], DST_TABLE)) return dst_throw(args, "expected table");
|
||||
if (!dst_checktype(args.v[1], DST_TABLE) && !dst_checktype(args.v[1], DST_NIL))
|
||||
return dst_throw(args, "expected table");
|
||||
dst_unwrap_table(args.v[0])->proto = dst_checktype(args.v[1], DST_TABLE)
|
||||
? dst_unwrap_table(args.v[1])
|
||||
: NULL;
|
||||
return dst_return(args, args.v[0]);
|
||||
}
|
||||
|
||||
int dst_core_fiber_status(DstArgs args) {
|
||||
const char *status = "";
|
||||
if (args.n != 1) return dst_throw(args, "expected 1 argument");
|
||||
|
||||
@@ -109,10 +109,15 @@ static void dst_mark_array(DstArray *array) {
|
||||
}
|
||||
|
||||
static void dst_mark_table(DstTable *table) {
|
||||
recur: /* Manual tail recursion */
|
||||
if (dst_gc_reachable(table))
|
||||
return;
|
||||
dst_gc_mark(table);
|
||||
dst_mark_kvs(table->data, table->capacity);
|
||||
if (table->proto) {
|
||||
table = table->proto;
|
||||
goto recur;
|
||||
}
|
||||
}
|
||||
|
||||
static void dst_mark_struct(const DstKV *st) {
|
||||
|
||||
@@ -43,6 +43,7 @@ DstTable *dst_table_init(DstTable *table, int32_t capacity) {
|
||||
}
|
||||
table->count = 0;
|
||||
table->deleted = 0;
|
||||
table->proto = NULL;
|
||||
return table;
|
||||
}
|
||||
|
||||
@@ -114,8 +115,25 @@ static void dst_table_rehash(DstTable *t, int32_t size) {
|
||||
free(olddata);
|
||||
}
|
||||
|
||||
/* Get a value out of the object */
|
||||
/* Get a value out of the table */
|
||||
Dst dst_table_get(DstTable *t, Dst key) {
|
||||
DstKV *bucket = dst_table_find(t, key);
|
||||
if (NULL != bucket && !dst_checktype(bucket->key, DST_NIL))
|
||||
return bucket->value;
|
||||
/* Check prototypes */
|
||||
{
|
||||
int i;
|
||||
for (i = DST_MAX_PROTO_DEPTH, t = t->proto; t && i; t = t->proto, --i) {
|
||||
bucket = dst_table_find(t, key);
|
||||
if (NULL != bucket && !dst_checktype(bucket->key, DST_NIL))
|
||||
return bucket->value;
|
||||
}
|
||||
}
|
||||
return dst_wrap_nil();
|
||||
}
|
||||
|
||||
/* Get a value out of the table. Don't check prototype tables. */
|
||||
Dst dst_table_rawget(DstTable *t, Dst key) {
|
||||
DstKV *bucket = dst_table_find(t, key);
|
||||
if (NULL != bucket && !dst_checktype(bucket->key, DST_NIL))
|
||||
return bucket->value;
|
||||
|
||||
@@ -120,6 +120,7 @@ DstTable *dst_table(int32_t capacity);
|
||||
DstTable *dst_table_init(DstTable *table, int32_t capacity);
|
||||
void dst_table_deinit(DstTable *table);
|
||||
Dst dst_table_get(DstTable *t, Dst key);
|
||||
Dst dst_table_rawget(DstTable *t, Dst key);
|
||||
Dst dst_table_remove(DstTable *t, Dst key);
|
||||
void dst_table_put(DstTable *t, Dst key, Dst value);
|
||||
const DstKV *dst_table_next(DstTable *t, const DstKV *kv);
|
||||
|
||||
@@ -120,6 +120,9 @@ extern "C" {
|
||||
* ands crashing (the parser). Instead, error out. */
|
||||
#define DST_RECURSION_GUARD 1024
|
||||
|
||||
/* Maximum depth to follow table prototypes before giving up and returning nil. */
|
||||
#define DST_MAX_PROTO_DEPTH 200
|
||||
|
||||
/* Define max stack size for stacks before raising a stack overflow error.
|
||||
* If this is not defined, fiber stacks can grow without limit (until memory
|
||||
* runs out) */
|
||||
|
||||
@@ -90,6 +90,9 @@ int dst_core_buffer(DstArgs args);
|
||||
int dst_core_gensym(DstArgs args);
|
||||
int dst_core_length(DstArgs args);
|
||||
int dst_core_get(DstArgs args);
|
||||
int dst_core_rawget(DstArgs args);
|
||||
int dst_core_getproto(DstArgs args);
|
||||
int dst_core_setproto(DstArgs args);
|
||||
int dst_core_fiber_status(DstArgs args);
|
||||
int dst_core_fiber_current(DstArgs args);
|
||||
int dst_core_put(DstArgs args);
|
||||
|
||||
@@ -359,6 +359,7 @@ struct DstBuffer {
|
||||
/* A mutable associative data type. Backed by a hashtable. */
|
||||
struct DstTable {
|
||||
DstKV *data;
|
||||
DstTable *proto;
|
||||
int32_t count;
|
||||
int32_t capacity;
|
||||
int32_t deleted;
|
||||
|
||||
Reference in New Issue
Block a user