experimenting with local state...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2026-07-12 17:36:47 +03:00
parent 47e96df6ac
commit b9043887d3

View File

@ -647,7 +647,31 @@ module.BaseParser = {
&& (body = this.expand(page, body, state, nested_handlers)) && (body = this.expand(page, body, state, nested_handlers))
// call macro... // call macro...
// XXX since this can be async and if so it will be mixed
// into the next .wait*, we'll need to explicitly pass
// and then thread the current .wait* promises before
// overwriting, to avoid wait-for-self deadlocks...
// ...the question is how to thread it...
// one way to do this is to split state into:
// state - current state of eval, mutable for all
// context - the context of evaluation of the curent
// macro, unique per macro, this would
// also be good to store things like
// line numbers and the like...
// ways to organize this:
// - context.state - nesting
// - state, context - sepatrate args
// - state.__proto__ - protorype
/* XXX LOCAL_STATE
var res = that.callMacro( page, name, args, body, {
__proto__: state,
state,
waitAll: state.waitAll,
waitNested: state.waitNested,
})
/*/
var res = that.callMacro(page, name, args, body, state) var res = that.callMacro(page, name, args, body, state)
//*/
// async... // async...
if(res instanceof Promise){ if(res instanceof Promise){
@ -864,7 +888,7 @@ module.BaseParser = {
return res.join('') }) }, return res.join('') }) },
// XXX // XXX
execNested: function(page, ast, state={}, nested_handlers={}){ execNested: function(page, ast, state={}, nested_handlers={}){
/* XXX waitNested here deadlocks the parser -- not sure why... /* XXX LOCAL_STATE waitNested here deadlocks the parser -- not sure why...
//return this.exec(page, ast, state, nested_handlers, 'unresolved') }, //return this.exec(page, ast, state, nested_handlers, 'unresolved') },
return this.exec(page, ast, state, nested_handlers, 'waitNested') }, return this.exec(page, ast, state, nested_handlers, 'waitNested') },
/*/ /*/
@ -965,6 +989,13 @@ module.parser = {
// //
// XXX should we include the global filters (current) or exclude // XXX should we include the global filters (current) or exclude
// them by default??? // them by default???
// XXX BUG: async body breaks nested filters...
// '<filter upper/>aaa <filter -upper> moo @source(/async/page) </filter> bbb'
// -> 'AAA MOO PAGE BBB'
// XXX and this deadlocks with LOCAL_STATE
// while:
// '<filter upper/>aaa <filter -upper> moo @source(/page) </filter> bbb'
// -> 'AAA moo Page BBB'
filter: Macro( filter: Macro(
[['clear']], [['clear']],
function(page, args, body, state){ function(page, args, body, state){
@ -1078,6 +1109,12 @@ module.parser = {
if(!name){ if(!name){
return '' } return '' }
/* XXX LOCAL_STATE
var vars = state.state.vars ??= {}
/*/
var vars = state.vars ??= {}
//*/
return Promise.awaitOrRun( return Promise.awaitOrRun(
this.execNested(page, name, state), this.execNested(page, name, state),
function(name){ function(name){
@ -1094,7 +1131,6 @@ module.parser = {
: undefined) : undefined)
?? args.shown ?? args.shown
var vars = state.vars ??= {}
// XXX INC_DEC // XXX INC_DEC
if(args.parent && name in vars){ if(args.parent && name in vars){
while(!vars.hasOwnProperty(name) while(!vars.hasOwnProperty(name)
@ -1222,10 +1258,15 @@ module.parser = {
var that = this var that = this
var name = args.name var name = args.name
/* XXX LOCAL_STATE
var slots = state.state.slots ??= {}
/*/
var slots = state.slots ??= {}
//*/
return Promise.awaitOrRun( return Promise.awaitOrRun(
this.execNested(page, name, state), this.execNested(page, name, state),
function(name){ function(name){
var slots = state.slots ??= {}
//var hidden = name in slots //var hidden = name in slots
var hidden = var hidden =
@ -1579,16 +1620,23 @@ module.parser = {
lazy( lazy(
function(page, args, body, state){ function(page, args, body, state){
var that = this var that = this
/* XXX LOCAL_STATE
var macros = state.state.macros ??= {}
/*/
var macros = state.macros ??= {}
//*/
return Promise.awaitOrRun( return Promise.awaitOrRun(
this.execNested(page, args.name, state), this.execNested(page, args.name, state),
function(name){ function(name){
// set macro... // set macro...
if(name && body){ if(name && body){
;(state.macros ??= {})[name] = body macros[name] = body
// get macro... // get macro...
} else if(name){ } else if(name){
body = (state.macros ?? {})[name] } body = macros[name] }
// else... // else...
if(args.src if(args.src