mirror of
https://github.com/janet-lang/janet
synced 2024-11-24 17:27:18 +00:00
Add symbol type.
This commit is contained in:
parent
31ec1e9147
commit
e2c78b36d0
@ -103,9 +103,6 @@ static int debug_run(Gst *vm, FILE *in) {
|
||||
while (p.status != GST_PARSER_ERROR && p.status != GST_PARSER_FULL) {
|
||||
if (*reader == '\0') {
|
||||
if (!fgets(buffer, sizeof(buffer), in)) {
|
||||
/* Add possible end of line */
|
||||
if (p.status == GST_PARSER_PENDING)
|
||||
gst_parse_cstring(&p, "\n");
|
||||
/* Check that parser is complete */
|
||||
if (p.status != GST_PARSER_FULL && p.status != GST_PARSER_ROOT) {
|
||||
printf("Unexpected end of source\n");
|
||||
@ -144,7 +141,6 @@ static int debug_repl(Gst *vm, uint64_t flags) {
|
||||
/* Init parser */
|
||||
gst_parser(&p, vm);
|
||||
while (p.status != GST_PARSER_ERROR && p.status != GST_PARSER_FULL) {
|
||||
gst_parse_cstring(&p, "\n");
|
||||
if (p.status == GST_PARSER_ERROR || p.status == GST_PARSER_FULL)
|
||||
break;
|
||||
if (!reader || *reader == '\0') {
|
||||
|
@ -126,14 +126,6 @@ static void c_error1(GstCompiler *c, GstValue e) {
|
||||
longjmp(c->onError, 1);
|
||||
}
|
||||
|
||||
/* Quote something */
|
||||
static GstValue quote(Gst *vm, GstValue x) {
|
||||
GstValue *q = gst_tuple_begin(vm, 2);
|
||||
q[0] = gst_string_cv(vm, "quote");
|
||||
q[1] = x; /* lit contains the var container of the environment */
|
||||
return gst_wrap_tuple(gst_tuple_end(vm, q));
|
||||
}
|
||||
|
||||
/* Push a new scope in the compiler and return
|
||||
* a pointer to it for configuration. There is
|
||||
* more configuration that needs to be done if
|
||||
@ -383,8 +375,8 @@ static uint16_t compiler_add_literal(GstCompiler *c, GstScope *scope, GstValue x
|
||||
static uint16_t compiler_declare_symbol(GstCompiler *c, GstScope *scope, GstValue sym, uint16_t flags) {
|
||||
GstValue x;
|
||||
uint16_t target;
|
||||
if (sym.type != GST_STRING)
|
||||
c_error(c, "expected string");
|
||||
if (sym.type != GST_SYMBOL)
|
||||
c_error(c, "expected symbol");
|
||||
target = compiler_get_local(c, scope);
|
||||
x.type = GST_INTEGER;
|
||||
x.data.integer = target + (flags << 16);
|
||||
@ -415,7 +407,7 @@ static int symbol_resolve(GstCompiler *c, GstValue x, uint16_t *level, uint16_t
|
||||
GstTable *metas = gst_env_meta(c->vm, c->env);
|
||||
GstValue maybeMeta = gst_table_get(metas, x);
|
||||
if (maybeMeta.type == GST_TABLE) {
|
||||
GstValue isMutable = gst_table_get(maybeMeta.data.table, gst_string_cv(c->vm, "mutable"));
|
||||
GstValue isMutable = gst_table_get(maybeMeta.data.table, gst_string_cvs(c->vm, "mutable"));
|
||||
if (gst_truthy(isMutable)) {
|
||||
if (flags) *flags = GST_LOCAL_FLAG_MUTABLE;
|
||||
*out = check;
|
||||
@ -509,6 +501,14 @@ static Slot compile_literal(GstCompiler *c, FormOptions opts, GstValue x) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Quote a value */
|
||||
static GstValue quote(Gst *vm, GstValue x) {
|
||||
GstValue *tuple = gst_tuple_begin(vm, 2);
|
||||
tuple[0] = gst_string_cvs(vm, "quote");
|
||||
tuple[1] = x;
|
||||
return gst_wrap_tuple(gst_tuple_end(vm, tuple));
|
||||
}
|
||||
|
||||
/* Compile a symbol. Resolves any kind of symbol. */
|
||||
static Slot compile_symbol(GstCompiler *c, FormOptions opts, GstValue sym) {
|
||||
GstValue lit = gst_wrap_nil();
|
||||
@ -529,7 +529,7 @@ static Slot compile_symbol(GstCompiler *c, FormOptions opts, GstValue sym) {
|
||||
const GstValue *tup;
|
||||
Gst *vm= c->vm;
|
||||
GstValue *t = gst_tuple_begin(vm, 3);
|
||||
t[0] = gst_string_cv(vm, "get"); /* Todo - replace with actual cfunc or bytecode */
|
||||
t[0] = gst_string_cvs(vm, "get"); /* Todo - replace with actual cfunc or bytecode */
|
||||
t[1] = quote(vm, lit);
|
||||
t[2] = gst_wrap_integer(0);
|
||||
tup = gst_tuple_end(vm, t);
|
||||
@ -608,8 +608,8 @@ static Slot compile_assign(GstCompiler *c, FormOptions opts, GstValue left, GstV
|
||||
const GstValue *tup;
|
||||
Gst *vm= c->vm;
|
||||
GstValue *t = gst_tuple_begin(vm, 4);
|
||||
t[0] = gst_string_cv(vm, "set!"); /* Todo - replace with ref ro actual cfunc */
|
||||
t[1] = quote(vm, lit);
|
||||
t[0] = gst_string_cvs(vm, "set!"); /* Todo - replace with ref ro actual cfunc */
|
||||
t[1] = quote(c->vm, lit);
|
||||
t[2] = gst_wrap_integer(0);
|
||||
t[3] = right;
|
||||
tup = gst_tuple_end(vm, t);
|
||||
@ -631,7 +631,7 @@ static Slot compile_assign(GstCompiler *c, FormOptions opts, GstValue left, GstV
|
||||
static Slot compile_varset(GstCompiler *c, FormOptions opts, const GstValue *form) {
|
||||
if (gst_tuple_length(form) != 3)
|
||||
c_error(c, "expected 2 arguments to varset");
|
||||
if (GST_STRING != form[1].type)
|
||||
if (GST_SYMBOL != form[1].type)
|
||||
c_error(c, "expected symbol as first argument");
|
||||
return compile_assign(c, opts, form[1], form[2]);
|
||||
}
|
||||
@ -641,11 +641,9 @@ static Slot compile_global_var(GstCompiler *c, FormOptions opts, const GstValue
|
||||
const GstValue *tup;
|
||||
Gst *vm= c->vm;
|
||||
GstValue *t = gst_tuple_begin(vm, 3);
|
||||
GstValue *q = gst_tuple_begin(vm, 2);
|
||||
q[0] = gst_string_cv(vm, "quote");
|
||||
q[1] = form[1];
|
||||
t[0] = gst_string_cv(vm, "global-var"); /* Todo - replace with ref ro actual cfunc */
|
||||
t[1] = gst_wrap_tuple(gst_tuple_end(vm, q));
|
||||
t[0] = gst_string_cvs(vm, "global-var"); /* Todo - replace with ref ro actual cfunc */
|
||||
t[1] = form[1];
|
||||
t[1].type = GST_STRING;
|
||||
t[2] = form[2];
|
||||
tup = gst_tuple_end(vm, t);
|
||||
return compile_value(c, opts, gst_wrap_tuple(tup));
|
||||
@ -656,11 +654,9 @@ static Slot compile_global_def(GstCompiler *c, FormOptions opts, const GstValue
|
||||
const GstValue *tup;
|
||||
Gst *vm= c->vm;
|
||||
GstValue *t = gst_tuple_begin(vm, 3);
|
||||
GstValue *q = gst_tuple_begin(vm, 2);
|
||||
q[0] = gst_string_cv(vm, "quote");
|
||||
q[1] = form[1];
|
||||
t[0] = gst_string_cv(vm, "global-def"); /* Todo - replace with ref ro actual cfunc */
|
||||
t[1] = gst_wrap_tuple(gst_tuple_end(vm, q));
|
||||
t[0] = gst_string_cvs(vm, "global-def"); /* Todo - replace with ref ro actual cfunc */
|
||||
t[1] = form[1];
|
||||
t[1].type = GST_STRING;
|
||||
t[2] = form[2];
|
||||
tup = gst_tuple_end(vm, t);
|
||||
return compile_value(c, opts, gst_wrap_tuple(tup));
|
||||
@ -671,7 +667,7 @@ static Slot compile_def(GstCompiler *c, FormOptions opts, const GstValue *form)
|
||||
GstScope *scope = c->tail;
|
||||
if (gst_tuple_length(form) != 3)
|
||||
c_error(c, "expected 2 arguments to def");
|
||||
if (GST_STRING != form[1].type)
|
||||
if (GST_SYMBOL != form[1].type)
|
||||
c_error(c, "expected symbol as first argument");
|
||||
if (scope->parent) {
|
||||
FormOptions subOpts;
|
||||
@ -692,7 +688,7 @@ static Slot compile_var(GstCompiler *c, FormOptions opts, const GstValue *form)
|
||||
GstScope *scope = c->tail;
|
||||
if (gst_tuple_length(form) != 3)
|
||||
c_error(c, "expected 2 arguments to var");
|
||||
if (GST_STRING != form[1].type)
|
||||
if (GST_SYMBOL != form[1].type)
|
||||
c_error(c, "expected symbol as first argument");
|
||||
if (scope->parent) {
|
||||
FormOptions subOpts;
|
||||
@ -798,8 +794,8 @@ static Slot compile_function(GstCompiler *c, FormOptions opts, const GstValue *f
|
||||
arity = params->count;
|
||||
for (i = 0; i < params->count; ++i) {
|
||||
GstValue param = params->data[i];
|
||||
if (param.type != GST_STRING)
|
||||
c_error(c, "function parameters should be strings");
|
||||
if (param.type != GST_SYMBOL)
|
||||
c_error(c, "function parameters should be symbols");
|
||||
/* Check for varargs */
|
||||
if (equal_cstr(param.data.string, "&")) {
|
||||
if (i != params->count - 1) {
|
||||
@ -1057,7 +1053,7 @@ typedef Slot (*SpecialFormHelper) (GstCompiler *c, FormOptions opts, const GstVa
|
||||
/* Dispatch to a special form */
|
||||
static SpecialFormHelper get_special(const GstValue *form) {
|
||||
const uint8_t *name;
|
||||
if (gst_tuple_length(form) < 1 || form[0].type != GST_STRING)
|
||||
if (gst_tuple_length(form) < 1 || form[0].type != GST_SYMBOL)
|
||||
return NULL;
|
||||
name = form[0].data.string;
|
||||
/* If we have a symbol with a zero length name, we have other
|
||||
@ -1277,7 +1273,7 @@ static Slot compile_value(GstCompiler *c, FormOptions opts, GstValue x) {
|
||||
case GST_INTEGER:
|
||||
ret = compile_nonref_type(c, opts, x);
|
||||
break;
|
||||
case GST_STRING:
|
||||
case GST_SYMBOL:
|
||||
ret = compile_symbol(c, opts, x);
|
||||
break;
|
||||
case GST_TUPLE:
|
||||
|
@ -97,6 +97,7 @@ void gst_mark(Gst *vm, GstValueUnion x, GstType type) {
|
||||
break;
|
||||
|
||||
case GST_STRING:
|
||||
case GST_SYMBOL:
|
||||
gc_header(gst_string_raw(x.string))->color = vm->black;
|
||||
break;
|
||||
|
||||
|
10
core/ids.c
10
core/ids.c
@ -437,6 +437,16 @@ GstValue gst_string_cv(Gst *vm, const char *str) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Load a c string and return it as a GstValue. Return the symbol. */
|
||||
GstValue gst_string_cvs(Gst *vm, const char *str) {
|
||||
GstValue ret;
|
||||
/* Only put strings in cache */
|
||||
const uint8_t *data = gst_string_c(vm, str);
|
||||
ret.type = GST_SYMBOL;
|
||||
ret.data.string = data;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Compares two strings */
|
||||
int gst_string_compare(const uint8_t *lhs, const uint8_t *rhs) {
|
||||
uint32_t xlen = gst_string_length(lhs);
|
||||
|
22
core/parse.c
22
core/parse.c
@ -44,15 +44,15 @@ static GstParseState *parser_pop(GstParser * p) {
|
||||
return p->data + --p->count;
|
||||
}
|
||||
|
||||
/* Quote a value */
|
||||
static GstValue quote(GstParser *p, GstValue x) {
|
||||
/* Load a quote form to get the string literal */
|
||||
GstValue *tuple;
|
||||
tuple = gst_tuple_begin(p->vm, 2);
|
||||
tuple[0] = gst_string_cv(p->vm, "quote");
|
||||
tuple[1] = x;
|
||||
return gst_wrap_tuple(gst_tuple_end(p->vm, tuple));
|
||||
}
|
||||
// /* Quote a value */
|
||||
// static GstValue quote(GstParser *p, GstValue x) {
|
||||
// /* Load a quote form to get the string literal */
|
||||
// GstValue *tuple;
|
||||
// tuple = gst_tuple_begin(p->vm, 2);
|
||||
// tuple[0] = gst_string_cv(p->vm, "quote");
|
||||
// tuple[1] = x;
|
||||
// return gst_wrap_tuple(gst_tuple_end(p->vm, tuple));
|
||||
// }
|
||||
|
||||
/* Add a new, empty ParseState to the ParseStack. */
|
||||
static void parser_push(GstParser *p, ParseType type, uint8_t character) {
|
||||
@ -239,7 +239,7 @@ static GstValue build_token(GstParser *p, GstBuffer *buf) {
|
||||
p_error(p, "symbols cannot start with digits");
|
||||
x.type = GST_NIL;
|
||||
} else {
|
||||
x.type = GST_STRING;
|
||||
x.type = GST_SYMBOL;
|
||||
x.data.string = gst_buffer_to_string(p->vm, buf);
|
||||
}
|
||||
}
|
||||
@ -289,7 +289,7 @@ static int string_state(GstParser *p, uint8_t c) {
|
||||
x.type = GST_STRING;
|
||||
x.data.string = gst_buffer_to_string(p->vm, top->buf.string.buffer);
|
||||
parser_pop(p);
|
||||
parser_append(p, quote(p, x));
|
||||
parser_append(p, x);
|
||||
} else {
|
||||
gst_buffer_push(p->vm, top->buf.string.buffer, c);
|
||||
}
|
||||
|
@ -51,6 +51,7 @@
|
||||
* Byte 216: CFunc - [u32 length]*[u8... idstring]
|
||||
* Byte 217: Ref - [u32 id]
|
||||
* Byte 218: Integer - [i64 value]
|
||||
* Byte 219: Symbol - [u32 length]*[u8... characters]
|
||||
*/
|
||||
|
||||
/* Error at buffer end */
|
||||
@ -173,7 +174,8 @@ static const char *gst_deserialize_impl(
|
||||
break;
|
||||
|
||||
case 205: /* String */
|
||||
ret.type = GST_STRING;
|
||||
case 219: /* Symbol */
|
||||
ret.type = data[-1] == 205 ? GST_STRING : GST_SYMBOL;
|
||||
read_u32(length);
|
||||
deser_datacheck(length);
|
||||
ret.data.string = gst_string_b(vm, data, length);
|
||||
@ -582,7 +584,8 @@ static const char *gst_serialize_impl(
|
||||
return "unable to serialize type";
|
||||
|
||||
case GST_STRING:
|
||||
write_byte(205);
|
||||
case GST_SYMBOL:
|
||||
write_byte(x.type == GST_STRING ? 205 : 219);
|
||||
count = gst_string_length(x.data.string);
|
||||
write_u32(count);
|
||||
for (i = 0; i < count; ++i) {
|
||||
|
33
core/stl.c
33
core/stl.c
@ -180,6 +180,7 @@ int gst_stl_length(Gst *vm) {
|
||||
default:
|
||||
gst_c_throwc(vm, "cannot get length");
|
||||
case GST_STRING:
|
||||
case GST_SYMBOL:
|
||||
ret.data.integer = gst_string_length(x.data.string);
|
||||
break;
|
||||
case GST_ARRAY:
|
||||
@ -284,6 +285,8 @@ int gst_stl_slice(Gst *vm) {
|
||||
gst_c_return(vm, gst_wrap_array(arr));
|
||||
} else if (x.type == GST_STRING) {
|
||||
gst_c_return(vm, gst_wrap_string(gst_string_b(vm, x.data.string + from, newlength)));
|
||||
} else if (x.type == GST_SYMBOL) {
|
||||
gst_c_return(vm, gst_wrap_symbol(gst_string_b(vm, x.data.string + from, newlength)));
|
||||
} else { /* buffer */
|
||||
GstBuffer *b = gst_buffer(vm, newlength);
|
||||
gst_memcpy(b->data, x.data.buffer->data, newlength);
|
||||
@ -315,6 +318,9 @@ int gst_stl_type(Gst *vm) {
|
||||
case GST_STRING:
|
||||
typestr = "string";
|
||||
break;
|
||||
case GST_SYMBOL:
|
||||
typestr = "symbol";
|
||||
break;
|
||||
case GST_ARRAY:
|
||||
typestr = "array";
|
||||
break;
|
||||
@ -659,7 +665,7 @@ int gst_stl_deserialize(Gst *vm) {
|
||||
const uint8_t *data;
|
||||
const char *err;
|
||||
if (!gst_chararray_view(gst_arg(vm, 0), &data, &len))
|
||||
gst_c_throwc(vm, "expected string/buffer");
|
||||
gst_c_throwc(vm, "expected string/buffer/symbol");
|
||||
err = gst_deserialize(vm, data, len, &ret, &data);
|
||||
if (err != NULL)
|
||||
gst_c_throwc(vm, err);
|
||||
@ -679,8 +685,9 @@ int gst_stl_namespace(Gst *vm) {
|
||||
int gst_stl_namespace_set(Gst *vm) {
|
||||
GstValue name = gst_arg(vm, 0);
|
||||
GstValue check;
|
||||
if (name.type != GST_STRING)
|
||||
gst_c_throwc(vm, "expected string");
|
||||
if (name.type != GST_STRING || name.type == GST_SYMBOL)
|
||||
gst_c_throwc(vm, "expected string/symbol");
|
||||
name.type = GST_SYMBOL;
|
||||
check = gst_table_get(vm->modules, name);
|
||||
if (check.type == GST_TABLE) {
|
||||
vm->registry = check.data.table;
|
||||
@ -731,24 +738,28 @@ int gst_stl_funcparent(Gst *vm) {
|
||||
}
|
||||
|
||||
int gst_stl_def(Gst *vm) {
|
||||
GstValue key = gst_arg(vm, 0);
|
||||
if (gst_count_args(vm) != 2) {
|
||||
gst_c_throwc(vm, "expected 2 arguments to global-def");
|
||||
}
|
||||
if (GST_STRING != gst_arg(vm, 0).type) {
|
||||
gst_c_throwc(vm, "expected string as first argument");
|
||||
if (key.type != GST_STRING && key.type != GST_SYMBOL) {
|
||||
gst_c_throwc(vm, "expected string/symbol as first argument");
|
||||
}
|
||||
gst_env_put(vm, vm->env, gst_arg(vm, 0), gst_arg(vm, 1));
|
||||
key.type = GST_SYMBOL;
|
||||
gst_env_put(vm, vm->env, key, gst_arg(vm, 1));
|
||||
gst_c_return(vm, gst_arg(vm, 1));
|
||||
}
|
||||
|
||||
int gst_stl_var(Gst *vm) {
|
||||
GstValue key = gst_arg(vm, 0);
|
||||
if (gst_count_args(vm) != 2) {
|
||||
gst_c_throwc(vm, "expected 2 arguments to global-var");
|
||||
}
|
||||
if (GST_STRING != gst_arg(vm, 0).type) {
|
||||
if (key.type != GST_STRING && key.type != GST_SYMBOL) {
|
||||
gst_c_throwc(vm, "expected string as first argument");
|
||||
}
|
||||
gst_env_putvar(vm, vm->env, gst_arg(vm, 0), gst_arg(vm, 1));
|
||||
key.type = GST_SYMBOL;
|
||||
gst_env_putvar(vm, vm->env, key, gst_arg(vm, 1));
|
||||
gst_c_return(vm, gst_arg(vm, 1));
|
||||
}
|
||||
|
||||
@ -937,7 +948,7 @@ static int gst_stl_parser_charseq(Gst *vm) {
|
||||
if (p == NULL)
|
||||
gst_c_throwc(vm, "expected parser");
|
||||
if (!gst_chararray_view(gst_arg(vm, 1), &data, &len))
|
||||
gst_c_throwc(vm, "expected string/buffer");
|
||||
gst_c_throwc(vm, "expected string/buffer/symbol");
|
||||
for (i = 0; i < len; ++i) {
|
||||
if (p->status != GST_PARSER_PENDING && p->status != GST_PARSER_ROOT) break;
|
||||
gst_parse_byte(p, data[i]);
|
||||
@ -983,7 +994,7 @@ static int gst_stl_parse(Gst *vm) {
|
||||
GstParser p;
|
||||
const uint8_t *data;
|
||||
if (!gst_chararray_view(gst_arg(vm, 0), &data, &len))
|
||||
gst_c_throwc(vm, "expected string/buffer to parse");
|
||||
gst_c_throwc(vm, "expected string/buffer/symbol to parse");
|
||||
gst_parser(&p, vm);
|
||||
for (i = 0; i < len; ++i) {
|
||||
if (p.status != GST_PARSER_PENDING && p.status != GST_PARSER_ROOT) break;
|
||||
@ -1129,7 +1140,7 @@ void gst_stl_load(Gst *vm) {
|
||||
gst_module_put(vm, "std", "stdin", gst_wrap_userdata(inp));
|
||||
gst_module_put(vm, "std", "stdout", gst_wrap_userdata(outp));
|
||||
gst_module_put(vm, "std", "stderr", gst_wrap_userdata(outp));
|
||||
maybeEnv = gst_table_get(vm->modules, gst_string_cv(vm, "std"));
|
||||
maybeEnv = gst_table_get(vm->modules, gst_string_cvs(vm, "std"));
|
||||
if (maybeEnv.type == GST_TABLE)
|
||||
gst_env_merge(vm, vm->env, maybeEnv.data.table);
|
||||
}
|
||||
|
31
core/util.c
31
core/util.c
@ -55,6 +55,7 @@ GST_WRAP_DEFINE(real, GstReal, GST_REAL, real)
|
||||
GST_WRAP_DEFINE(integer, GstInteger, GST_INTEGER, integer)
|
||||
GST_WRAP_DEFINE(boolean, int, GST_BOOLEAN, boolean)
|
||||
GST_WRAP_DEFINE(string, const uint8_t *, GST_STRING, string)
|
||||
GST_WRAP_DEFINE(symbol, const uint8_t *, GST_SYMBOL, string)
|
||||
GST_WRAP_DEFINE(array, GstArray *, GST_ARRAY, array)
|
||||
GST_WRAP_DEFINE(tuple, const GstValue *, GST_TUPLE, tuple)
|
||||
GST_WRAP_DEFINE(struct, const GstValue *, GST_STRUCT, st)
|
||||
@ -94,7 +95,7 @@ static void gst_cmodule_register(Gst *vm, const char *name, const GstModuleItem
|
||||
GstValue key;
|
||||
buffer->count = startLength;
|
||||
gst_buffer_append_cstring(vm, buffer, mod->name);
|
||||
key = gst_wrap_string(gst_buffer_to_string(vm, buffer));
|
||||
key = gst_wrap_symbol(gst_buffer_to_string(vm, buffer));
|
||||
gst_table_put(vm, vm->registry, key, gst_wrap_cfunction(mod->data));
|
||||
gst_table_put(vm, vm->registry, gst_wrap_cfunction(mod->data), key);
|
||||
mod++;
|
||||
@ -104,7 +105,7 @@ static void gst_cmodule_register(Gst *vm, const char *name, const GstModuleItem
|
||||
static 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);
|
||||
GstValue key = gst_string_cvs(vm, mod->name);
|
||||
gst_table_put(vm, module, key, gst_wrap_cfunction(mod->data));
|
||||
mod++;
|
||||
}
|
||||
@ -123,7 +124,7 @@ static GstValue gst_cmodule_struct(Gst *vm, const GstModuleItem *mod) {
|
||||
m = mod;
|
||||
while (m->name != NULL) {
|
||||
gst_struct_put(st,
|
||||
gst_string_cv(vm, m->name),
|
||||
gst_string_cvs(vm, m->name),
|
||||
gst_wrap_cfunction(m->data));
|
||||
++m;
|
||||
}
|
||||
@ -131,17 +132,17 @@ static GstValue gst_cmodule_struct(Gst *vm, const GstModuleItem *mod) {
|
||||
}
|
||||
|
||||
void gst_module(Gst *vm, const char *packagename, const GstModuleItem *mod) {
|
||||
gst_table_put(vm, vm->modules, gst_string_cv(vm, packagename), gst_cmodule_struct(vm, mod));
|
||||
gst_table_put(vm, vm->modules, gst_string_cvs(vm, packagename), gst_cmodule_struct(vm, mod));
|
||||
gst_cmodule_register(vm, packagename, mod);
|
||||
}
|
||||
|
||||
void gst_module_mutable(Gst *vm, const char *packagename, const GstModuleItem *mod) {
|
||||
gst_table_put(vm, vm->modules, gst_string_cv(vm, packagename), gst_cmodule_table(vm, mod));
|
||||
gst_table_put(vm, vm->modules, gst_string_cvs(vm, packagename), gst_cmodule_table(vm, mod));
|
||||
gst_cmodule_register(vm, packagename, mod);
|
||||
}
|
||||
|
||||
void gst_module_put(Gst *vm, const char *packagename, const char *name, GstValue v) {
|
||||
GstValue modtable = gst_table_get(vm->modules, gst_string_cv(vm, packagename));
|
||||
GstValue modtable = gst_table_get(vm->modules, gst_string_cvs(vm, packagename));
|
||||
if (modtable.type == GST_TABLE) {
|
||||
GstTable *table = modtable.data.table;
|
||||
if (v.type == GST_CFUNCTION) {
|
||||
@ -154,12 +155,12 @@ void gst_module_put(Gst *vm, const char *packagename, const char *name, GstValue
|
||||
gst_table_put(vm, vm->registry, key, v);
|
||||
gst_table_put(vm, vm->registry, v, key);
|
||||
}
|
||||
gst_table_put(vm, table, gst_string_cv(vm, name), v);
|
||||
gst_table_put(vm, table, gst_string_cvs(vm, name), v);
|
||||
}
|
||||
}
|
||||
|
||||
GstValue gst_module_get(Gst *vm, const char *packagename) {
|
||||
return gst_table_get(vm->modules, gst_string_cv(vm, packagename));
|
||||
return gst_table_get(vm->modules, gst_string_cvs(vm, packagename));
|
||||
}
|
||||
|
||||
/****/
|
||||
@ -186,7 +187,7 @@ int gst_seq_view(GstValue seq, const GstValue **data, uint32_t *len) {
|
||||
/* Read both strings and buffer as unsigned character array + uint32_t len.
|
||||
* Returns 1 if the view can be constructed and 0 if the type is invalid. */
|
||||
int gst_chararray_view(GstValue str, const uint8_t **data, uint32_t *len) {
|
||||
if (str.type == GST_STRING) {
|
||||
if (str.type == GST_STRING || str.type == GST_SYMBOL) {
|
||||
*data = str.data.string;
|
||||
*len = gst_string_length(str.data.string);
|
||||
return 1;
|
||||
@ -281,7 +282,7 @@ static void mergenils(Gst *vm, GstTable *destEnv, GstTable *nils) {
|
||||
uint32_t i;
|
||||
GstTable *destNils = gst_env_nils(vm, destEnv);
|
||||
for (i = 0; i < len; i += 2) {
|
||||
if (data[i].type == GST_STRING) {
|
||||
if (data[i].type == GST_SYMBOL) {
|
||||
gst_table_put(vm, destEnv, data[i], gst_wrap_nil());
|
||||
gst_table_put(vm, destNils, data[i], gst_wrap_boolean(1));
|
||||
}
|
||||
@ -295,7 +296,7 @@ static void mergemeta(Gst *vm, GstTable *destEnv, GstTable *meta) {
|
||||
uint32_t i;
|
||||
GstTable *destMeta = gst_env_meta(vm, destEnv);
|
||||
for (i = 0; i < len; i += 2) {
|
||||
if (data[i].type == GST_STRING) {
|
||||
if (data[i].type == GST_SYMBOL) {
|
||||
gst_table_put(vm, destMeta, data[i], data[i + 1]);
|
||||
}
|
||||
}
|
||||
@ -307,7 +308,7 @@ void gst_env_merge(Gst *vm, GstTable *destEnv, GstTable *srcEnv) {
|
||||
uint32_t len = srcEnv->capacity;
|
||||
uint32_t i;
|
||||
for (i = 0; i < len; i += 2) {
|
||||
if (data[i].type == GST_STRING) {
|
||||
if (data[i].type == GST_SYMBOL) {
|
||||
gst_table_put(vm, destEnv, data[i], data[i + 1]);
|
||||
} else if (data[i].type == GST_INTEGER) {
|
||||
switch (data[i].data.integer) {
|
||||
@ -336,7 +337,7 @@ void gst_env_put(Gst *vm, GstTable *env, GstValue key, GstValue value) {
|
||||
}
|
||||
|
||||
void gst_env_putc(Gst *vm, GstTable *env, const char *key, GstValue value) {
|
||||
GstValue keyv = gst_string_cv(vm, key);
|
||||
GstValue keyv = gst_string_cvs(vm, key);
|
||||
gst_env_put(vm, env, keyv, value);
|
||||
}
|
||||
|
||||
@ -347,11 +348,11 @@ void gst_env_putvar(Gst *vm, GstTable *env, GstValue key, GstValue value) {
|
||||
ref->count = 1;
|
||||
ref->data[0] = value;
|
||||
gst_table_put(vm, env, key, gst_wrap_array(ref));
|
||||
gst_table_put(vm, newmeta, gst_string_cv(vm, "mutable"), gst_wrap_boolean(1));
|
||||
gst_table_put(vm, newmeta, gst_string_cvs(vm, "mutable"), gst_wrap_boolean(1));
|
||||
gst_table_put(vm, meta, key, gst_wrap_table(newmeta));
|
||||
}
|
||||
|
||||
void gst_env_putvarc(Gst *vm, GstTable *env, const char *key, GstValue value) {
|
||||
GstValue keyv = gst_string_cv(vm, key);
|
||||
GstValue keyv = gst_string_cvs(vm, key);
|
||||
gst_env_putvar(vm, env, keyv, value);
|
||||
}
|
@ -180,6 +180,8 @@ const uint8_t *gst_short_description(Gst *vm, GstValue x) {
|
||||
return string_description(vm, "struct", x.data.pointer);
|
||||
case GST_TABLE:
|
||||
return string_description(vm, "table", x.data.pointer);
|
||||
case GST_SYMBOL:
|
||||
return x.data.string;
|
||||
case GST_STRING:
|
||||
{
|
||||
GstBuffer *buf = gst_buffer(vm, gst_string_length(x.data.string) + 4);
|
||||
@ -227,6 +229,9 @@ static GstInteger gst_description_helper(Gst *vm, GstBuffer *b, GstTable *seen,
|
||||
case GST_STRING:
|
||||
gst_escape_string(vm, b, x.data.string);
|
||||
return next;
|
||||
case GST_SYMBOL:
|
||||
gst_buffer_append(vm, b, x.data.string, gst_string_length(x.data.string));
|
||||
return next;
|
||||
case GST_NIL:
|
||||
gst_buffer_append_cstring(vm, b, "nil");
|
||||
return next;
|
||||
@ -287,7 +292,7 @@ const uint8_t *gst_description(Gst *vm, GstValue x) {
|
||||
}
|
||||
|
||||
const uint8_t *gst_to_string(Gst *vm, GstValue x) {
|
||||
if (x.type == GST_STRING) {
|
||||
if (x.type == GST_STRING || x.type == GST_SYMBOL) {
|
||||
return x.data.string;
|
||||
} else if (x.type == GST_BYTEBUFFER) {
|
||||
return gst_buffer_to_string(vm, x.data.buffer);
|
||||
@ -335,6 +340,7 @@ uint32_t gst_hash(GstValue x) {
|
||||
hash = x.data.boolean;
|
||||
break;
|
||||
case GST_STRING:
|
||||
case GST_SYMBOL:
|
||||
hash = gst_string_hash(x.data.string);
|
||||
break;
|
||||
case GST_TUPLE:
|
||||
@ -436,6 +442,7 @@ const char *gst_get(GstValue ds, GstValue key, GstValue *out) {
|
||||
ret.data.integer = ds.data.buffer->data[index];
|
||||
break;
|
||||
case GST_STRING:
|
||||
case GST_SYMBOL:
|
||||
if (key.type != GST_INTEGER) return "expected integer key";
|
||||
index = gst_startrange(key.data.integer, gst_string_length(ds.data.string));
|
||||
if (index < 0) return "invalid string access";
|
||||
|
@ -43,13 +43,20 @@
|
||||
(assert (= 7 (bor 3 4)) "bit or")
|
||||
(assert (= 0 (band 3 4)) "bit and")
|
||||
|
||||
((fn []
|
||||
(var accum 1)
|
||||
(var count 0)
|
||||
(while (< count 16)
|
||||
(varset! accum (blshift accum 1))
|
||||
(varset! count (+ 1 count)))
|
||||
(assert (= accum 65536) "loop in closure")))
|
||||
|
||||
(var accum 1)
|
||||
(var count 0)
|
||||
(while (< count 16)
|
||||
(varset! accum (blshift accum 1))
|
||||
(varset! count (+ 1 count)))
|
||||
|
||||
(assert (= accum 65536) "loop")
|
||||
(assert (= accum 65536) "loop globally")
|
||||
|
||||
(assert (= (struct 1 2 3 4 5 6 7 8) (struct 7 8 5 6 3 4 1 2)) "struct order does not matter")
|
||||
|
||||
|
@ -129,6 +129,7 @@ typedef enum GstType {
|
||||
GST_INTEGER,
|
||||
GST_BOOLEAN,
|
||||
GST_STRING,
|
||||
GST_SYMBOL,
|
||||
GST_ARRAY,
|
||||
GST_TUPLE,
|
||||
GST_TABLE,
|
||||
@ -459,7 +460,7 @@ GstValue *gst_tuple_begin(Gst *vm, uint32_t length);
|
||||
const GstValue *gst_tuple_end(Gst *vm, GstValue *tuple);
|
||||
|
||||
/****/
|
||||
/* String functions */
|
||||
/* String/Symbol functions */
|
||||
/****/
|
||||
|
||||
uint8_t *gst_string_begin(Gst *vm, uint32_t len);
|
||||
@ -467,6 +468,7 @@ const uint8_t *gst_string_end(Gst *vm, uint8_t *str);
|
||||
const uint8_t *gst_string_b(Gst *vm, const uint8_t *buf, uint32_t len);
|
||||
const uint8_t *gst_string_c(Gst *vm, const char *cstring);
|
||||
GstValue gst_string_cv(Gst *vm, const char *string);
|
||||
GstValue gst_string_cvs(Gst *vm, const char *string);
|
||||
int gst_string_compare(const uint8_t *lhs, const uint8_t *rhs);
|
||||
|
||||
/****/
|
||||
@ -609,6 +611,7 @@ GstValue gst_wrap_real(GstReal x);
|
||||
GstValue gst_wrap_integer(GstInteger x);
|
||||
GstValue gst_wrap_boolean(int x);
|
||||
GstValue gst_wrap_string(const uint8_t *x);
|
||||
GstValue gst_wrap_symbol(const uint8_t *x);
|
||||
GstValue gst_wrap_array(GstArray *x);
|
||||
GstValue gst_wrap_tuple(const GstValue *x);
|
||||
GstValue gst_wrap_struct(const GstValue *x);
|
||||
@ -627,6 +630,7 @@ int gst_check_real(Gst *vm, uint32_t i, GstReal (*x));
|
||||
int gst_check_integer(Gst *vm, uint32_t i, GstInteger (*x));
|
||||
int gst_check_boolean(Gst *vm, uint32_t i, int (*x));
|
||||
int gst_check_string(Gst *vm, uint32_t i, const uint8_t *(*x));
|
||||
int gst_check_symbol(Gst *vm, uint32_t i, const uint8_t *(*x));
|
||||
int gst_check_array(Gst *vm, uint32_t i, GstArray *(*x));
|
||||
int gst_check_tuple(Gst *vm, uint32_t i, const GstValue *(*x));
|
||||
int gst_check_struct(Gst *vm, uint32_t i, const GstValue *(*x));
|
||||
|
Loading…
Reference in New Issue
Block a user