Index: modules/pt/pkgIndex.tcl ================================================================== --- modules/pt/pkgIndex.tcl +++ modules/pt/pkgIndex.tcl @@ -46,16 +46,17 @@ package ifneeded pt::peg::from::json 1 [list source [file join $dir pt_peg_from_json.tcl]] package ifneeded pt::peg::from::peg 1 [list source [file join $dir pt_peg_from_peg.tcl]] # PARAM runtime. package ifneeded pt::rde 1.0.2 [list source [file join $dir pt_rdengine.tcl]] +package ifneeded pt::rde::oo 1.0.2 [list source [file join $dir pt_rdengine_oo.tcl]] # PEG grammar specification, as CONTAINER package ifneeded pt::peg::container::peg 1 [list source [file join $dir pt_peg_container_peg.tcl]] # */PARAM support (canned configurations). package ifneeded pt::cparam::configuration::critcl 1.0.1 [list source [file join $dir pt_cparam_config_critcl.tcl]] package ifneeded pt::tclparam::configuration::snit 1.0.1 [list source [file join $dir pt_tclparam_config_snit.tcl]] -package ifneeded pt::tclparam::configuration::tcloo 1.0.2 [list source [file join $dir pt_tclparam_config_tcloo.tcl]] +package ifneeded pt::tclparam::configuration::tcloo 1.0.3 [list source [file join $dir pt_tclparam_config_tcloo.tcl]] # Parser generator core. package ifneeded pt::pgen 1.0.1 [list source [file join $dir pt_pgen.tcl]] Index: modules/pt/pt_rdengine_oo.tcl ================================================================== --- modules/pt/pt_rdengine_oo.tcl +++ modules/pt/pt_rdengine_oo.tcl @@ -29,39 +29,42 @@ # # ## ### ##### ######## ############# ##################### ## API - Lifecycle constructor {} { - set selfns [info object namespace] + set selfns [self namespace] set mystackloc [struct::stack ${selfns}::LOC] ; # LS set mystackerr [struct::stack ${selfns}::ERR] ; # ES set mystackast [struct::stack ${selfns}::AST] ; # ARS/AS set mystackmark [struct::stack ${selfns}::MARK] ; # s.a. - my reset + my reset {} return } method reset {chan} { set mychan $chan ; # IN - set myline 1 ; # - set mycolumn 0 ; # set mycurrent {} ; # CC set myloc -1 ; # CL set myok 0 ; # ST set msvalue {} ; # SV set myerror {} ; # ER - set mytoken {} ; # TC + set mytoken {} ; # TC (string) array unset mysymbol * ; # NC $mystackloc clear $mystackerr clear $mystackast clear $mystackmark clear return } + + method data {string} { + append mytoken $string + return + } method complete {} { if {$myok} { set n [$mystackast size] if {$n > 1} { @@ -80,12 +83,10 @@ # # ## ### ##### ######## ############# ##################### ## API - State accessors method chan {} { return $mychan } - method line {} { return $myline } - method column {} { return $mycolumn } # - - -- --- ----- -------- method current {} { return $mycurrent } method location {} { return $myloc } @@ -101,12 +102,12 @@ # - - -- --- ----- -------- method tokens {{from {}} {to {}}} { switch -exact [llength [info level 0]] { 4 { return $mytoken } - 5 { return [lrange $mytoken $from $from] } - 6 { return [lrange $mytoken $from $to] } + 5 { return [string range $mytoken $from $from] } + 6 { return [string range $mytoken $from $to] } } } method symbols {} { return [array get mysymbol] @@ -120,14 +121,1151 @@ method asts {} { return [lreverse [$mystackast get]] } method amarked {} { return [lreverse [$mystackmark get]] } method ast {} { return [$mystackast peek] } - # - - -- --- ----- -------- - - method position {loc} { - return [lrange [lindex $mytoken $loc] 1 2] + # # ## ### ##### ######## ############# ##################### + ## Common instruction sequences + + method si:void_state_push {} { ;#X + # i_loc_push + # i_error_clear_push + $mystackloc push $myloc + set myerror {} + $mystackerr push {} + return + } + + method si:void2_state_push {} { ;#X + # i_loc_push + # i_error_push + $mystackloc push $myloc + $mystackerr push {} + return + } + + method si:value_state_push {} { ;#X + # i_ast_push + # i_loc_push + # i_error_clear_push + $mystackmark push [$mystackast size] + $mystackloc push $myloc + set myerror {} + $mystackerr push {} + return + } + + # - -- --- ----- -------- ------------- --------------------- + + method si:void_state_merge {} { + # i_error_pop_merge + # i_loc_pop_rewind/discard + + set olderror [$mystackerr pop] + # We have either old or new error data, keep it. + if {![llength $myerror]} { + set myerror $olderror + } elseif {[llength $olderror]} { + # If one of the errors is further on in the input choose + # that as the information to propagate. + + lassign $myerror loe msgse + lassign $olderror lon msgsn + + if {$lon > $loe} { + set myerror $olderror + } elseif {$loe == $lon} { + # Equal locations, merge the message lists, set-like. + set myerror [list $loe [lsort -uniq [list {*}$msgse {*}$msgsn]]] + } + } + + set last [$mystackloc pop] + if {$myok} return + set myloc $last + return + } + + method si:void_state_merge_ok {} { + # i_error_pop_merge + # i_loc_pop_rewind/discard + # i_status_ok + + set olderror [$mystackerr pop] + # We have either old or new error data, keep it. + if {![llength $myerror]} { + set myerror $olderror + } elseif {[llength $olderror]} { + # If one of the errors is further on in the input choose + # that as the information to propagate. + + lassign $myerror loe msgse + lassign $olderror lon msgsn + + if {$lon > $loe} { + set myerror $olderror + } elseif {$loe == $lon} { + # Equal locations, merge the message lists, set-like. + set myerror [list $loe [lsort -uniq [list {*}$msgse {*}$msgsn]]] + } + } + + set last [$mystackloc pop] + if {$myok} return + set myloc $last + set myok 1 + return + } + + method si:value_state_merge {} { + # i_error_pop_merge + # i_ast_pop_rewind/discard + # i_loc_pop_rewind/discard + + set olderror [$mystackerr pop] + # We have either old or new error data, keep it. + if {![llength $myerror]} { + set myerror $olderror + } elseif {[llength $olderror]} { + # If one of the errors is further on in the input choose + # that as the information to propagate. + + lassign $myerror loe msgse + lassign $olderror lon msgsn + + if {$lon > $loe} { + set myerror $olderror + } elseif {$loe == $lon} { + # Equal locations, merge the message lists, set-like. + set myerror [list $loe [lsort -uniq [list {*}$msgse {*}$msgsn]]] + } + } + + set mark [$mystackmark pop] + set last [$mystackloc pop] + if {$myok} return + $mystackast trim* $mark + set myloc $last + return + } + + # - -- --- ----- -------- ------------- --------------------- + + method si:value_notahead_start {} { + # i_loc_push + # i_ast_push + + $mystackloc push $myloc + $mystackmark push [$mystackast size] + return + } + + method si:void_notahead_exit {} { + # i_loc_pop_rewind + # i_status_negate + + set myloc [$mystackloc pop] + set myok [expr {!$myok}] + return + } + + method si:value_notahead_exit {} { + # i_ast_pop_discard/rewind + # i_loc_pop_rewind + # i_status_negate + + set mark [$mystackmark pop] + if {$myok} { + $mystackast trim* $mark + } + set myloc [$mystackloc pop] + set myok [expr {!$myok}] + return + } + + # - -- --- ----- -------- ------------- --------------------- + + method si:kleene_abort {} { + # i_loc_pop_rewind/discard + # i:fail_return + + set last [$mystackloc pop] + if {$myok} return + set myloc $last + return -code return + } + + method si:kleene_close {} { + # i_error_pop_merge + # i_loc_pop_rewind/discard + # i:fail_status_ok + # i:fail_return + + set olderror [$mystackerr pop] + # We have either old or new error data, keep it. + if {![llength $myerror]} { + set myerror $olderror + } elseif {[llength $olderror]} { + # If one of the errors is further on in the input choose + # that as the information to propagate. + + lassign $myerror loe msgse + lassign $olderror lon msgsn + + if {$lon > $loe} { + set myerror $olderror + } elseif {$loe == $lon} { + # Equal locations, merge the message lists, set-like. + set myerror [list $loe [lsort -uniq [list {*}$msgse {*}$msgsn]]] + } + } + + set last [$mystackloc pop] + if {$myok} return + set myok 1 + set myloc $last + return -code return + } + + # - -- --- ----- -------- ------------- --------------------- + + method si:voidvoid_branch {} { + # i_error_pop_merge + # i:ok_loc_pop_discard + # i:ok_return + # i_loc_rewind + # i_error_push + + set olderror [$mystackerr pop] + # We have either old or new error data, keep it. + if {![llength $myerror]} { + set myerror $olderror + } elseif {[llength $olderror]} { + # If one of the errors is further on in the input choose + # that as the information to propagate. + + lassign $myerror loe msgse + lassign $olderror lon msgsn + + if {$lon > $loe} { + set myerror $olderror + } elseif {$loe == $lon} { + # Equal locations, merge the message lists, set-like. + set myerror [list $loe [lsort -uniq [list {*}$msgse {*}$msgsn]]] + } + } + + if {$myok} { + $mystackloc pop + return -code return + } + set myloc [$mystackloc peek] + $mystackerr push {} + return + } + + method si:voidvalue_branch {} { + # i_error_pop_merge + # i:ok_loc_pop_discard + # i:ok_return + # i_ast_push + # i_loc_rewind + # i_error_push + + set olderror [$mystackerr pop] + # We have either old or new error data, keep it. + if {![llength $myerror]} { + set myerror $olderror + } elseif {[llength $olderror]} { + # If one of the errors is further on in the input choose + # that as the information to propagate. + + lassign $myerror loe msgse + lassign $olderror lon msgsn + + if {$lon > $loe} { + set myerror $olderror + } elseif {$loe == $lon} { + # Equal locations, merge the message lists, set-like. + set myerror [list $loe [lsort -uniq [list {*}$msgse {*}$msgsn]]] + } + } + + if {$myok} { + $mystackloc pop + return -code return + } + $mystackmark push [$mystackast size] + set myloc [$mystackloc peek] + $mystackerr push {} + return + } + + method si:valuevoid_branch {} { + # i_error_pop_merge + # i_ast_pop_rewind/discard + # i:ok_loc_pop_discard + # i:ok_return + # i_loc_rewind + # i_error_push + + set olderror [$mystackerr pop] + # We have either old or new error data, keep it. + if {![llength $myerror]} { + set myerror $olderror + } elseif {[llength $olderror]} { + # If one of the errors is further on in the input choose + # that as the information to propagate. + + lassign $myerror loe msgse + lassign $olderror lon msgsn + + if {$lon > $loe} { + set myerror $olderror + } elseif {$loe == $lon} { + # Equal locations, merge the message lists, set-like. + set myerror [list $loe [lsort -uniq [list {*}$msgse {*}$msgsn]]] + } + } + set mark [$mystackmark pop] + if {$myok} { + $mystackloc pop + return -code return + } + $mystackast trim* $mark + set myloc [$mystackloc peek] + $mystackerr push {} + return + } + + method si:valuevalue_branch {} { + # i_error_pop_merge + # i_ast_pop_discard + # i:ok_loc_pop_discard + # i:ok_return + # i_ast_rewind + # i_loc_rewind + # i_error_push + + set olderror [$mystackerr pop] + # We have either old or new error data, keep it. + if {![llength $myerror]} { + set myerror $olderror + } elseif {[llength $olderror]} { + # If one of the errors is further on in the input choose + # that as the information to propagate. + + lassign $myerror loe msgse + lassign $olderror lon msgsn + + if {$lon > $loe} { + set myerror $olderror + } elseif {$loe == $lon} { + # Equal locations, merge the message lists, set-like. + set myerror [list $loe [lsort -uniq [list {*}$msgse {*}$msgsn]]] + } + } + if {$myok} { + $mystackmark pop + $mystackloc pop + return -code return + } + $mystackast trim* [$mystackmark peek] + set myloc [$mystackloc peek] + $mystackerr push {} + return + } + + # - -- --- ----- -------- ------------- --------------------- + + method si:voidvoid_part {} { + # i_error_pop_merge + # i:fail_loc_pop_rewind + # i:fail_return + # i_error_push + + set olderror [$mystackerr pop] + # We have either old or new error data, keep it. + if {![llength $myerror]} { + set myerror $olderror + } elseif {[llength $olderror]} { + # If one of the errors is further on in the input choose + # that as the information to propagate. + + lassign $myerror loe msgse + lassign $olderror lon msgsn + + if {$lon > $loe} { + set myerror $olderror + } elseif {$loe == $lon} { + # Equal locations, merge the message lists, set-like. + set myerror [list $loe [lsort -uniq [list {*}$msgse {*}$msgsn]]] + } + } + if {!$myok} { + set myloc [$mystackloc pop] + return -code return + } + $mystackerr push $myerror + return + } + + method si:voidvalue_part {} { + # i_error_pop_merge + # i:fail_loc_pop_rewind + # i:fail_return + # i_ast_push + # i_error_push + + set olderror [$mystackerr pop] + # We have either old or new error data, keep it. + if {![llength $myerror]} { + set myerror $olderror + } elseif {[llength $olderror]} { + # If one of the errors is further on in the input choose + # that as the information to propagate. + + lassign $myerror loe msgse + lassign $olderror lon msgsn + + if {$lon > $loe} { + set myerror $olderror + } elseif {$loe == $lon} { + # Equal locations, merge the message lists, set-like. + set myerror [list $loe [lsort -uniq [list {*}$msgse {*}$msgsn]]] + } + } + if {!$myok} { + set myloc [$mystackloc pop] + return -code return + } + $mystackmark push [$mystackast size] + $mystackerr push $myerror + return + } + + method si:valuevalue_part {} { + # i_error_pop_merge + # i:fail_ast_pop_rewind + # i:fail_loc_pop_rewind + # i:fail_return + # i_error_push + + set olderror [$mystackerr pop] + # We have either old or new error data, keep it. + if {![llength $myerror]} { + set myerror $olderror + } elseif {[llength $olderror]} { + # If one of the errors is further on in the input choose + # that as the information to propagate. + + lassign $myerror loe msgse + lassign $olderror lon msgsn + + if {$lon > $loe} { + set myerror $olderror + } elseif {$loe == $lon} { + # Equal locations, merge the message lists, set-like. + set myerror [list $loe [lsort -uniq [list {*}$msgse {*}$msgsn]]] + } + } + if {!$myok} { + $mystackast trim* [$mystackmark pop] + set myloc [$mystackloc pop] + return -code return + } + $mystackerr push $myerror + return + } + + # - -- --- ----- -------- ------------- --------------------- + + method si:next_str {tok} { + # String = sequence of characters. No need for all the intermediate + # stack churn. + + set n [string length $tok] + set last [expr {$myloc + $n}] + set max [string length $mytoken] + + incr myloc + if {($last >= $max) && ![my ExtendTCN [expr {$last - $max + 1}]]} { + set myok 0 + set myerror [list $myloc [list [list t $tok]]] + # i:fail_return + return + } + set lex [string range $mytoken $myloc $last] + set mycurrent [string index $mytoken $last] + + set myok [expr {$tok eq $lex}] + + if {$myok} { + set myloc $last + set myerror {} + } else { + set myerror [list $myloc [list [list t $tok]]] + incr myloc -1 + } + return + } + + method si:next_class {tok} { + # Class = Choice of characters. No need for stack churn. + + # i_input_next "\{t $c\}" + # i:fail_return + # i_test_ + + incr myloc + if {($myloc >= [string length $mytoken]) && ![my ExtendTC]} { + set myok 0 + set myerror [list $myloc [list [list t $tok]]] + # i:fail_return + return + } + set mycurrent [string index $mytoken $myloc] + + # Note what is needle versus hay. The token, i.e. the string + # of allowed characters is the hay in which the current + # character is looked, making it the needle. + set myok [expr {[string first $mycurrent $tok] >= 0}] + + if {$myok} { + set myerror {} + } else { + set myerror [list $myloc [list [list t $tok]]] + incr myloc -1 + } + return + } + + method si:next_char {tok} { + # i_input_next "\{t $c\}" + # i:fail_return + # i_test_char $c + + incr myloc + if {($myloc >= [string length $mytoken]) && ![my ExtendTC]} { + set myok 0 + set myerror [list $myloc [list [list t $tok]]] + # i:fail_return + return + } + set mycurrent [string index $mytoken $myloc] + + set myok [expr {$tok eq $mycurrent}] + if {$myok} { + set myerror {} + } else { + set myerror [list $myloc [list [list t $tok]]] + incr myloc -1 + } + return + } + + method si:next_range {toks toke} { + #Asm::Ins i_input_next "\{.. $s $e\}" + #Asm::Ins i:fail_return + #Asm::Ins i_test_range $s $e + + incr myloc + if {($myloc >= [string length $mytoken]) && ![my ExtendTC]} { + set myok 0 + set myerror [list $myloc [list [list .. $toks $toke]]] + # i:fail_return + return + } + set mycurrent [string index $mytoken $myloc] + + set myok [expr { + ([string compare $toks $mycurrent] <= 0) && + ([string compare $mycurrent $toke] <= 0) + }] ; # {} + if {$myok} { + set myerror {} + } else { + set myerror [list $myloc [list [pt::pe range $toks $toke]]] + incr myloc -1 + } + return + } + + # - -- --- ----- -------- ------------- --------------------- + + method si:next_alnum {} { ; #TRACE puts "[format %8d [incr count]] RDE si:next_alnum" + #Asm::Ins i_input_next alnum + #Asm::Ins i:fail_return + #Asm::Ins i_test_alnum + + incr myloc + if {($myloc >= [string length $mytoken]) && ![my ExtendTC]} { + set myok 0 + set myerror [list $myloc [list alnum]] + # i:fail_return + return + } + set mycurrent [string index $mytoken $myloc] + + set myok [string is alnum -strict $mycurrent] + if {!$myok} { + set myerror [list $myloc [list alnum]] + incr myloc -1 + } else { + set myerror {} + } + return + } + + method si:next_alpha {} { ; #TRACE puts "[format %8d [incr count]] RDE si:next_alpha" + #Asm::Ins i_input_next alpha + #Asm::Ins i:fail_return + #Asm::Ins i_test_alpha + + incr myloc + if {($myloc >= [string length $mytoken]) && ![my ExtendTC]} { + set myok 0 + set myerror [list $myloc [list alpha]] + # i:fail_return + return + } + set mycurrent [string index $mytoken $myloc] + + set myok [string is alpha -strict $mycurrent] + if {!$myok} { + set myerror [list $myloc [list alpha]] + incr myloc -1 + } else { + set myerror {} + } + return + } + + method si:next_ascii {} { ; #TRACE puts "[format %8d [incr count]] RDE si:next_ascii" + #Asm::Ins i_input_next ascii + #Asm::Ins i:fail_return + #Asm::Ins i_test_ascii + + incr myloc + if {($myloc >= [string length $mytoken]) && ![my ExtendTC]} { + set myok 0 + set myerror [list $myloc [list ascii]] + # i:fail_return + return + } + set mycurrent [string index $mytoken $myloc] + + set myok [string is ascii -strict $mycurrent] + if {!$myok} { + set myerror [list $myloc [list ascii]] + incr myloc -1 + } else { + set myerror {} + } + return + } + + method si:next_ddigit {} { ; #TRACE puts "[format %8d [incr count]] RDE si:next_ddigit" + #Asm::Ins i_input_next ddigit + #Asm::Ins i:fail_return + #Asm::Ins i_test_ddigit + + incr myloc + if {($myloc >= [string length $mytoken]) && ![my ExtendTC]} { + set myok 0 + set myerror [list $myloc [list ddigit]] + # i:fail_return + return + } + set mycurrent [string index $mytoken $myloc] + + set myok [string match {[0-9]} $mycurrent] + if {!$myok} { + set myerror [list $myloc [list ddigit]] + incr myloc -1 + } else { + set myerror {} + } + return + } + + method si:next_digit {} { ; #TRACE puts "[format %8d [incr count]] RDE si:next_digit" + #Asm::Ins i_input_next digit + #Asm::Ins i:fail_return + #Asm::Ins i_test_digit + + incr myloc + if {($myloc >= [string length $mytoken]) && ![my ExtendTC]} { + set myok 0 + set myerror [list $myloc [list digit]] + # i:fail_return + return + } + set mycurrent [string index $mytoken $myloc] + + set myok [string is digit -strict $mycurrent] + if {!$myok} { + set myerror [list $myloc [list digit]] + incr myloc -1 + } else { + set myerror {} + } + return + } + + method si:next_graph {} { ; #TRACE puts "[format %8d [incr count]] RDE si:next_graph" + #Asm::Ins i_input_next graph + #Asm::Ins i:fail_return + #Asm::Ins i_test_graph + + incr myloc + if {($myloc >= [string length $mytoken]) && ![my ExtendTC]} { + set myok 0 + set myerror [list $myloc [list graph]] + # i:fail_return + return + } + set mycurrent [string index $mytoken $myloc] + + set myok [string is graph -strict $mycurrent] + if {!$myok} { + set myerror [list $myloc [list graph]] + incr myloc -1 + } else { + set myerror {} + } + return + } + + method si:next_lower {} { ; #TRACE puts "[format %8d [incr count]] RDE si:next_lower" + #Asm::Ins i_input_next lower + #Asm::Ins i:fail_return + #Asm::Ins i_test_lower + + incr myloc + if {($myloc >= [string length $mytoken]) && ![my ExtendTC]} { + set myok 0 + set myerror [list $myloc [list lower]] + # i:fail_return + return + } + set mycurrent [string index $mytoken $myloc] + + set myok [string is lower -strict $mycurrent] + if {!$myok} { + set myerror [list $myloc [list lower]] + incr myloc -1 + } else { + set myerror {} + } + return + } + + method si:next_print {} { ; #TRACE puts "[format %8d [incr count]] RDE si:next_print" + #Asm::Ins i_input_next print + #Asm::Ins i:fail_return + #Asm::Ins i_test_print + + incr myloc + if {($myloc >= [string length $mytoken]) && ![my ExtendTC]} { + set myok 0 + set myerror [list $myloc [list print]] + # i:fail_return + return + } + set mycurrent [string index $mytoken $myloc] + + set myok [string is print -strict $mycurrent] + if {!$myok} { + set myerror [list $myloc [list print]] + incr myloc -1 + } else { + set myerror {} + } + return + } + + method si:next_punct {} { ; #TRACE puts "[format %8d [incr count]] RDE si:next_punct" + #Asm::Ins i_input_next punct + #Asm::Ins i:fail_return + #Asm::Ins i_test_punct + + incr myloc + if {($myloc >= [string length $mytoken]) && ![my ExtendTC]} { + set myok 0 + set myerror [list $myloc [list punct]] + # i:fail_return + return + } + set mycurrent [string index $mytoken $myloc] + + set myok [string is punct -strict $mycurrent] + if {!$myok} { + set myerror [list $myloc [list punct]] + incr myloc -1 + } else { + set myerror {} + } + return + } + + method si:next_space {} { ; #TRACE puts "[format %8d [incr count]] RDE si:next_space" + #Asm::Ins i_input_next space + #Asm::Ins i:fail_return + #Asm::Ins i_test_space + + incr myloc + if {($myloc >= [string length $mytoken]) && ![my ExtendTC]} { + set myok 0 + set myerror [list $myloc [list space]] + # i:fail_return + return + } + set mycurrent [string index $mytoken $myloc] + + set myok [string is space -strict $mycurrent] + if {!$myok} { + set myerror [list $myloc [list space]] + incr myloc -1 + } else { + set myerror {} + } + return + } + + method si:next_upper {} { ; #TRACE puts "[format %8d [incr count]] RDE si:next_upper" + #Asm::Ins i_input_next upper + #Asm::Ins i:fail_return + #Asm::Ins i_test_upper + + incr myloc + if {($myloc >= [string length $mytoken]) && ![my ExtendTC]} { + set myok 0 + set myerror [list $myloc [list upper]] + # i:fail_return + return + } + set mycurrent [string index $mytoken $myloc] + + set myok [string is upper -strict $mycurrent] + if {!$myok} { + set myerror [list $myloc [list upper]] + incr myloc -1 + } else { + set myerror {} + } + return + } + + method si:next_wordchar {} { ; #TRACE puts "[format %8d [incr count]] RDE si:next_wordchar" + #Asm::Ins i_input_next wordchar + #Asm::Ins i:fail_return + #Asm::Ins i_test_wordchar + + incr myloc + if {($myloc >= [string length $mytoken]) && ![my ExtendTC]} { + set myok 0 + set myerror [list $myloc [list wordchar]] + # i:fail_return + return + } + set mycurrent [string index $mytoken $myloc] + + set myok [string is wordchar -strict $mycurrent] + if {!$myok} { + set myerror [list $myloc [list wordchar]] + incr myloc -1 + } else { + set myerror {} + } + return + } + + method si:next_xdigit {} { ; #TRACE puts "[format %8d [incr count]] RDE si:next_xdigit" + #Asm::Ins i_input_next xdigit + #Asm::Ins i:fail_return + #Asm::Ins i_test_xdigit + + incr myloc + if {($myloc >= [string length $mytoken]) && ![my ExtendTC]} { + set myok 0 + set myerror [list $myloc [list xdigit]] + # i:fail_return + return + } + set mycurrent [string index $mytoken $myloc] + + set myok [string is xdigit -strict $mycurrent] + if {!$myok} { + set myerror [list $myloc [list xdigit]] + incr myloc -1 + } else { + set myerror {} + } + return + } + + # - -- --- ----- -------- ------------- --------------------- + + method si:value_symbol_start {symbol} { + # if @runtime@ i_symbol_restore $symbol + # i:found:ok_ast_value_push + # i:found_return + # i_loc_push + # i_ast_push + + set k [list $myloc $symbol] + if {[info exists mysymbol($k)]} { + lassign $mysymbol($k) myloc myok myerror mysvalue + if {$myok} { + $mystackast push $mysvalue + } + return -code return + } + $mystackloc push $myloc + $mystackmark push [$mystackast size] + return + } + + method si:value_void_symbol_start {symbol} { + # if @runtime@ i_symbol_restore $symbol + # i:found_return + # i_loc_push + # i_ast_push + + set k [list $myloc $symbol] + if {[info exists mysymbol($k)]} { + lassign $mysymbol($k) myloc myok myerror mysvalue + return -code return + } + $mystackloc push $myloc + $mystackmark push [$mystackast size] + return + } + + method si:void_symbol_start {symbol} { + # if @runtime@ i_symbol_restore $symbol + # i:found:ok_ast_value_push + # i:found_return + # i_loc_push + + set k [list $myloc $symbol] + if {[info exists mysymbol($k)]} { + lassign $mysymbol($k) myloc myok myerror mysvalue + if {$myok} { + $mystackast push $mysvalue + } + return -code return + } + $mystackloc push $myloc + return + } + + method si:void_void_symbol_start {symbol} { + # if @runtime@ i_symbol_restore $symbol + # i:found_return + # i_loc_push + + set k [list $myloc $symbol] + if {[info exists mysymbol($k)]} { + lassign $mysymbol($k) myloc myok myerror mysvalue + return -code return + } + $mystackloc push $myloc + return + } + + method si:reduce_symbol_end {symbol} { + # i_value_clear/reduce $symbol + # i_symbol_save $symbol + # i_error_nonterminal $symbol + # i_ast_pop_rewind + # i_loc_pop_discard + # i:ok_ast_value_push + + set mysvalue {} + set at [$mystackloc pop] + + if {$myok} { + set mark [$mystackmark peek];# Old size of stack before current nt pushed more. + set newa [expr {[$mystackast size] - $mark}] + set pos $at + incr pos + + if {!$newa} { + set mysvalue {} + } elseif {$newa == 1} { + # peek 1 => single element comes back + set mysvalue [list [$mystackast peek]] ; # SaveToMark + } else { + # peek n > 1 => list of elements comes back + set mysvalue [$mystackast peekr $newa] ; # SaveToMark + } + + if {$at == $myloc} { + # The symbol did not process any input. As this is + # signaled to be ok (*) we create a node covering an + # empty range. (Ad *): Can happen for a RHS using + # toplevel operators * or ?. + set mysvalue [pt::ast new0 $symbol $pos {*}$mysvalue] + } else { + set mysvalue [pt::ast new $symbol $pos $myloc {*}$mysvalue] ; # Reduce $symbol + } + } + + set k [list $at $symbol] + set mysymbol($k) [list $myloc $myok $myerror $mysvalue] + + if {[llength $myerror]} { + set pos $at + incr pos + lassign $myerror loc messages + if {$loc == $pos} { + set myerror [list $loc [list [list n $symbol]]] + } + } + + $mystackast trim* [$mystackmark pop] + if {$myok} { + $mystackast push $mysvalue + } + return + } + + method si:void_leaf_symbol_end {symbol} { + # i_value_clear/leaf $symbol + # i_symbol_save $symbol + # i_error_nonterminal $symbol + # i_loc_pop_discard + # i:ok_ast_value_push + + set mysvalue {} + set at [$mystackloc pop] + + if {$myok} { + set pos $at + incr pos + if {$at == $myloc} { + # The symbol did not process any input. As this is + # signaled to be ok (*) we create a node covering an + # empty range. (Ad *): Can happen for a RHS using + # toplevel operators * or ?. + set mysvalue [pt::ast new0 $symbol $pos] + } else { + set mysvalue [pt::ast new $symbol $pos $myloc] + } + } + + set k [list $at $symbol] + set mysymbol($k) [list $myloc $myok $myerror $mysvalue] + + if {[llength $myerror]} { + set pos $at + incr pos + lassign $myerror loc messages + if {$loc == $pos} { + set myerror [list $loc [list [list n $symbol]]] + } + } + + if {$myok} { + $mystackast push $mysvalue + } + return + } + + method si:value_leaf_symbol_end {symbol} { + # i_value_clear/leaf $symbol + # i_symbol_save $symbol + # i_error_nonterminal $symbol + # i_loc_pop_discard + # i_ast_pop_rewind + # i:ok_ast_value_push + + set mysvalue {} + set at [$mystackloc pop] + + if {$myok} { + set pos $at + incr pos + if {$at == $myloc} { + # The symbol did not process any input. As this is + # signaled to be ok (*) we create a node covering an + # empty range. (Ad *): Can happen for a RHS using + # toplevel operators * or ?. + set mysvalue [pt::ast new0 $symbol $pos] + } else { + set mysvalue [pt::ast new $symbol $pos $myloc] + } + } + + set k [list $at $symbol] + set mysymbol($k) [list $myloc $myok $myerror $mysvalue] + + if {[llength $myerror]} { + set pos $at + incr pos + lassign $myerror loc messages + if {$loc == $pos} { + set myerror [list $loc [list [list n $symbol]]] + } + } + + $mystackast trim* [$mystackmark pop] + if {$myok} { + $mystackast push $mysvalue + } + return + } + + method si:value_clear_symbol_end {symbol} { + # i_value_clear + # i_symbol_save $symbol + # i_error_nonterminal $symbol + # i_loc_pop_discard + # i_ast_pop_rewind + + set mysvalue {} + set at [$mystackloc pop] + + set k [list $at $symbol] + set mysymbol($k) [list $myloc $myok $myerror $mysvalue] + + if {[llength $myerror]} { + set pos $at + incr pos + lassign $myerror loc messages + if {$loc == $pos} { + set myerror [list $loc [list [list n $symbol]]] + } + } + + $mystackast trim* [$mystackmark pop] + return + } + + method si:void_clear_symbol_end {symbol} { + # i_value_clear + # i_symbol_save $symbol + # i_error_nonterminal $symbol + # i_loc_pop_discard + + set mysvalue {} + set at [$mystackloc pop] + + set k [list $at $symbol] + set mysymbol($k) [list $myloc $myok $myerror $mysvalue] + + if {[llength $myerror]} { + set pos $at + incr pos + lassign $myerror loc messages + if {$loc == $pos} { + set myerror [list $loc [list [list n $symbol]]] + } + } + return } # # ## ### ##### ######## ############# ##################### ## API - Instructions - Control flow @@ -179,10 +1317,16 @@ method i_error_push {} { $mystackerr push $myerror return } + + method i_error_clear_push {} { + set myerror {} + $mystackerr push {} + return + } method i_error_pop_merge {} { set olderror [$mystackerr pop] # We have either old or new error data, keep it. @@ -372,33 +1516,22 @@ method i_input_next {msg} { # Inlined: Getch, Expected, ClearErrors # Satisfy from input cache if possible. incr myloc - if {$myloc < [llength $mytoken]} { - set mycurrent [lindex $mytoken $myloc 0] - set myok 1 - set myerror {} - return - } - - # Actually read from the input, and remember - # the information. - # Note: We are implicitly incrementing the location! - - set token [my ReadChar] - - if {![llength $token]} { + # May read from the input (ExtendTC), and remember the + # information. Note: We are implicitly incrementing the + # location! + if {($myloc >= [string length $mytoken]) && ![my ExtendTC]} { set myok 0 set myerror [list $myloc [list $msg]] return } + set mycurrent [string index $mytoken $myloc] - lappend mytoken $token - set mycurrent [lindex $token 0] - set myok 1 - set myerror {} + set myok 1 + set myerror {} return } method i_test_alnum {} { set myok [string is alnum -strict $mycurrent] @@ -494,28 +1627,40 @@ } # # ## ### ##### ######## ############# ##################### ## Internals - method ReadChar {} { - upvar 1 mychan mychan myline myline mycolumn mycolumn + method ExtendTC {} { + upvar 1 mychan mychan mytoken mytoken - if {[eof $mychan]} {return {}} + if {($mychan eq {}) || + [eof $mychan]} {return 0} set ch [read $mychan 1] - if {$ch eq ""} {return {}} - - set token [list $ch $myline $mycolumn] - - if {$ch eq "\n"} { - incr myline - set mycolumn 0 - } else { - incr mycolumn + if {$ch eq {}} { + return 0 + } + + append mytoken $ch + return 1 + } + + method ExtendTCN {n} { + upvar 1 mychan mychan mytoken mytoken + + if {($mychan eq {}) || + [eof $mychan]} {return 0} + + set str [read $mychan $n] + set k [string length $str] + + append mytoken $str + if {$k < $n} { + return 0 } - return $token + return 1 } method OkFail {msg} { upvar 1 myok myok myerror myerror myloc myloc # Inlined: Expected, Unget, ClearErrors @@ -531,15 +1676,13 @@ # # ## ### ##### ######## ############# ##################### ## Data structures. ## Mainly the architectural state of the instance's PARAM. variable \ - mychan myline mycolumn \ - mycurrent myloc mystackloc \ + mychan mycurrent myloc mystackloc \ myok mysvalue myerror mystackerr \ - mytoken mysymbol \ - mystackast mystackmark + mytoken mysymbol mystackast mystackmark # Parser Input (channel, location (line, column)) ........... # Token, current parsing location, stack of locations ....... # Match state . ........ ............. ..................... # Caches for tokens and nonterminals .. ..................... @@ -549,7 +1692,7 @@ } # # ## ### ##### ######## ############# ##################### ## Ready -package provide pt::rde 1.0.2 +package provide pt::rde::oo 1.0.2 return Index: modules/pt/pt_tclparam_config_tcloo.man ================================================================== --- modules/pt/pt_tclparam_config_tcloo.man +++ modules/pt/pt_tclparam_config_tcloo.man @@ -1,10 +1,10 @@ [comment {-*- text -*- doctools manpage}] -[manpage_begin pt::tclparam::configuration::tcloo n 1.0.1] +[manpage_begin pt::tclparam::configuration::tcloo n 1.0.3] [include include/module.inc] [titledesc {Tcl/PARAM, Canned configuration, Tcloo}] -[require pt::tclparam::configuration::tcloo [opt 1.0.1]] +[require pt::tclparam::configuration::tcloo [opt 1.0.3]] [description] [include include/ref_intro.inc] This package is an adjunct to [package pt::peg::to::tclparam], to make the use of this highly configurable package easier by providing a Index: modules/pt/pt_tclparam_config_tcloo.tcl ================================================================== --- modules/pt/pt_tclparam_config_tcloo.tcl +++ modules/pt/pt_tclparam_config_tcloo.tcl @@ -84,11 +84,11 @@ my MAIN ; # Entrypoint for the generated code. return [my complete] } method parset {text} { - my reset + my reset {} my data $text my MAIN ; # Entrypoint for the generated code. return [my complete] } @@ -115,7 +115,7 @@ namespace eval ::pt::tclparam::configuration::tcloo {} # # ## ### ##### ######## ############# ##################### ## Ready -package provide pt::tclparam::configuration::tcloo 1.0.2 +package provide pt::tclparam::configuration::tcloo 1.0.3 return