mirror of
https://github.com/janet-lang/janet
synced 2024-11-28 11:09:54 +00:00
Try to address memoization problem in pegs.
This commit is contained in:
parent
d4b49cd622
commit
8bc8709d0e
@ -879,10 +879,14 @@ static const SpecialPair peg_specials[] = {
|
|||||||
static uint32_t peg_compile1(Builder *b, Janet peg) {
|
static uint32_t peg_compile1(Builder *b, Janet peg) {
|
||||||
|
|
||||||
/* Check for already compiled rules */
|
/* Check for already compiled rules */
|
||||||
Janet check = janet_table_get(b->memoized, peg);
|
int is_keyword = janet_checktype(peg, JANET_KEYWORD);
|
||||||
if (!janet_checktype(check, JANET_NIL)) {
|
Janet old_memo = janet_wrap_nil(); /* for compiler warnings */
|
||||||
uint32_t rule = (uint32_t) janet_unwrap_number(check);
|
if (is_keyword) {
|
||||||
return rule;
|
old_memo = janet_table_get(b->memoized, peg);
|
||||||
|
if (!janet_checktype(old_memo, JANET_NIL)) {
|
||||||
|
uint32_t rule = (uint32_t) janet_unwrap_number(old_memo);
|
||||||
|
return rule;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Keep track of the form being compiled for error purposes */
|
/* Keep track of the form being compiled for error purposes */
|
||||||
@ -896,10 +900,10 @@ static uint32_t peg_compile1(Builder *b, Janet peg) {
|
|||||||
|
|
||||||
/* The final rule to return */
|
/* The final rule to return */
|
||||||
uint32_t rule = janet_v_count(b->bytecode);
|
uint32_t rule = janet_v_count(b->bytecode);
|
||||||
if (!janet_checktype(peg, JANET_KEYWORD) &&
|
|
||||||
!janet_checktype(peg, JANET_STRUCT)) {
|
/* Cache keywords for recursion points (loops) */
|
||||||
|
if (is_keyword)
|
||||||
janet_table_put(b->memoized, peg, janet_wrap_number(rule));
|
janet_table_put(b->memoized, peg, janet_wrap_number(rule));
|
||||||
}
|
|
||||||
|
|
||||||
switch (janet_type(peg)) {
|
switch (janet_type(peg)) {
|
||||||
default:
|
default:
|
||||||
@ -960,6 +964,10 @@ static uint32_t peg_compile1(Builder *b, Janet peg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reset old cached rule */
|
||||||
|
if (is_keyword)
|
||||||
|
janet_table_put(b->memoized, peg, old_memo);
|
||||||
|
|
||||||
/* Increase depth again */
|
/* Increase depth again */
|
||||||
b->depth++;
|
b->depth++;
|
||||||
b->form = old_form;
|
b->form = old_form;
|
||||||
|
@ -421,4 +421,14 @@
|
|||||||
(assert (= (tuple/type (-> '(1 2 3) marshal unmarshal)) :parens) "normal tuple marshalled/unmarshalled")
|
(assert (= (tuple/type (-> '(1 2 3) marshal unmarshal)) :parens) "normal tuple marshalled/unmarshalled")
|
||||||
(assert (= (tuple/type (-> '[1 2 3] marshal unmarshal)) :brackets) "normal tuple marshalled/unmarshalled")
|
(assert (= (tuple/type (-> '[1 2 3] marshal unmarshal)) :brackets) "normal tuple marshalled/unmarshalled")
|
||||||
|
|
||||||
|
# Check for bad memoization (+ :a) should mean different things in different contexts.
|
||||||
|
(def redef-a
|
||||||
|
~{:a "abc"
|
||||||
|
:c (+ :a)
|
||||||
|
:main (* :c {:a "def" :main (+ :a)} -1)})
|
||||||
|
|
||||||
|
(check-match redef-a "abcdef" true)
|
||||||
|
(check-match redef-a "abcabc" false)
|
||||||
|
(check-match redef-a "defdef" false)
|
||||||
|
|
||||||
(end-suite)
|
(end-suite)
|
||||||
|
Loading…
Reference in New Issue
Block a user