1
0
mirror of https://github.com/janet-lang/janet synced 2024-06-21 12:43:15 +00:00

Change object to table type.

Tables are simpler and don't do inheritance via metatables. This means
object polymorphism will be done through a different mechanism rather
than Lua-like metatables. Perhaps smalltalk style messaging using
functions as objects, or lisp-like method dispatch.
This commit is contained in:
bakpakin 2017-04-24 21:00:56 -04:00
parent c33d4da994
commit 0a96e45c4a
11 changed files with 159 additions and 178 deletions

View File

@ -86,9 +86,9 @@ struct GstScope {
uint32_t heapCapacity;
uint32_t heapSize;
uint16_t *freeHeap;
GstObject *literals;
GstTable *literals;
GstArray *literalsArray;
GstObject *locals;
GstTable *locals;
GstScope *parent;
};
@ -124,7 +124,7 @@ static void c_error(GstCompiler *c, const char *e) {
* the new scope is a function declaration. */
static GstScope *compiler_push_scope(GstCompiler *c, int sameFunction) {
GstScope *scope = gst_alloc(c->vm, sizeof(GstScope));
scope->locals = gst_object(c->vm, 10);
scope->locals = gst_table(c->vm, 10);
scope->freeHeap = gst_alloc(c->vm, 10 * sizeof(uint16_t));
scope->heapSize = 0;
scope->heapCapacity = 10;
@ -144,7 +144,7 @@ static GstScope *compiler_push_scope(GstCompiler *c, int sameFunction) {
scope->literalsArray = c->tail->literalsArray;
} else {
scope->nextLocal = 0;
scope->literals = gst_object(c->vm, 10);
scope->literals = gst_table(c->vm, 10);
scope->literalsArray = gst_array(c->vm, 10);
}
c->tail = scope;
@ -318,7 +318,7 @@ static void compiler_tracker_push(GstCompiler *c, SlotTracker *tracker, Slot slo
* that one instead of creating a new literal. This allows for some reuse
* of things like string constants.*/
static uint16_t compiler_add_literal(GstCompiler *c, GstScope *scope, GstValue x) {
GstValue checkDup = gst_object_get(scope->literals, x);
GstValue checkDup = gst_table_get(scope->literals, x);
uint16_t literalIndex = 0;
if (checkDup.type != GST_NIL) {
/* An equal literal is already registered in the current scope */
@ -329,7 +329,7 @@ static uint16_t compiler_add_literal(GstCompiler *c, GstScope *scope, GstValue x
valIndex.type = GST_INTEGER;
literalIndex = scope->literalsArray->count;
valIndex.data.integer = literalIndex;
gst_object_put(c->vm, scope->literals, x, valIndex);
gst_table_put(c->vm, scope->literals, x, valIndex);
gst_array_push(c->vm, scope->literalsArray, x);
}
return literalIndex;
@ -344,7 +344,7 @@ static uint16_t compiler_declare_symbol(GstCompiler *c, GstScope *scope, GstValu
target = compiler_get_local(c, scope);
x.type = GST_INTEGER;
x.data.integer = target;
gst_object_put(c->vm, scope->locals, sym, x);
gst_table_put(c->vm, scope->locals, sym, x);
return target;
}
@ -354,7 +354,7 @@ static int symbol_resolve(GstCompiler *c, GstValue x, uint16_t *level, uint16_t
GstScope *scope = c->tail;
uint32_t currentLevel = scope->level;
while (scope) {
GstValue check = gst_object_get(scope->locals, x);
GstValue check = gst_table_get(scope->locals, x);
if (check.type != GST_NIL) {
*level = currentLevel - scope->level;
*index = (uint16_t) check.data.integer;
@ -925,28 +925,28 @@ static Slot compile_array(GstCompiler *c, FormOptions opts, GstArray *array) {
}
/* Compile an object literal */
static Slot compile_object(GstCompiler *c, FormOptions opts, GstObject *obj) {
static Slot compile_table(GstCompiler *c, FormOptions opts, GstTable *tab) {
GstScope *scope = c->tail;
FormOptions subOpts = form_options_default();
GstBuffer *buffer = c->buffer;
Slot ret;
SlotTracker tracker;
uint32_t i, cap;
cap = obj->capacity;
cap = tab->capacity;
ret = compiler_get_target(c, opts);
tracker_init(c, &tracker);
for (i = 0; i < cap; i += 2) {
if (obj->data[i].type != GST_NIL) {
Slot slot = compile_value(c, subOpts, obj->data[i]);
if (tab->data[i].type != GST_NIL) {
Slot slot = compile_value(c, subOpts, tab->data[i]);
compiler_tracker_push(c, &tracker, compiler_realize_slot(c, slot));
slot = compile_value(c, subOpts, obj->data[i + 1]);
slot = compile_value(c, subOpts, tab->data[i + 1]);
compiler_tracker_push(c, &tracker, compiler_realize_slot(c, slot));
}
}
compiler_tracker_free(c, scope, &tracker);
gst_buffer_push_u16(c->vm, buffer, GST_OP_DIC);
gst_buffer_push_u16(c->vm, buffer, ret.index);
gst_buffer_push_u16(c->vm, buffer, obj->count * 2);
gst_buffer_push_u16(c->vm, buffer, tab->count * 2);
compiler_tracker_write(c, &tracker, 0);
return ret;
}
@ -1017,8 +1017,8 @@ static Slot compile_value(GstCompiler *c, FormOptions opts, GstValue x) {
return compile_form(c, opts, x.data.tuple);
case GST_ARRAY:
return compile_array(c, opts, x.data.array);
case GST_OBJECT:
return compile_object(c, opts, x.data.object);
case GST_TABLE:
return compile_table(c, opts, x.data.table);
default:
return compile_literal(c, opts, x);
}
@ -1044,12 +1044,12 @@ void gst_compiler_global(GstCompiler *c, const char *name, GstValue x) {
/* Add many global variables */
void gst_compiler_globals(GstCompiler *c, GstValue env) {
uint32_t i;
if (env.type == GST_OBJECT) {
GstObject *o = env.data.object;
for (i = 0; i < o->capacity; i += 2) {
if (o->data[i].type == GST_STRING) {
compiler_declare_symbol(c, c->tail, o->data[i]);
gst_array_push(c->vm, c->env, o->data[i + 1]);
if (env.type == GST_TABLE) {
GstTable *t = env.data.table;
for (i = 0; i < t->capacity; i += 2) {
if (t->data[i].type == GST_STRING) {
compiler_declare_symbol(c, c->tail, t->data[i]);
gst_array_push(c->vm, c->env, t->data[i + 1]);
}
}
} else if (env.type == GST_STRUCT) {
@ -1065,7 +1065,7 @@ void gst_compiler_globals(GstCompiler *c, GstValue env) {
/* Use a module that was loaded into the vm */
void gst_compiler_usemodule(GstCompiler *c, const char *modulename) {
GstValue mod = gst_object_get(c->vm->modules, gst_string_cv(c->vm, modulename));
GstValue mod = gst_table_get(c->vm->modules, gst_string_cv(c->vm, modulename));
gst_compiler_globals(c, mod);
}

View File

@ -163,7 +163,7 @@ void gst_dasm(FILE * out, uint16_t *byteCode, uint32_t len) {
current += dasm_varg_op(out, current, "array", 1);
break;
case GST_OP_DIC:
current += dasm_varg_op(out, current, "object", 1);
current += dasm_varg_op(out, current, "table", 1);
break;
case GST_OP_TUP:
current += dasm_varg_op(out, current, "tuple", 1);

View File

@ -169,55 +169,54 @@ void *gst_userdata(Gst *vm, uint32_t size, const GstValue *meta) {
}
/****/
/* Dictionary functions */
/* Table functions */
/****/
/* Create a new dictionary */
GstObject* gst_object(Gst *vm, uint32_t capacity) {
GstObject *o = gst_alloc(vm, sizeof(GstObject));
/* Create a new table */
GstTable *gst_table(Gst *vm, uint32_t capacity) {
GstTable *t = gst_alloc(vm, sizeof(GstTable));
GstValue *data = gst_zalloc(vm, capacity * sizeof(GstValue));
o->data = data;
o->capacity = capacity;
o->count = 0;
o->parent = NULL;
o->deleted = 0;
return o;
t->data = data;
t->capacity = capacity;
t->count = 0;
t->deleted = 0;
return t;
}
/* Find the bucket that contains the given key. Will also return
* bucket where key should go if not in object. */
static GstValue *gst_object_find(GstObject *o, GstValue key) {
uint32_t index = (gst_hash(key) % (o->capacity / 2)) * 2;
* bucket where key should go if not in the table. */
static GstValue *gst_table_find(GstTable *t, GstValue key) {
uint32_t index = (gst_hash(key) % (t->capacity / 2)) * 2;
uint32_t i, j;
uint32_t start[2], end[2];
start[0] = index; end[0] = o->capacity;
start[0] = index; end[0] = t->capacity;
start[1] = 0; end[1] = index;
for (j = 0; j < 2; ++j)
for (i = start[j]; i < end[j]; i += 2) {
if (o->data[i].type == GST_NIL) {
if (o->data[i + 1].type == GST_NIL) {
if (t->data[i].type == GST_NIL) {
if (t->data[i + 1].type == GST_NIL) {
/* Empty */
return o->data + i;
return t->data + i;
}
} else if (gst_equals(o->data[i], key)) {
return o->data + i;
} else if (gst_equals(t->data[i], key)) {
return t->data + i;
}
}
return NULL;
}
/* Resize the dictionary table. */
static void gst_object_rehash(Gst *vm, GstObject *o, uint32_t size) {
GstValue *olddata = o->data;
static void gst_table_rehash(Gst *vm, GstTable *t, uint32_t size) {
GstValue *olddata = t->data;
GstValue *newdata = gst_zalloc(vm, size * sizeof(GstValue));
uint32_t i, oldcapacity;
oldcapacity = o->capacity;
o->data = newdata;
o->capacity = size;
o->deleted = 0;
oldcapacity = t->capacity;
t->data = newdata;
t->capacity = size;
t->deleted = 0;
for (i = 0; i < oldcapacity; i += 2) {
if (olddata[i].type != GST_NIL) {
GstValue *bucket = gst_object_find(o, olddata[i]);
GstValue *bucket = gst_table_find(t, olddata[i]);
bucket[0] = olddata[i];
bucket[1] = olddata[i + 1];
}
@ -225,63 +224,58 @@ static void gst_object_rehash(Gst *vm, GstObject *o, uint32_t size) {
}
/* Get a value out of the object */
GstValue gst_object_get(GstObject *o, GstValue key) {
GstValue *bucket = gst_object_find(o, key);
if (bucket && bucket[0].type != GST_NIL) {
GstValue gst_table_get(GstTable *t, GstValue key) {
GstValue *bucket = gst_table_find(t, key);
if (bucket && bucket[0].type != GST_NIL)
return bucket[1];
} else {
GstValue nil;
nil.type = GST_NIL;
return nil;
}
else
return gst_wrap_nil();
}
/* Remove an entry from the dictionary */
GstValue gst_object_remove(GstObject *o, GstValue key) {
GstValue *bucket = gst_object_find(o, key);
GstValue gst_table_remove(GstTable *t, GstValue key) {
GstValue *bucket = gst_table_find(t, key);
if (bucket && bucket[0].type != GST_NIL) {
GstValue ret = bucket[1];
o->count--;
o->deleted++;
t->count--;
t->deleted++;
bucket[0].type = GST_NIL;
bucket[1].type = GST_BOOLEAN;
return ret;
} else {
GstValue nil;
nil.type = GST_NIL;
return nil;
return gst_wrap_nil();
}
}
/* Put a value into the object */
void gst_object_put(Gst *vm, GstObject *o, GstValue key, GstValue value) {
void gst_table_put(Gst *vm, GstTable *t, GstValue key, GstValue value) {
if (key.type == GST_NIL) return;
if (value.type == GST_NIL) {
gst_object_remove(o, key);
gst_table_remove(t, key);
} else {
GstValue *bucket = gst_object_find(o, key);
GstValue *bucket = gst_table_find(t, key);
if (bucket && bucket[0].type != GST_NIL) {
bucket[1] = value;
} else {
if (!bucket || 4 * (o->count + o->deleted) >= o->capacity) {
gst_object_rehash(vm, o, 4 * o->count + 6);
if (!bucket || 4 * (t->count + t->deleted) >= t->capacity) {
gst_table_rehash(vm, t, 4 * t->count + 6);
}
bucket = gst_object_find(o, key);
bucket = gst_table_find(t, key);
bucket[0] = key;
bucket[1] = value;
++o->count;
++t->count;
}
}
}
/* Find next key in an object. Returns nil if no next key. */
GstValue gst_object_next(GstObject *o, GstValue key) {
GstValue gst_table_next(GstTable *t, GstValue key) {
const GstValue *bucket, *end;
end = o->data + o->capacity;
end = t->data + t->capacity;
if (key.type == GST_NIL) {
bucket = o->data;
bucket = t->data;
} else {
bucket = gst_object_find(o, key);
bucket = gst_table_find(t, key);
if (!bucket || bucket[0].type == GST_NIL)
return gst_wrap_nil();
bucket += 2;

View File

@ -158,19 +158,14 @@ void gst_mark(Gst *vm, GstValueUnion x, GstType type) {
}
break;
case GST_OBJECT:
if (gc_header(x.object)->color != vm->black) {
case GST_TABLE:
if (gc_header(x.table)->color != vm->black) {
uint32_t i;
gc_header(x.object)->color = vm->black;
gc_header(x.object->data)->color = vm->black;
for (i = 0; i < x.object->capacity; i += 2) {
gst_mark_value(vm, x.object->data[i]);
gst_mark_value(vm, x.object->data[i + 1]);
}
if (x.object->parent != NULL) {
GstValueUnion temp;
temp.object = x.object->parent;
gst_mark(vm, temp, GST_OBJECT);
gc_header(x.table)->color = vm->black;
gc_header(x.table->data)->color = vm->black;
for (i = 0; i < x.table->capacity; i += 2) {
gst_mark_value(vm, x.table->data[i]);
gst_mark_value(vm, x.table->data[i + 1]);
}
}
break;
@ -264,8 +259,8 @@ void gst_collect(Gst *vm) {
/* Thread can be null */
if (vm->thread)
gst_mark_value(vm, gst_wrap_thread(vm->thread));
gst_mark_value(vm, gst_wrap_object(vm->modules));
gst_mark_value(vm, gst_wrap_object(vm->registry));
gst_mark_value(vm, gst_wrap_table(vm->modules));
gst_mark_value(vm, gst_wrap_table(vm->registry));
gst_mark_value(vm, vm->ret);
if (vm->scratch)
gc_header(vm->scratch)->color = vm->black;

View File

@ -45,8 +45,8 @@ struct GstParseState {
struct {
GstValue key;
int keyFound;
GstObject *object;
} object;
GstTable *table;
} table;
struct {
GstBuffer *buffer;
uint32_t count;
@ -432,13 +432,13 @@ static int form_state(GstParser *p, uint8_t c) {
} else { /* c == '{' */
uint32_t i;
if (array->count % 2 != 0) {
p_error(p, "object literal must have even number of elements");
p_error(p, "table literal must have even number of elements");
return 1;
}
x.type = GST_OBJECT;
x.data.object = gst_object(p->vm, array->count);
x.type = GST_TABLE;
x.data.table = gst_table(p->vm, array->count);
for (i = 0; i < array->count; i += 2) {
gst_object_put(p->vm, x.data.object, array->data[i], array->data[i + 1]);
gst_table_put(p->vm, x.data.table, array->data[i], array->data[i + 1]);
}
}
parser_pop(p);

View File

@ -40,7 +40,7 @@
* Byte 209: Tuple - [u32 length]*[value... elements]
* Byte 210: Thread - [u8 state][u32 frames]*[[value callee][value env]
* [u32 pcoffset][u16 ret][u16 args][u16 size]*[value ...stack]
* Byte 211: Object - [value parent][u32 length]*2*[value... kvs]
* Byte 211: Table - [u32 length]*2*[value... kvs]
* Byte 212: FuncDef - [u32 locals][u32 arity][u32 flags][u32 literallen]*[value...
* literals][u32 bytecodelen]*[u16... bytecode]
* Byte 213: FunEnv - [value thread][u32 length]*[value ...upvalues]
@ -290,24 +290,19 @@ static const char *gst_deserialize_impl(
}
break;
case 211: /* Object */
case 211: /* Table */
{
GstValue parent;
ret.type = GST_OBJECT;
ret.data.object = gst_object(vm, 10);
err = gst_deserialize_impl(vm, data, end, &data, visited, &parent);
if (err != NULL) return err;
ret.type = GST_TABLE;
read_u32(length);
ret.data.table = gst_table(vm, 2 * length);
for (i = 0; i < length; i += 2) {
GstValue key, value;
err = gst_deserialize_impl(vm, data, end, &data, visited, &key);
if (err != NULL) return err;
err = gst_deserialize_impl(vm, data, end, &data, visited, &value);
if (err != NULL) return err;
gst_object_put(vm, ret.data.object, key, value);
gst_table_put(vm, ret.data.table, key, value);
}
if (parent.type == GST_OBJECT)
ret.data.object->parent = parent.data.object;
gst_array_push(vm, visited, ret);
}
break;
@ -461,7 +456,7 @@ BUFFER_DEFINE(u32, uint32_t)
const char *gst_serialize_impl(
Gst *vm,
GstBuffer *buffer,
GstObject *visited,
GstTable *visited,
uint32_t *nextId,
GstValue x) {
@ -503,7 +498,7 @@ const char *gst_serialize_impl(
}
/* Check if already seen - if so, use reference */
check = gst_object_get(visited, x);
check = gst_table_get(visited, x);
if (check.type == GST_INTEGER) {
write_byte(217);
write_u32((uint32_t) check.data.integer);
@ -568,7 +563,7 @@ const char *gst_serialize_impl(
/* Record reference */
check.type = GST_INTEGER;
check.data.integer = *nextId++;
gst_object_put(vm, visited, x, check);
gst_table_put(vm, visited, x, check);
/* Return success */
return NULL;
@ -579,7 +574,7 @@ const char *gst_serialize(Gst *vm, GstBuffer *buffer, GstValue x) {
uint32_t nextId = 0;
uint32_t oldCount = buffer->count;
const char *err;
GstObject *visited = gst_object(vm, 10);
GstTable *visited = gst_table(vm, 10);
err = gst_serialize_impl(vm, buffer, visited, &nextId, x);
if (err != NULL) {
buffer->count = oldCount;

View File

@ -115,13 +115,11 @@ int gst_stl_not(Gst *vm) {
/* Get length of object */
int gst_stl_length(Gst *vm) {
GstValue ret;
uint32_t count = gst_count_args(vm);
if (count == 0) {
ret.type = GST_NIL;
gst_c_return(vm, ret);
}
if (count == 1) {
gst_c_return(vm, gst_wrap_nil());
} else {
GstValue ret;
ret.type = GST_INTEGER;
GstValue x = gst_arg(vm, 0);
switch (x.type) {
@ -139,12 +137,12 @@ int gst_stl_length(Gst *vm) {
case GST_TUPLE:
ret.data.integer = gst_tuple_length(x.data.tuple);
break;
case GST_OBJECT:
ret.data.integer = x.data.object->count;
case GST_TABLE:
ret.data.integer = x.data.table->count;
break;
}
gst_c_return(vm, ret);
}
gst_c_return(vm, ret);
}
/* Convert to integer */
@ -259,8 +257,8 @@ int gst_stl_type(Gst *vm) {
case GST_CFUNCTION:
typestr = "cfunction";
break;
case GST_OBJECT:
typestr = "object";
case GST_TABLE:
typestr = "table";
break;
case GST_USERDATA:
typestr = "userdata";
@ -296,16 +294,16 @@ int gst_stl_tuple(Gst *vm) {
}
/* Create object */
int gst_stl_object(Gst *vm) {
int gst_stl_table(Gst *vm) {
uint32_t i;
uint32_t count = gst_count_args(vm);
GstObject *object;
GstTable *table;
if (count % 2 != 0)
gst_c_throwc(vm, "expected even number of arguments");
object = gst_object(vm, 4 * count);
table = gst_table(vm, 4 * count);
for (i = 0; i < count; i += 2)
gst_object_put(vm, object, gst_arg(vm, i), gst_arg(vm, i + 1));
gst_c_return(vm, gst_wrap_object(object));
gst_table_put(vm, table, gst_arg(vm, i), gst_arg(vm, i + 1));
gst_c_return(vm, gst_wrap_table(table));
}
/* Create struct */
@ -425,16 +423,16 @@ int gst_stl_ensure(Gst *vm) {
gst_c_return(vm, ds);
}
/* Get next key in struct or object */
/* Get next key in struct or table */
int gst_stl_next(Gst *vm) {
GstValue ds = gst_arg(vm, 0);
GstValue key = gst_arg(vm, 1);
if (ds.type == GST_OBJECT) {
gst_c_return(vm, gst_object_next(ds.data.object, key));
if (ds.type == GST_TABLE) {
gst_c_return(vm, gst_table_next(ds.data.table, key));
} else if (ds.type == GST_STRUCT) {
gst_c_return(vm, gst_struct_next(ds.data.st, key));
} else {
gst_c_throwc(vm, "expected object or struct");
gst_c_throwc(vm, "expected table or struct");
}
}
@ -499,11 +497,11 @@ int gst_stl_serialize(Gst *vm) {
/****/
int gst_stl_global(Gst *vm) {
gst_c_return(vm, gst_object_get(vm->registry, gst_arg(vm, 0)));
gst_c_return(vm, gst_table_get(vm->registry, gst_arg(vm, 0)));
}
int gst_stl_setglobal(Gst *vm) {
gst_object_put(vm, vm->registry, gst_arg(vm, 0), gst_arg(vm, 1));
gst_table_put(vm, vm->registry, gst_arg(vm, 0), gst_arg(vm, 1));
gst_c_return(vm, gst_wrap_nil());
}
@ -577,7 +575,7 @@ static const GstModuleItem const std_module[] = {
{"slice", gst_stl_slice},
{"array", gst_stl_array},
{"tuple", gst_stl_tuple},
{"object", gst_stl_object},
{"table", gst_stl_table},
{"struct", gst_stl_struct},
{"buffer", gst_stl_buffer},
{"strcat", gst_stl_strcat},

View File

@ -62,21 +62,21 @@ GST_WRAP_DEFINE(thread, GstThread *, GST_THREAD, thread)
GST_WRAP_DEFINE(buffer, GstBuffer *, GST_BYTEBUFFER, buffer)
GST_WRAP_DEFINE(function, GstFunction *, GST_FUNCTION, function)
GST_WRAP_DEFINE(cfunction, GstCFunction, GST_CFUNCTION, cfunction)
GST_WRAP_DEFINE(object, GstObject *, GST_OBJECT, object)
GST_WRAP_DEFINE(table, GstTable *, GST_TABLE, table)
GST_WRAP_DEFINE(userdata, void *, GST_USERDATA, pointer)
GST_WRAP_DEFINE(funcenv, GstFuncEnv *, GST_FUNCENV, env)
GST_WRAP_DEFINE(funcdef, GstFuncDef *, GST_FUNCDEF, def)
#undef GST_WRAP_DEFINE
GstValue gst_cmodule_object(Gst *vm, const GstModuleItem *mod) {
GstObject *module = gst_object(vm, 10);
GstValue gst_cmodule_table(Gst *vm, const GstModuleItem *mod) {
GstTable *module = gst_table(vm, 10);
while (mod->name != NULL) {
GstValue key = gst_string_cv(vm, mod->name);
gst_object_put(vm, module, key, gst_wrap_cfunction(mod->data));
gst_table_put(vm, module, key, gst_wrap_cfunction(mod->data));
mod++;
}
return gst_wrap_object(module);
return gst_wrap_table(module);
}
GstValue gst_cmodule_struct(Gst *vm, const GstModuleItem *mod) {
@ -100,19 +100,19 @@ GstValue gst_cmodule_struct(Gst *vm, const GstModuleItem *mod) {
}
void gst_module_put(Gst *vm, const char *packagename, GstValue mod) {
gst_object_put(vm, vm->modules, gst_string_cv(vm, packagename), mod);
gst_table_put(vm, vm->modules, gst_string_cv(vm, packagename), mod);
}
GstValue gst_module_get(Gst *vm, const char *packagename) {
return gst_object_get(vm->modules, gst_string_cv(vm, packagename));
return gst_table_get(vm->modules, gst_string_cv(vm, packagename));
}
void gst_register_put(Gst *vm, const char *name, GstValue c) {
gst_object_put(vm, vm->registry, gst_string_cv(vm, name), c);
gst_table_put(vm, vm->registry, gst_string_cv(vm, name), c);
}
GstValue gst_register_get(Gst *vm, const char *name) {
return gst_object_get(vm->registry, gst_string_cv(vm, name));
return gst_table_get(vm->registry, gst_string_cv(vm, name));
}
/****/
@ -151,13 +151,13 @@ int gst_chararray_view(GstValue str, const uint8_t **data, uint32_t *len) {
return 0;
}
/* Read both structs and objects as the entries of a hashtable with
/* Read both structs and tables as the entries of a hashtable with
* identical structure. Returns 1 if the view can be constructed and
* 0 if the type is invalid. */
int gst_hashtable_view(GstValue tab, const GstValue **data, uint32_t *cap) {
if (tab.type == GST_OBJECT) {
*data = tab.data.object->data;
*cap = tab.data.object->capacity;
if (tab.type == GST_TABLE) {
*data = tab.data.table->data;
*cap = tab.data.table->capacity;
return 1;
} else if (tab.type == GST_STRUCT) {
*data = tab.data.st;

View File

@ -96,8 +96,8 @@ const uint8_t *gst_to_string(Gst *vm, GstValue x) {
return string_description(vm, "tuple", x.data.pointer);
case GST_STRUCT:
return string_description(vm, "struct", x.data.pointer);
case GST_OBJECT:
return string_description(vm, "object", x.data.pointer);
case GST_TABLE:
return string_description(vm, "table", x.data.pointer);
case GST_STRING:
return x.data.string;
case GST_BYTEBUFFER:
@ -267,8 +267,8 @@ const char *gst_get(GstValue ds, GstValue key, GstValue *out) {
case GST_STRUCT:
ret = gst_struct_get(ds.data.st, key);
break;
case GST_OBJECT:
ret = gst_object_get(ds.data.object, key);
case GST_TABLE:
ret = gst_table_get(ds.data.table, key);
break;
default:
return "cannot get";
@ -295,8 +295,8 @@ const char *gst_set(Gst *vm, GstValue ds, GstValue key, GstValue value) {
if (index < 0) return "invalid buffer access";
ds.data.buffer->data[index] = (uint8_t) value.data.integer;
break;
case GST_OBJECT:
gst_object_put(vm, ds.data.object, key, value);
case GST_TABLE:
gst_table_put(vm, ds.data.table, key, value);
break;
default:
return "cannot set";
@ -326,8 +326,8 @@ GstInteger gst_length(Gst *vm, GstValue x) {
case GST_STRUCT:
length = gst_struct_length(x.data.st);
break;
case GST_OBJECT:
length = x.data.object->count;
case GST_TABLE:
length = x.data.table->count;
break;
}
return length;

View File

@ -330,19 +330,19 @@ int gst_continue(Gst *vm) {
}
break;
case GST_OP_DIC: /* Object literal */
case GST_OP_DIC: /* Table literal */
{
uint32_t i = 3;
uint32_t kvs = pc[2];
GstObject *o = gst_object(vm, 2 * kvs);
GstTable *t = gst_table(vm, 2 * kvs);
kvs = kvs + 3;
while (i < kvs) {
v1 = stack[pc[i++]];
v2 = stack[pc[i++]];
gst_object_put(vm, o, v1, v2);
gst_table_put(vm, t, v1, v2);
}
temp.type = GST_OBJECT;
temp.data.object = o;
temp.type = GST_TABLE;
temp.data.table = t;
stack[pc[1]] = temp;
pc += kvs;
}
@ -466,8 +466,8 @@ void gst_init(Gst *vm) {
vm->cache_count = 0;
vm->cache_deleted = 0;
/* Set up global env */
vm->modules = gst_object(vm, 10);
vm->registry = gst_object(vm, 10);
vm->modules = gst_table(vm, 10);
vm->registry = gst_table(vm, 10);
}
/* Clear all memory associated with the VM */

View File

@ -125,7 +125,7 @@ typedef enum GstType {
GST_BYTEBUFFER,
GST_FUNCTION,
GST_CFUNCTION,
GST_OBJECT,
GST_TABLE,
GST_USERDATA,
GST_FUNCENV,
GST_FUNCDEF
@ -144,7 +144,7 @@ typedef int GstBoolean;
typedef struct GstFunction GstFunction;
typedef struct GstArray GstArray;
typedef struct GstBuffer GstBuffer;
typedef struct GstObject GstObject;
typedef struct GstTable GstTable;
typedef struct GstThread GstThread;
typedef int (*GstCFunction)(Gst * vm);
@ -170,7 +170,7 @@ union GstValueUnion {
GstInteger integer;
GstArray *array;
GstBuffer *buffer;
GstObject *object;
GstTable *table;
GstThread *thread;
const GstValue *tuple;
GstCFunction cfunction;
@ -223,13 +223,12 @@ struct GstBuffer {
uint8_t *data;
};
/* The main Gst type, an obect. Objects are just hashtables with a parent */
struct GstObject {
/* A mutable associative data type. Backed by a hashtable. */
struct GstTable {
uint32_t count;
uint32_t capacity;
uint32_t deleted;
GstValue *data;
GstObject *parent;
};
/* Some function defintion flags */
@ -288,8 +287,8 @@ struct Gst {
uint32_t scratch_len;
/* GC roots */
GstThread *thread;
GstObject *modules;
GstObject *registry;
GstTable *modules;
GstTable *registry;
/* Return state */
const char *crash;
GstValue ret; /* Returned value from gst_start. */
@ -388,14 +387,14 @@ GstValue gst_struct_get(const GstValue *st, GstValue key);
GstValue gst_struct_next(const GstValue *st, GstValue key);
/****/
/* Object functions */
/* Table functions */
/****/
GstObject *gst_object(Gst *vm, uint32_t capacity);
GstValue gst_object_get(GstObject *obj, GstValue key);
GstValue gst_object_remove(GstObject *obj, GstValue key);
void gst_object_put(Gst *vm, GstObject *obj, GstValue key, GstValue value);
GstValue gst_object_next(GstObject *o, GstValue key);
GstTable *gst_table(Gst *vm, uint32_t capacity);
GstValue gst_table_get(GstTable *t, GstValue key);
GstValue gst_table_remove(GstTable *t, GstValue key);
void gst_table_put(Gst *vm, GstTable *t, GstValue key, GstValue value);
GstValue gst_table_next(GstTable *o, GstValue key);
/****/
/* Threads */
@ -446,7 +445,7 @@ GstInteger gst_length(Gst *vm, GstValue x);
* Byte 209: Tuple - [u32 length]*[value... elements]
* Byte 210: Thread - [u8 state][u32 frames]*[[value callee][value env]
* [u32 pcoffset][u32 erroffset][u16 ret][u16 errloc][u16 size]*[value ...stack]
* Byte 211: Object - [value meta][u32 length]*2*[value... kvs]
* Byte 211: Table - [u32 length]*2*[value... kvs]
* Byte 212: FuncDef - [u32 locals][u32 arity][u32 flags][u32 literallen]*[value...
* literals][u32 bytecodelen]*[u16... bytecode]
* Byte 213: FunEnv - [value thread][u32 length]*[value ...upvalues]
@ -501,7 +500,7 @@ uint16_t gst_count_args(Gst *vm);
/* C Api */
/****/
GstValue gst_cmodule_object(Gst *vm, const GstModuleItem *mod);
GstValue gst_cmodule_table(Gst *vm, const GstModuleItem *mod);
GstValue gst_cmodule_struct(Gst *vm, const GstModuleItem *mod);
void gst_module_put(Gst *vm, const char *packagename, GstValue mod);
GstValue gst_module_get(Gst *vm, const char *packagename);
@ -521,7 +520,7 @@ GstValue gst_wrap_thread(GstThread *x);
GstValue gst_wrap_buffer(GstBuffer *x);
GstValue gst_wrap_function(GstFunction *x);
GstValue gst_wrap_cfunction(GstCFunction x);
GstValue gst_wrap_object(GstObject *x);
GstValue gst_wrap_table(GstTable *x);
GstValue gst_wrap_userdata(void *x);
GstValue gst_wrap_funcenv(GstFuncEnv *x);
GstValue gst_wrap_funcdef(GstFuncDef *x);
@ -539,7 +538,7 @@ int gst_check_thread(Gst *vm, uint32_t i, GstThread *(*x));
int gst_check_buffer(Gst *vm, uint32_t i, GstBuffer *(*x));
int gst_check_function(Gst *vm, uint32_t i, GstFunction *(*x));
int gst_check_cfunction(Gst *vm, uint32_t i, GstCFunction (*x));
int gst_check_object(Gst *vm, uint32_t i, GstObject *(*x));
int gst_check_table(Gst *vm, uint32_t i, GstTable *(*x));
int gst_check_userdata(Gst *vm, uint32_t i, void *(*x));
int gst_check_funcenv(Gst *vm, uint32_t i, GstFuncEnv *(*x));
int gst_check_funcdef(Gst *vm, uint32_t i, GstFuncDef *(*x));