mirror of
https://github.com/janet-lang/janet
synced 2024-12-25 07:50:27 +00:00
Allow marshaling pegs.
This commit is contained in:
parent
4adfb9f2d3
commit
446ab037b0
@ -945,6 +945,7 @@ static uint32_t peg_compile1(Builder *b, Janet peg) {
|
||||
typedef struct {
|
||||
uint32_t *bytecode;
|
||||
Janet *constants;
|
||||
size_t bytecode_len;
|
||||
uint32_t num_constants;
|
||||
} Peg;
|
||||
|
||||
@ -956,16 +957,15 @@ static int peg_mark(void *p, size_t size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static JanetAbstractType peg_type = {
|
||||
"core/peg",
|
||||
NULL,
|
||||
peg_mark,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
static void peg_marshal(void *p, JanetMarshalContext *ctx) {
|
||||
Peg *peg = (Peg *)p;
|
||||
janet_marshal_size(ctx, peg->bytecode_len);
|
||||
janet_marshal_int(ctx, (int32_t)peg->num_constants);
|
||||
for (size_t i = 0; i < peg->bytecode_len; i++)
|
||||
janet_marshal_int(ctx, (int32_t) peg->bytecode[i]);
|
||||
for (uint32_t j = 0; j < peg->num_constants; j++)
|
||||
janet_marshal_janet(ctx, peg->constants[j]);
|
||||
}
|
||||
|
||||
/* Used to ensure that if we place several arrays in one memory chunk, each
|
||||
* array will be correctly aligned */
|
||||
@ -974,6 +974,43 @@ static size_t size_padded(size_t offset, size_t size) {
|
||||
return x - (x % size);
|
||||
}
|
||||
|
||||
static void peg_unmarshal(void *p, JanetMarshalContext *ctx) {
|
||||
char *mem = p;
|
||||
Peg *peg = (Peg *)p;
|
||||
peg->bytecode_len = janet_unmarshal_size(ctx);
|
||||
peg->num_constants = (uint32_t) janet_unmarshal_int(ctx);
|
||||
|
||||
/* Calculate offsets. Should match those in make_peg */
|
||||
size_t bytecode_start = size_padded(sizeof(Peg), sizeof(uint32_t));
|
||||
size_t bytecode_size = peg->bytecode_len * sizeof(uint32_t);
|
||||
size_t constants_start = size_padded(bytecode_start + bytecode_size, sizeof(Janet));
|
||||
uint32_t *bytecode = (uint32_t *)(mem + bytecode_start);
|
||||
Janet *constants = (Janet *)(mem + constants_start);
|
||||
peg->bytecode = bytecode;
|
||||
peg->constants = constants;
|
||||
|
||||
for (size_t i = 0; i < peg->bytecode_len; i++)
|
||||
bytecode[i] = (uint32_t) janet_unmarshal_int(ctx);
|
||||
for (uint32_t j = 0; j < peg->num_constants; j++)
|
||||
constants[j] = janet_unmarshal_janet(ctx);
|
||||
|
||||
/* TODO - verify peg bytecode. This is basically iterating
|
||||
* the bytecode and making sure instructions don't reference
|
||||
* memory outside the bytecode array. Otherwise, all programs
|
||||
* should be valid.*/
|
||||
}
|
||||
|
||||
static const JanetAbstractType peg_type = {
|
||||
"core/peg",
|
||||
NULL,
|
||||
peg_mark,
|
||||
NULL,
|
||||
NULL,
|
||||
peg_marshal,
|
||||
peg_unmarshal,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* Convert Builder to Peg (Janet Abstract Value) */
|
||||
static Peg *make_peg(Builder *b) {
|
||||
size_t bytecode_start = size_padded(sizeof(Peg), sizeof(uint32_t));
|
||||
@ -988,6 +1025,7 @@ static Peg *make_peg(Builder *b) {
|
||||
peg->num_constants = janet_v_count(b->constants);
|
||||
memcpy(peg->bytecode, b->bytecode, bytecode_size);
|
||||
memcpy(peg->constants, b->constants, constants_size);
|
||||
peg->bytecode_len = janet_v_count(b->bytecode);
|
||||
return peg;
|
||||
}
|
||||
|
||||
@ -1072,6 +1110,7 @@ static const JanetReg peg_cfuns[] = {
|
||||
/* Load the peg module */
|
||||
void janet_lib_peg(JanetTable *env) {
|
||||
janet_core_cfuns(env, NULL, peg_cfuns);
|
||||
janet_register_abstract_type(&peg_type);
|
||||
}
|
||||
|
||||
#endif /* ifdef JANET_PEG */
|
||||
|
@ -125,4 +125,10 @@
|
||||
(assert (not (string/check-set "abc" "")) "string/check-set 4")
|
||||
(assert (not (string/check-set "" "aabc")) "string/check-set 5")
|
||||
|
||||
# Marshal and unmarshal pegs
|
||||
(def p (-> "abcd" peg/compile marshal unmarshal))
|
||||
(assert (peg/match p "abcd") "peg marshal 1")
|
||||
(assert (peg/match p "abcdefg") "peg marshal 2")
|
||||
(assert (not (peg/match p "zabcdefg")) "peg marshal 3")
|
||||
|
||||
(end-suite)
|
||||
|
Loading…
Reference in New Issue
Block a user