mirror of
https://github.com/janet-lang/janet
synced 2024-12-01 04:19:55 +00:00
Remove symbol type in favor of only strings. Anticipate
addition of struct type, which will be an immutable hashtable.
This commit is contained in:
parent
e28e31f818
commit
20bb5a18f7
@ -59,7 +59,7 @@ void debug_repl(FILE *in, FILE *out) {
|
|||||||
gst_compiler(&c, &vm);
|
gst_compiler(&c, &vm);
|
||||||
func.type = GST_NIL;
|
func.type = GST_NIL;
|
||||||
gst_compiler_usemodule(&c, "std");
|
gst_compiler_usemodule(&c, "std");
|
||||||
gst_compiler_global(&c, "ans", gst_object_get(vm.rootenv, gst_load_csymbol(&vm, "ans")));
|
gst_compiler_global(&c, "ans", gst_object_get(vm.rootenv, gst_load_cstring(&vm, "ans")));
|
||||||
func.type = GST_FUNCTION;
|
func.type = GST_FUNCTION;
|
||||||
func.data.function = gst_compiler_compile(&c, p.value);
|
func.data.function = gst_compiler_compile(&c, p.value);
|
||||||
|
|
||||||
@ -73,12 +73,6 @@ void debug_repl(FILE *in, FILE *out) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print asm */
|
|
||||||
/*if (out) {
|
|
||||||
fprintf(out, "\n");
|
|
||||||
gst_dasm_function(out, func.data.function);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/* Execute function */
|
/* Execute function */
|
||||||
if (gst_run(&vm, func)) {
|
if (gst_run(&vm, func)) {
|
||||||
if (out) {
|
if (out) {
|
||||||
@ -94,7 +88,7 @@ void debug_repl(FILE *in, FILE *out) {
|
|||||||
continue;
|
continue;
|
||||||
} else if (out) {
|
} else if (out) {
|
||||||
fprintf(out, "%s\n", (char *)gst_to_string(&vm, vm.ret));
|
fprintf(out, "%s\n", (char *)gst_to_string(&vm, vm.ret));
|
||||||
gst_object_put(&vm, vm.rootenv, gst_load_csymbol(&vm, "ans"), vm.ret);
|
gst_object_put(&vm, vm.rootenv, gst_load_cstring(&vm, "ans"), vm.ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
GstObject *gst_c_module(Gst *vm, const GstModuleItem *mod) {
|
GstObject *gst_c_module(Gst *vm, const GstModuleItem *mod) {
|
||||||
GstObject *module = gst_object(vm, 10);
|
GstObject *module = gst_object(vm, 10);
|
||||||
while (mod->name != NULL) {
|
while (mod->name != NULL) {
|
||||||
GstValue key = gst_load_csymbol(vm, mod->name);
|
GstValue key = gst_load_cstring(vm, mod->name);
|
||||||
GstValue val;
|
GstValue val;
|
||||||
val.type = GST_CFUNCTION;
|
val.type = GST_CFUNCTION;
|
||||||
val.data.cfunction = mod->data;
|
val.data.cfunction = mod->data;
|
||||||
@ -19,5 +19,5 @@ void gst_c_register(Gst *vm, const char *packagename, GstObject *mod) {
|
|||||||
vm->rootenv = gst_object(vm, 10);
|
vm->rootenv = gst_object(vm, 10);
|
||||||
modv.type = GST_OBJECT;
|
modv.type = GST_OBJECT;
|
||||||
modv.data.object = mod;
|
modv.data.object = mod;
|
||||||
gst_object_put(vm, vm->rootenv, gst_load_csymbol(vm, packagename), modv);
|
gst_object_put(vm, vm->rootenv, gst_load_cstring(vm, packagename), modv);
|
||||||
}
|
}
|
||||||
|
@ -316,8 +316,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) {
|
static uint16_t compiler_declare_symbol(GstCompiler *c, GstScope *scope, GstValue sym) {
|
||||||
GstValue x;
|
GstValue x;
|
||||||
uint16_t target;
|
uint16_t target;
|
||||||
if (sym.type != GST_SYMBOL)
|
if (sym.type != GST_STRING)
|
||||||
c_error(c, "expected symbol");
|
c_error(c, "expected string");
|
||||||
target = compiler_get_local(c, scope);
|
target = compiler_get_local(c, scope);
|
||||||
x.type = GST_NUMBER;
|
x.type = GST_NUMBER;
|
||||||
x.data.number = target;
|
x.data.number = target;
|
||||||
@ -564,8 +564,8 @@ static Slot compile_function(GstCompiler *c, FormOptions opts, GstValue *form) {
|
|||||||
params = form[current++].data.array;
|
params = form[current++].data.array;
|
||||||
for (i = 0; i < params->count; ++i) {
|
for (i = 0; i < params->count; ++i) {
|
||||||
GstValue param = params->data[i];
|
GstValue param = params->data[i];
|
||||||
if (param.type != GST_SYMBOL)
|
if (param.type != GST_STRING)
|
||||||
c_error(c, "function parameters should be symbols");
|
c_error(c, "function parameters should be strings");
|
||||||
/* The compiler puts the parameter locals
|
/* The compiler puts the parameter locals
|
||||||
* in the right place by default - at the beginning
|
* in the right place by default - at the beginning
|
||||||
* of the stack frame. */
|
* of the stack frame. */
|
||||||
@ -676,8 +676,8 @@ static Slot compile_try(GstCompiler *c, FormOptions opts, GstValue *form) {
|
|||||||
if (gst_tuple_length(form) < 3 || gst_tuple_length(form) > 4)
|
if (gst_tuple_length(form) < 3 || gst_tuple_length(form) > 4)
|
||||||
c_error(c, "try takes either 2 or 3 arguments");
|
c_error(c, "try takes either 2 or 3 arguments");
|
||||||
/* Check for symbol to bind error to */
|
/* Check for symbol to bind error to */
|
||||||
if (form[1].type != GST_SYMBOL)
|
if (form[1].type != GST_STRING)
|
||||||
c_error(c, "expected symbol at start of try");
|
c_error(c, "expected string at start of try");
|
||||||
/* Add subscope for error variable */
|
/* Add subscope for error variable */
|
||||||
GstScope *subScope = compiler_push_scope(c, 1);
|
GstScope *subScope = compiler_push_scope(c, 1);
|
||||||
errorIndex = compiler_declare_symbol(c, subScope, form[1]);
|
errorIndex = compiler_declare_symbol(c, subScope, form[1]);
|
||||||
@ -813,7 +813,7 @@ typedef Slot (*SpecialFormHelper) (GstCompiler *c, FormOptions opts, GstValue *f
|
|||||||
/* Dispatch to a special form */
|
/* Dispatch to a special form */
|
||||||
static SpecialFormHelper get_special(GstValue *form) {
|
static SpecialFormHelper get_special(GstValue *form) {
|
||||||
const uint8_t *name;
|
const uint8_t *name;
|
||||||
if (gst_tuple_length(form) < 1 || form[0].type != GST_SYMBOL)
|
if (gst_tuple_length(form) < 1 || form[0].type != GST_STRING)
|
||||||
return NULL;
|
return NULL;
|
||||||
name = form[0].data.string;
|
name = form[0].data.string;
|
||||||
/* If we have a symbol with a zero length name, we have other
|
/* If we have a symbol with a zero length name, we have other
|
||||||
@ -1001,7 +1001,7 @@ static Slot compile_value(GstCompiler *c, FormOptions opts, GstValue x) {
|
|||||||
case GST_BOOLEAN:
|
case GST_BOOLEAN:
|
||||||
case GST_NUMBER:
|
case GST_NUMBER:
|
||||||
return compile_nonref_type(c, opts, x);
|
return compile_nonref_type(c, opts, x);
|
||||||
case GST_SYMBOL:
|
case GST_STRING:
|
||||||
return compile_symbol(c, opts, x);
|
return compile_symbol(c, opts, x);
|
||||||
case GST_TUPLE:
|
case GST_TUPLE:
|
||||||
return compile_form(c, opts, x.data.tuple);
|
return compile_form(c, opts, x.data.tuple);
|
||||||
@ -1026,7 +1026,7 @@ void gst_compiler(GstCompiler *c, Gst *vm) {
|
|||||||
|
|
||||||
/* Add a global variable */
|
/* Add a global variable */
|
||||||
void gst_compiler_global(GstCompiler *c, const char *name, GstValue x) {
|
void gst_compiler_global(GstCompiler *c, const char *name, GstValue x) {
|
||||||
GstValue sym = gst_load_csymbol(c->vm, name);
|
GstValue sym = gst_load_cstring(c->vm, name);
|
||||||
compiler_declare_symbol(c, c->tail, sym);
|
compiler_declare_symbol(c, c->tail, sym);
|
||||||
gst_array_push(c->vm, c->env, x);
|
gst_array_push(c->vm, c->env, x);
|
||||||
}
|
}
|
||||||
@ -1038,7 +1038,7 @@ void gst_compiler_globals(GstCompiler *c, GstObject *env) {
|
|||||||
for (i = 0; i < env->capacity; ++i) {
|
for (i = 0; i < env->capacity; ++i) {
|
||||||
bucket = env->buckets[i];
|
bucket = env->buckets[i];
|
||||||
while (bucket) {
|
while (bucket) {
|
||||||
if (bucket->key.type == GST_SYMBOL) {
|
if (bucket->key.type == GST_STRING) {
|
||||||
compiler_declare_symbol(c, c->tail, bucket->key);
|
compiler_declare_symbol(c, c->tail, bucket->key);
|
||||||
gst_array_push(c->vm, c->env, bucket->value);
|
gst_array_push(c->vm, c->env, bucket->value);
|
||||||
}
|
}
|
||||||
@ -1049,7 +1049,7 @@ void gst_compiler_globals(GstCompiler *c, GstObject *env) {
|
|||||||
|
|
||||||
/* Use a module that was loaded into the vm */
|
/* Use a module that was loaded into the vm */
|
||||||
void gst_compiler_usemodule(GstCompiler *c, const char *modulename) {
|
void gst_compiler_usemodule(GstCompiler *c, const char *modulename) {
|
||||||
GstValue mod = gst_object_get(c->vm->rootenv, gst_load_csymbol(c->vm, modulename));
|
GstValue mod = gst_object_get(c->vm->rootenv, gst_load_cstring(c->vm, modulename));
|
||||||
if (mod.type == GST_OBJECT) {
|
if (mod.type == GST_OBJECT) {
|
||||||
gst_compiler_globals(c, mod.data.object);
|
gst_compiler_globals(c, mod.data.object);
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,6 @@ void gst_mark(Gst *vm, GstValueUnion x, GstType type) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case GST_STRING:
|
case GST_STRING:
|
||||||
case GST_SYMBOL:
|
|
||||||
gc_header(gst_string_raw(x.string))->color = vm->black;
|
gc_header(gst_string_raw(x.string))->color = vm->black;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ static GstValue quote(GstParser *p, GstValue x) {
|
|||||||
tuple = gst_tuple(p->vm, 2);
|
tuple = gst_tuple(p->vm, 2);
|
||||||
tuplev.type = GST_TUPLE;
|
tuplev.type = GST_TUPLE;
|
||||||
tuplev.data.tuple = tuple;
|
tuplev.data.tuple = tuple;
|
||||||
tuple[0] = gst_load_csymbol(p->vm, "quote");
|
tuple[0] = gst_load_cstring(p->vm, "quote");
|
||||||
tuple[1] = x;
|
tuple[1] = x;
|
||||||
return tuplev;
|
return tuplev;
|
||||||
}
|
}
|
||||||
@ -238,7 +238,7 @@ static GstValue build_token(GstParser *p, GstBuffer *buf) {
|
|||||||
p_error(p, "symbols cannot start with digits");
|
p_error(p, "symbols cannot start with digits");
|
||||||
x.type = GST_NIL;
|
x.type = GST_NIL;
|
||||||
} else {
|
} else {
|
||||||
x.type = GST_SYMBOL;
|
x.type = GST_STRING;
|
||||||
x.data.string = gst_buffer_to_string(p->vm, buf);
|
x.data.string = gst_buffer_to_string(p->vm, buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -288,7 +288,7 @@ static int string_state(GstParser *p, uint8_t c) {
|
|||||||
x.type = GST_STRING;
|
x.type = GST_STRING;
|
||||||
x.data.string = gst_buffer_to_string(p->vm, top->buf.string.buffer);
|
x.data.string = gst_buffer_to_string(p->vm, top->buf.string.buffer);
|
||||||
parser_pop(p);
|
parser_pop(p);
|
||||||
parser_append(p, x);
|
parser_append(p, quote(p, x));
|
||||||
} else {
|
} else {
|
||||||
gst_buffer_push(p->vm, top->buf.string.buffer, c);
|
gst_buffer_push(p->vm, top->buf.string.buffer, c);
|
||||||
}
|
}
|
||||||
|
@ -111,6 +111,9 @@ static const char *gst_deserialize_impl(
|
|||||||
/* Main switch for types */
|
/* Main switch for types */
|
||||||
switch (*data++) {
|
switch (*data++) {
|
||||||
|
|
||||||
|
default:
|
||||||
|
return "unable to deserialize";
|
||||||
|
|
||||||
case 201: /* Nil */
|
case 201: /* Nil */
|
||||||
ret.type = GST_NIL;
|
ret.type = GST_NIL;
|
||||||
break;
|
break;
|
||||||
@ -131,8 +134,7 @@ static const char *gst_deserialize_impl(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 205: /* String */
|
case 205: /* String */
|
||||||
case 206: /* Symbol */
|
ret.type = GST_STRING;
|
||||||
ret.type = data[-1] == 205 ? GST_STRING : GST_SYMBOL;
|
|
||||||
read_u32(length);
|
read_u32(length);
|
||||||
deser_datacheck(length);
|
deser_datacheck(length);
|
||||||
ret.data.string = gst_string_loadbuffer(vm, data, length);
|
ret.data.string = gst_string_loadbuffer(vm, data, length);
|
||||||
@ -463,8 +465,7 @@ const char *gst_serialize_impl(
|
|||||||
default:
|
default:
|
||||||
return "unable to serialize type";
|
return "unable to serialize type";
|
||||||
case GST_STRING:
|
case GST_STRING:
|
||||||
case GST_SYMBOL:
|
write_byte(205);
|
||||||
write_byte(x.type == GST_STRING ? 205 : 206);
|
|
||||||
count = gst_string_length(x.data.string);
|
count = gst_string_length(x.data.string);
|
||||||
write_u32(count);
|
write_u32(count);
|
||||||
for (i = 0; i < count; ++i) {
|
for (i = 0; i < count; ++i) {
|
||||||
|
@ -113,7 +113,6 @@ int gst_stl_length(Gst *vm) {
|
|||||||
default:
|
default:
|
||||||
gst_c_throwc(vm, "cannot get length");
|
gst_c_throwc(vm, "cannot get length");
|
||||||
case GST_STRING:
|
case GST_STRING:
|
||||||
case GST_SYMBOL:
|
|
||||||
ret.data.number = gst_string_length(x.data.string);
|
ret.data.number = gst_string_length(x.data.string);
|
||||||
break;
|
break;
|
||||||
case GST_ARRAY:
|
case GST_ARRAY:
|
||||||
@ -167,9 +166,6 @@ int gst_stl_type(Gst *vm) {
|
|||||||
case GST_STRING:
|
case GST_STRING:
|
||||||
typestr = "string";
|
typestr = "string";
|
||||||
break;
|
break;
|
||||||
case GST_SYMBOL:
|
|
||||||
typestr = "symbol";
|
|
||||||
break;
|
|
||||||
case GST_ARRAY:
|
case GST_ARRAY:
|
||||||
typestr = "array";
|
typestr = "array";
|
||||||
break;
|
break;
|
||||||
@ -276,7 +272,7 @@ int gst_stl_strcat(Gst *vm) {
|
|||||||
/* Find length and assert string arguments */
|
/* Find length and assert string arguments */
|
||||||
for (j = 0; j < count; ++j) {
|
for (j = 0; j < count; ++j) {
|
||||||
GstValue arg = gst_arg(vm, j);
|
GstValue arg = gst_arg(vm, j);
|
||||||
if (arg.type != GST_STRING && arg.type != GST_SYMBOL)
|
if (arg.type != GST_STRING)
|
||||||
gst_c_throwc(vm, GST_EXPECTED_STRING);
|
gst_c_throwc(vm, GST_EXPECTED_STRING);
|
||||||
length += gst_string_length(arg.data.string);
|
length += gst_string_length(arg.data.string);
|
||||||
}
|
}
|
||||||
|
@ -220,14 +220,6 @@ GstValue gst_load_cstring(Gst *vm, const char *string) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load a c string into a GST symbol */
|
|
||||||
GstValue gst_load_csymbol(Gst *vm, const char *string) {
|
|
||||||
GstValue ret;
|
|
||||||
ret.type = GST_SYMBOL;
|
|
||||||
ret.data.string = gst_cstring_to_string(vm, string);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compares two strings */
|
/* Compares two strings */
|
||||||
int gst_string_compare(const uint8_t *lhs, const uint8_t *rhs) {
|
int gst_string_compare(const uint8_t *lhs, const uint8_t *rhs) {
|
||||||
uint32_t xlen = gst_string_length(lhs);
|
uint32_t xlen = gst_string_length(lhs);
|
||||||
|
@ -70,8 +70,6 @@ const uint8_t *gst_to_string(Gst *vm, GstValue x) {
|
|||||||
return string_description(vm, "object", x.data.pointer);
|
return string_description(vm, "object", x.data.pointer);
|
||||||
case GST_STRING:
|
case GST_STRING:
|
||||||
return x.data.string;
|
return x.data.string;
|
||||||
case GST_SYMBOL:
|
|
||||||
return string_description(vm, "symbol", x.data.pointer);
|
|
||||||
case GST_BYTEBUFFER:
|
case GST_BYTEBUFFER:
|
||||||
return string_description(vm, "buffer", x.data.pointer);
|
return string_description(vm, "buffer", x.data.pointer);
|
||||||
case GST_CFUNCTION:
|
case GST_CFUNCTION:
|
||||||
@ -168,7 +166,6 @@ uint32_t gst_hash(GstValue x) {
|
|||||||
break;
|
break;
|
||||||
/* String hashes */
|
/* String hashes */
|
||||||
case GST_STRING:
|
case GST_STRING:
|
||||||
case GST_SYMBOL:
|
|
||||||
hash = gst_string_hash(x.data.string);
|
hash = gst_string_hash(x.data.string);
|
||||||
break;
|
break;
|
||||||
case GST_TUPLE:
|
case GST_TUPLE:
|
||||||
@ -214,7 +211,6 @@ int gst_compare(GstValue x, GstValue y) {
|
|||||||
return x.data.number > y.data.number ? 1 : -1;
|
return x.data.number > y.data.number ? 1 : -1;
|
||||||
}
|
}
|
||||||
case GST_STRING:
|
case GST_STRING:
|
||||||
case GST_SYMBOL:
|
|
||||||
return gst_string_compare(x.data.string, y.data.string);
|
return gst_string_compare(x.data.string, y.data.string);
|
||||||
/* Lower indices are most significant */
|
/* Lower indices are most significant */
|
||||||
case GST_TUPLE:
|
case GST_TUPLE:
|
||||||
@ -302,7 +298,6 @@ const char *gst_get(GstValue ds, GstValue key, GstValue *out) {
|
|||||||
ret.data.number = ds.data.buffer->data[index];
|
ret.data.number = ds.data.buffer->data[index];
|
||||||
break;
|
break;
|
||||||
case GST_STRING:
|
case GST_STRING:
|
||||||
case GST_SYMBOL:
|
|
||||||
if (key.type != GST_NUMBER) return "expected numeric key";
|
if (key.type != GST_NUMBER) return "expected numeric key";
|
||||||
index = to_index(key.data.number, gst_string_length(ds.data.string));
|
index = to_index(key.data.number, gst_string_length(ds.data.string));
|
||||||
if (index == -1) return "invalid string access";
|
if (index == -1) return "invalid string access";
|
||||||
@ -354,7 +349,6 @@ int gst_length(Gst *vm, GstValue x, GstValue *len) {
|
|||||||
vm->ret = gst_load_cstring(vm, "cannot get length");
|
vm->ret = gst_load_cstring(vm, "cannot get length");
|
||||||
return GST_RETURN_ERROR;
|
return GST_RETURN_ERROR;
|
||||||
case GST_STRING:
|
case GST_STRING:
|
||||||
case GST_SYMBOL:
|
|
||||||
length = gst_string_length(x.data.string);
|
length = gst_string_length(x.data.string);
|
||||||
break;
|
break;
|
||||||
case GST_ARRAY:
|
case GST_ARRAY:
|
||||||
|
@ -13,6 +13,12 @@
|
|||||||
#define gst_tuple_length(t) (gst_tuple_raw(t)[0])
|
#define gst_tuple_length(t) (gst_tuple_raw(t)[0])
|
||||||
#define gst_tuple_hash(t) (gst_tuple_raw(t)[1])
|
#define gst_tuple_hash(t) (gst_tuple_raw(t)[1])
|
||||||
|
|
||||||
|
/* Struct utils */
|
||||||
|
#define gst_struct_raw(t) ((uint32_t *)(t) - 2)
|
||||||
|
#define gst_struct_length(t) (gst_struct_raw(t)[0])
|
||||||
|
#define gst_struct_capacity(t) (gst_struct_length(t) * 3)
|
||||||
|
#define gst_struct_hash(t) (gst_struct_raw(t)[1])
|
||||||
|
|
||||||
/* Memcpy for moving memory */
|
/* Memcpy for moving memory */
|
||||||
#ifndef gst_memcpy
|
#ifndef gst_memcpy
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -93,7 +99,6 @@ typedef enum GstType {
|
|||||||
GST_NUMBER,
|
GST_NUMBER,
|
||||||
GST_BOOLEAN,
|
GST_BOOLEAN,
|
||||||
GST_STRING,
|
GST_STRING,
|
||||||
GST_SYMBOL,
|
|
||||||
GST_ARRAY,
|
GST_ARRAY,
|
||||||
GST_TUPLE,
|
GST_TUPLE,
|
||||||
GST_THREAD,
|
GST_THREAD,
|
||||||
@ -153,6 +158,7 @@ union GstValueUnion {
|
|||||||
GstFunction *function;
|
GstFunction *function;
|
||||||
GstFuncEnv *env;
|
GstFuncEnv *env;
|
||||||
GstFuncDef *def;
|
GstFuncDef *def;
|
||||||
|
GstValue *st;
|
||||||
const uint8_t *string;
|
const uint8_t *string;
|
||||||
const char *cstring; /* Alias for ease of use from c */
|
const char *cstring; /* Alias for ease of use from c */
|
||||||
/* Indirectly used union members */
|
/* Indirectly used union members */
|
||||||
@ -354,7 +360,6 @@ const uint8_t *gst_string_end(Gst *vm, uint8_t *str);
|
|||||||
const uint8_t *gst_string_loadbuffer(Gst *vm, const uint8_t *buf, uint32_t len);
|
const uint8_t *gst_string_loadbuffer(Gst *vm, const uint8_t *buf, uint32_t len);
|
||||||
const uint8_t *gst_cstring_to_string(Gst *vm, const char *cstring);
|
const uint8_t *gst_cstring_to_string(Gst *vm, const char *cstring);
|
||||||
GstValue gst_load_cstring(Gst *vm, const char *string);
|
GstValue gst_load_cstring(Gst *vm, const char *string);
|
||||||
GstValue gst_load_csymbol(Gst *vm, const char *string);
|
|
||||||
int gst_string_compare(const uint8_t *lhs, const uint8_t *rhs);
|
int gst_string_compare(const uint8_t *lhs, const uint8_t *rhs);
|
||||||
|
|
||||||
/****/
|
/****/
|
||||||
|
Loading…
Reference in New Issue
Block a user