Handle compilation of circular parsers

db4
Chris Double 2008-03-28 14:10:33 +13:00
parent f96a251f8a
commit f596aa2d71
2 changed files with 15 additions and 5 deletions

View File

@ -1,7 +1,7 @@
! Copyright (C) 2007 Chris Double. ! Copyright (C) 2007 Chris Double.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
! !
USING: kernel tools.test strings namespaces arrays sequences peg peg.private ; USING: kernel tools.test strings namespaces arrays sequences peg peg.private accessors words ;
IN: peg.tests IN: peg.tests
{ f } [ { f } [
@ -196,3 +196,9 @@ IN: peg.tests
"1+1" expr [ parse ] with-packrat parse-result-ast "1+1" expr [ parse ] with-packrat parse-result-ast
] unit-test ] unit-test
{ t } [
#! Ensure a circular parser doesn't loop infinitely
[ f , "a" token , ] seq*
dup parsers>>
dupd 0 swap set-nth compile word?
] unit-test

View File

@ -73,10 +73,14 @@ GENERIC: (compile) ( parser -- quot )
#! Look to see if the given parser has been compiled. #! Look to see if the given parser has been compiled.
#! If not, compile it to a temporary word, cache it, #! If not, compile it to a temporary word, cache it,
#! and return it. Otherwise return the existing one. #! and return it. Otherwise return the existing one.
compiled-parsers [ #! Circular parsers are supported by getting the word
dup parser-body define-temp #! name and storing it in the cache, before compiling,
tuck swap "peg" set-word-prop #! so it is picked up when re-entered.
] cache ; dup id>> compiled-parsers [
drop dup gensym swap 2dup id>> compiled-parsers set-at
2dup parser-body define
dupd "peg" set-word-prop
] cache nip ;
: compile ( parser -- word ) : compile ( parser -- word )
[ compiled-parser ] with-compilation-unit ; [ compiled-parser ] with-compilation-unit ;