mirror of
https://github.com/flynx/pWiki.git
synced 2026-10-03 12:51:40 +00:00
Compare commits
3 Commits
b1c1c4024f
...
b9043887d3
| Author | SHA1 | Date | |
|---|---|---|---|
| b9043887d3 | |||
| 47e96df6ac | |||
| 2fc3a7cc12 |
@ -593,14 +593,10 @@ module.BaseParser = {
|
|||||||
// - everything returns an ast
|
// - everything returns an ast
|
||||||
// - callbacks/events/handlers to trigger on specific macro
|
// - callbacks/events/handlers to trigger on specific macro
|
||||||
// resolution
|
// resolution
|
||||||
// XXX Remove async/await... (???)
|
//
|
||||||
// - for trivial stuff they are nice
|
|
||||||
// - infectios -- force all subsequent levels to use async/await
|
|
||||||
// - provide no alternatives
|
|
||||||
// ...i.e. promises can be extended to indlude partial
|
|
||||||
// states and the like, async/await can't...
|
|
||||||
// XXX Q: do we need generators?
|
// XXX Q: do we need generators?
|
||||||
// XXX Handle errors...
|
// XXX Handle errors...
|
||||||
|
// XXX BUG: awaiting on .wait* can deadlock...
|
||||||
expand: function(page, ast, state={}, nested_handlers={}){
|
expand: function(page, ast, state={}, nested_handlers={}){
|
||||||
var that = this
|
var that = this
|
||||||
ast = typeof(ast) != 'object' ?
|
ast = typeof(ast) != 'object' ?
|
||||||
@ -651,13 +647,43 @@ 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){
|
||||||
|
elem.resolving = res
|
||||||
|
|
||||||
let all, nested
|
let all, nested
|
||||||
|
// XXX if res is not started yet and it has not yet
|
||||||
|
// started waiting for .waitAll this can be a
|
||||||
|
// condition for a dead lock:
|
||||||
|
// res -> .waitAll -> res
|
||||||
all = state.waitAll =
|
all = state.waitAll =
|
||||||
Promise.all([state.waitAll, res])
|
Promise.all([state.waitAll, res])
|
||||||
elem.resolving = res
|
|
||||||
// XXX do we need to wait till the last .waitNested is
|
// XXX do we need to wait till the last .waitNested is
|
||||||
// resolved?
|
// resolved?
|
||||||
// ...should it's handlers complete??
|
// ...should it's handlers complete??
|
||||||
@ -862,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') },
|
||||||
/*/
|
/*/
|
||||||
@ -963,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){
|
||||||
@ -1076,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){
|
||||||
@ -1092,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)
|
||||||
@ -1220,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 =
|
||||||
@ -1577,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
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user