mirror of
https://github.com/janet-lang/janet
synced 2024-11-28 11:09:54 +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 {
|
typedef struct {
|
||||||
uint32_t *bytecode;
|
uint32_t *bytecode;
|
||||||
Janet *constants;
|
Janet *constants;
|
||||||
|
size_t bytecode_len;
|
||||||
uint32_t num_constants;
|
uint32_t num_constants;
|
||||||
} Peg;
|
} Peg;
|
||||||
|
|
||||||
@ -956,16 +957,15 @@ static int peg_mark(void *p, size_t size) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JanetAbstractType peg_type = {
|
static void peg_marshal(void *p, JanetMarshalContext *ctx) {
|
||||||
"core/peg",
|
Peg *peg = (Peg *)p;
|
||||||
NULL,
|
janet_marshal_size(ctx, peg->bytecode_len);
|
||||||
peg_mark,
|
janet_marshal_int(ctx, (int32_t)peg->num_constants);
|
||||||
NULL,
|
for (size_t i = 0; i < peg->bytecode_len; i++)
|
||||||
NULL,
|
janet_marshal_int(ctx, (int32_t) peg->bytecode[i]);
|
||||||
NULL,
|
for (uint32_t j = 0; j < peg->num_constants; j++)
|
||||||
NULL,
|
janet_marshal_janet(ctx, peg->constants[j]);
|
||||||
NULL
|
}
|
||||||
};
|
|
||||||
|
|
||||||
/* Used to ensure that if we place several arrays in one memory chunk, each
|
/* Used to ensure that if we place several arrays in one memory chunk, each
|
||||||
* array will be correctly aligned */
|
* array will be correctly aligned */
|
||||||
@ -974,6 +974,43 @@ static size_t size_padded(size_t offset, size_t size) {
|
|||||||
return x - (x % 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) */
|
/* Convert Builder to Peg (Janet Abstract Value) */
|
||||||
static Peg *make_peg(Builder *b) {
|
static Peg *make_peg(Builder *b) {
|
||||||
size_t bytecode_start = size_padded(sizeof(Peg), sizeof(uint32_t));
|
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);
|
peg->num_constants = janet_v_count(b->constants);
|
||||||
memcpy(peg->bytecode, b->bytecode, bytecode_size);
|
memcpy(peg->bytecode, b->bytecode, bytecode_size);
|
||||||
memcpy(peg->constants, b->constants, constants_size);
|
memcpy(peg->constants, b->constants, constants_size);
|
||||||
|
peg->bytecode_len = janet_v_count(b->bytecode);
|
||||||
return peg;
|
return peg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1072,6 +1110,7 @@ static const JanetReg peg_cfuns[] = {
|
|||||||
/* Load the peg module */
|
/* Load the peg module */
|
||||||
void janet_lib_peg(JanetTable *env) {
|
void janet_lib_peg(JanetTable *env) {
|
||||||
janet_core_cfuns(env, NULL, peg_cfuns);
|
janet_core_cfuns(env, NULL, peg_cfuns);
|
||||||
|
janet_register_abstract_type(&peg_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* ifdef JANET_PEG */
|
#endif /* ifdef JANET_PEG */
|
||||||
|
@ -125,4 +125,10 @@
|
|||||||
(assert (not (string/check-set "abc" "")) "string/check-set 4")
|
(assert (not (string/check-set "abc" "")) "string/check-set 4")
|
||||||
(assert (not (string/check-set "" "aabc")) "string/check-set 5")
|
(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)
|
(end-suite)
|
||||||
|
Loading…
Reference in New Issue
Block a user