#lang racket/base
(require racket/promise
"ssax/sxpathlib.rkt"
srfi/2
"sxpath-ext.rkt"
"txpath.rkt"
"xpath-ast.rkt"
"xpath-context_xlink.rkt"
"ddo-axes.rkt")
(provide (all-defined-out))
(define (ddo:or . args)
(if (null? args) #f (or (car args) (apply ddo:or (cdr args)))))
(define (ddo:foldr op init lst)
(if (null? lst)
init
(op (car lst)
(ddo:foldr op init (cdr lst)))))
(define ddo:type-nodeset 'ddo:type-nodeset)
(define ddo:type-number 'ddo:type-number)
(define ddo:type-string 'ddo:type-string)
(define ddo:type-boolean 'ddo:type-boolean)
(define ddo:type-any 'ddo:type-any)
(define (ddo:nset-contained? nodeset1 nodeset2)
(cond
((null? nodeset1) #t)
((memq (car nodeset1) nodeset2)
(ddo:nset-contained? (cdr nodeset1) nodeset2))
(else #f)))
(define (ddo:nset-equal? nodeset1 nodeset2)
(and (ddo:nset-contained? nodeset1 nodeset2)
(ddo:nset-contained? nodeset2 nodeset1)))
(define (ddo:pos-result-forward? pos-result)
(let loop ((pos-res pos-result))
(cond
((null? pos-res) #t)
((or (null? (car pos-res)) (null? (cdar pos-res)))
(loop (cdr pos-res)))
(else
(< (cdaar pos-res) (cdadar pos-res))))))
(define (ddo:pos-result->nodeset pos-result)
(letrec ( (combine-2-pos-nodesets
(lambda (chain1 chain2)
(cond
((null? chain1) chain2)
((null? chain2) chain1)
((eq? (caar chain1) (caar chain2)) (cons (car chain1)
(combine-2-pos-nodesets (cdr chain1) (cdr chain2))))
((< (cdar chain1) (cdar chain2))
(cons (car chain1)
(combine-2-pos-nodesets (cdr chain1) chain2)))
(else
(cons (car chain2)
(combine-2-pos-nodesets chain1 (cdr chain2))))))))
(if
(null? pos-result) pos-result
(let ((pos-result (if (ddo:pos-result-forward? pos-result)
pos-result
(map reverse pos-result))))
(let loop ((res (car pos-result))
(to-scan (cdr pos-result)))
(if (null? to-scan)
res
(loop (combine-2-pos-nodesets res (car to-scan))
(cdr to-scan))))))))
(define (ddo:location-step-pos pos-axis-impl pred-impl-lst)
(lambda (nodeset position+size var-binding)
(map
car
(ddo:pos-result->nodeset
(map
(lambda (pos-nodeset)
(let iter-preds ((nset pos-nodeset)
(preds pred-impl-lst))
(if
(null? preds)
nset
(let ((size (length nset))) (let iter-pairs ((nset nset)
(res '())
(pos 1))
(if
(null? nset) (iter-preds (reverse res) (cdr preds))
(let ((val ((car preds) (list (caar nset)) (cons pos size) var-binding)))
(iter-pairs (cdr nset)
(if (if (number? val)
(= val pos)
(sxml:boolean val))
(cons (car nset) res)
res)
(+ pos 1)))))))))
(pos-axis-impl nodeset))))))
(define (ddo:location-step-non-intersect axis-impl pred-impl-lst)
(lambda (nodeset position+size var-binding)
(map-union
(lambda (node)
(let iter-preds ((nset (axis-impl node))
(preds pred-impl-lst))
(if
(null? preds)
nset
(let ((size (length nset))) (let iter-nodes ((nset nset)
(res '())
(pos 1))
(if
(null? nset) (iter-preds (reverse res) (cdr preds))
(let ((val ((car preds) (list (car nset)) (cons pos size) var-binding)))
(iter-nodes (cdr nset)
(if (if (number? val)
(= val pos)
(sxml:boolean val))
(cons (car nset) res)
res)
(+ pos 1)))))))))
nodeset)))
(define (ddo:location-step-non-pos axis-impl pred-impl-lst)
(lambda (nodeset position+size var-binding)
(let iter-preds ((nset (axis-impl nodeset))
(preds pred-impl-lst))
(if
(null? preds)
nset
(let ((curr-pred (car preds)))
(iter-preds
(filter
(lambda (node)
(sxml:boolean
(curr-pred (list node)
(cons 1 1) var-binding)))
nset)
(cdr preds)))))))
(define (ddo:filter-expr-general expr-impl pred-impl-lst)
(lambda (nodeset position+size var-binding)
(let ((prim-res (expr-impl nodeset position+size var-binding)))
(cond
((not (nodeset? prim-res))
(sxml:xpath-error "filter" "nodeset" prim-res)
'())
(else
(let iter-preds ((nset prim-res)
(preds pred-impl-lst))
(if
(null? preds)
nset
(let ((size (length nset))) (let iter-nodes ((nset nset)
(res '())
(pos 1))
(if
(null? nset) (iter-preds (reverse res) (cdr preds))
(let ((val ((car preds) (list (car nset)) (cons pos size) var-binding)))
(iter-nodes (cdr nset)
(if (if (number? val)
(= val pos)
(sxml:boolean val))
(cons (car nset) res)
res)
(+ pos 1)))))))))))))
(define (ddo:filter-expr-non-pos expr-impl pred-impl-lst)
(lambda (nodeset position+size var-binding)
(let ((prim-res (expr-impl nodeset position+size var-binding)))
(cond
((not (nodeset? prim-res))
(sxml:xpath-type-error "filter" "nodeset" prim-res)
'())
(else
(let iter-preds ((nset prim-res)
(preds pred-impl-lst))
(if
(null? preds)
nset
(let ((curr-pred (car preds)))
(iter-preds
(filter
(lambda (node)
(sxml:boolean
(curr-pred (list node)
(cons 1 1) var-binding)))
nset)
(cdr preds))))))))))
(define (ddo:filter-expr-special-predicate expr-impl special-pred-impl)
(lambda (nodeset position+size var-binding)
(let ((prim-res (expr-impl nodeset position+size var-binding)))
(if
(not (nodeset? prim-res))
(begin
(sxml:xpath-type-error "filter" "nodeset" prim-res)
'())
(special-pred-impl prim-res)))))
(define (ddo:all-contexts-in-doc doc)
(let iter-nodes ((contents (map
(lambda (kid) (list kid doc))
((sxml:child sxml:node?) doc)))
(res (list doc)))
(cond
((null? contents) (reverse res))
((not ((ntype?? '*) (caar contents))) (iter-nodes (cdr contents)
(cons
(draft:make-context (caar contents) (cdar contents))
res)))
(else (let iter-attrs ((attrs (sxml:attr-list (caar contents)))
(res (cons
(draft:make-context
(caar contents) (cdar contents))
res)))
(cond
((null? attrs) (iter-nodes
(append (map
(lambda (kid) (cons kid (car contents)))
((sxml:child sxml:node?) (caar contents)))
(cdr contents))
res))
((not (sxml:node? (car attrs))) (iter-attrs (cdr attrs) res))
((null? (cdar attrs)) (iter-attrs (cdr attrs)
(cons
(draft:make-context (car attrs) (car contents))
res)))
(else (iter-attrs
(cdr attrs)
(cons (draft:make-context (cadar attrs)
(cons (car attrs) (car contents)))
(cons
(draft:make-context (car attrs) (car contents))
res))))))))))
(define (ddo:unite-2-contextsets cntset1 cntset2)
(if
(null? cntset1) cntset2
(let loop ((order (ddo:all-contexts-in-doc
(draft:list-last
(sxml:context->content (car cntset1)))))
(cntset1 cntset1)
(cntset2 cntset2)
(res '()))
(cond
((null? cntset1)
(append (reverse res) cntset2))
((null? cntset2)
(append (reverse res) cntset1))
((eq? (sxml:context->node (car order))
(sxml:context->node (car cntset1)))
(loop (cdr order)
(cdr cntset1)
(if (eq? (sxml:context->node (car cntset1))
(sxml:context->node (car cntset2)))
(cdr cntset2)
cntset2)
(cons (car cntset1) res)))
((eq? (sxml:context->node (car order))
(sxml:context->node (car cntset2)))
(loop (cdr order)
cntset1
(cdr cntset2)
(cons (car cntset2) res)))
(else
(loop (cdr order) cntset1 cntset2 res))))))
(define (ddo:unite-multiple-context-sets . context-sets)
(if (null? context-sets) '()
(let loop ((res (car context-sets))
(more (cdr context-sets)))
(if (null? more)
res
(loop (ddo:unite-2-contextsets res (car more))
(cdr more))))))
(define (ddo:list-tail lst k)
(if (or (null? lst) (<= k 0))
lst
(ddo:list-tail (cdr lst) (- k 1))))
(define (ddo:list-head lst k)
(if (or (null? lst) (<= k 0))
'()
(cons (car lst) (ddo:list-head (cdr lst) (- k 1)))))
(define (ddo:list-ref lst k)
(cond ((null? lst) lst)
((zero? k) (car lst))
(else (ddo:list-ref (cdr lst) (- k 1)))))
(define ddo:check-ast-position?
(let ((ddo:ast-for-position-fun-call (txp:expr->ast "position()")))
(lambda (op)
(equal? op ddo:ast-for-position-fun-call))))
(define (ddo:check4ast-number op)
(if
(eq? (car op) 'number)
(let ((number (cadr op)))
(if (and (number? number) (exact? number))
number #f))
#f))
(define (ddo:check-special-predicate op)
(if
(not (eq? (car op) 'predicate))
#f (let ((expr (cadr op)))
(cond
((ddo:check4ast-number expr)
=> (lambda (num)
(lambda (nodeset) (ddo:list-ref nodeset (- num 1)))))
((and (memq (car expr) '(= > < >= <=))
(= (length expr) 3))
(call-with-values
(lambda ()
(cond
((and (ddo:check-ast-position? (cadr expr))
(ddo:check4ast-number (caddr expr)))
=> (lambda (num) (values (car expr) num)))
((and (ddo:check-ast-position? (caddr expr))
(ddo:check4ast-number (cadr expr)))
=> (lambda (num)
(values
(cond ((assq (car expr)
'((< . >) (> . <) (>= . <=) (<= . >=)))
=> cdr)
(else (car expr)))
num)))
(else
(values #f #f))))
(lambda (cmp-op num)
(if
(not num)
#f
(case cmp-op
((=)
(lambda (nodeset) (ddo:list-ref nodeset (- num 1))))
((>)
(lambda (nodeset) (ddo:list-tail nodeset num)))
((>=)
(lambda (nodeset) (ddo:list-tail nodeset (- num 1))))
((<)
(lambda (nodeset) (ddo:list-head nodeset (- num 1))))
((<=)
(lambda (nodeset) (ddo:list-head nodeset num)))
(else #f))))))
(else #f)))))
(define ddo:check-ast-desc-os?
(let ((ddo:ast-for-desc-os (cadr (txp:xpath->ast "//dummy"))))
(lambda (op)
(equal? op ddo:ast-for-desc-os))))
(define (ddo:rewrite-step* op-lst)
(cond
((or (null? op-lst) (null? (cdr op-lst))) op-lst)
((and (ddo:check-ast-desc-os? (car op-lst))
(equal? (txp:step-axis (cadr op-lst)) '(child))
(null? (txp:step-preds (cadr op-lst))))
(cons
(txp:construct-step
'(descendant) (txp:step-node-test (cadr op-lst)) )
(ddo:rewrite-step* (cddr op-lst))))
(else (cons (car op-lst)
(ddo:rewrite-step* (cdr op-lst))))))
(define (ddo:generate-pred-id)
(string->symbol
(string-append "*predicate-" (symbol->string (gensym)) "*")))
(define (ddo:get-pred-value pred-id)
(lambda (nodeset position+size var-binding)
(cond
((not (and (nodeset? nodeset)
(null? (cdr nodeset))))
(sxml:xpath-error
"internal DDO SXPath error; predicate given a non-singleton nodeset: ~e" pred-id)
#f)
((or (null? var-binding)
(not (eq? (caar var-binding) '*var-vector*)))
(sxml:xpath-error
"internal DDO SXPath error; predicate value not found: ~e " pred-id)
#f)
((assq (sxml:context->node (car nodeset))
(vector-ref (cdar var-binding) pred-id))
=> (lambda (pair) (force (cdr pair)))
)
(else (sxml:xpath-error
"internal DDO SXPath error; no predicate '~a' for node: ~e"
pred-id (sxml:context->node (car nodeset)))
#f))))
(define (ddo:get-pred-value-pos pred-id)
(lambda (nodeset position+size var-binding)
(cond
((not (and (nodeset? nodeset)
(null? (cdr nodeset))))
(sxml:xpath-error
"internal DDO SXPath error; predicate given a non-singleton nodeset: ~e" pred-id)
#f)
((or (null? var-binding)
(not (eq? (caar var-binding) '*var-vector*)))
(sxml:xpath-error
"internal DDO SXPath error; predicate value not found: ~e" pred-id)
#f)
((assq (sxml:context->node (car nodeset))
(vector-ref (cdar var-binding) pred-id))
=> (lambda (size-pair)
(if
(> (cdr position+size) (vector-length (cdr size-pair)))
(begin
(sxml:xpath-error
"internal DDO SXPath error; vector member for context size not found: ~e"
pred-id)
#f)
(let ((pos-vect (vector-ref (cdr size-pair)
(- (cdr position+size) 1))))
(if
(> (car position+size) (vector-length pos-vect))
(begin
(sxml:xpath-error
"internal DDO SXPath error; vector member for context position not found: ~e"
pred-id)
#f)
(force (vector-ref pos-vect
(- (car position+size) 1))))))))
(else (sxml:xpath-error
"internal DDO SXPath error; no predicate '~s' for node: ~e"
pred-id (sxml:context->node (car nodeset)))
#f))))
(define (ddo:get-abs-lpath-value pred-id)
(lambda (nodeset position+size var-binding)
(if
(or (null? var-binding)
(not (eq? (caar var-binding) '*var-vector*)))
(begin
(sxml:xpath-error
"internal DDO SXPath error; value for absolute location path not found: ~e" pred-id)
'() )
(vector-ref (cdar var-binding) pred-id))))
(define (ddo:construct-pred-values pred-impl context-set var-binding)
(map
(lambda (context)
(cons (sxml:context->node context)
(delay
(sxml:boolean (pred-impl (list context)
(cons 1 1) var-binding)))))
context-set))
(define (ddo:construct-pred-values-pos
pred-impl context-set var-binding max-size)
(map
(lambda (context)
(cons
(sxml:context->node context)
(let ((context (list context)))
(let iter-size ((size 1)
(size-lst '()))
(if
(> size max-size) (list->vector (reverse size-lst))
(let iter-pos ((position 1)
(pos-lst '()))
(if
(> position size) (iter-size
(+ size 1)
(cons (list->vector (reverse pos-lst))
size-lst))
(iter-pos
(+ position 1)
(cons
(delay
(let ((pred-value
(pred-impl
context (cons position size) var-binding)))
(if (number? pred-value)
(= pred-value position)
(sxml:boolean pred-value))))
pos-lst)))))))))
context-set))
(define (ddo:vector-copy-set vect k obj)
(let loop ((src (vector->list vect))
(pos 0)
(res '()))
(if
(null? src) (list->vector (reverse res))
(loop (cdr src)
(+ pos 1)
(cons
(if (= pos k) obj (car src))
res)))))
(define (ddo:add-vector-to-var-binding
vars2offsets deep-predicates doc var-binding)
(let ((cons-var-vector (lambda (var-vector var-binding)
(cons (cons '*var-vector* var-vector)
var-binding))))
(if
(and (null? deep-predicates) (null? var-binding))
var-binding (let* ((var-tree
(if
(< (length var-binding) 100) #f (ddo:var-binding->tree var-binding)))
(var-vector
(let iter-offsets ((pos (- (car vars2offsets) 1))
(vars-alist (cdr vars2offsets))
(lst '()))
(cond
((< pos 0) (list->vector lst))
((or (null? vars-alist) (not (= pos (cdar vars-alist))))
(iter-offsets (- pos 1)
vars-alist
(cons #f lst) ))
(else (iter-offsets
(- pos 1)
(cdr vars-alist)
(cons
(cond (var-tree (ddo:get-var-value-from-tree (caar vars-alist) var-tree))
((assq (caar vars-alist) var-binding)
=> cdr)
(else
(sxml:xpath-error "variable reference: unbound variable: ~e"
(cdar vars-alist))
'()))
lst)))))))
(if
(null? deep-predicates)
(cons-var-vector var-vector var-binding)
(let* ((context-set
(if (null? (filter
(lambda (triple)
(not (eq? (cadr triple) 'absolute-location-path)))
deep-predicates))
'() (ddo:all-contexts-in-doc doc)))
(max-size
(if (not (null? (filter cadr deep-predicates)))
(length context-set)
1 )))
(let iter-preds ((deep-predicates deep-predicates)
(var-vector var-vector))
(if
(null? deep-predicates) (cons-var-vector var-vector var-binding)
(iter-preds
(cdr deep-predicates)
(ddo:vector-copy-set
var-vector
(caar deep-predicates) (cond
((eq? (cadar deep-predicates) 'absolute-location-path)
((caddar deep-predicates) (as-nodeset doc)
(cons 1 1) (cons-var-vector var-vector var-binding)))
((cadar deep-predicates) (ddo:construct-pred-values-pos
(caddar deep-predicates) context-set
(cons-var-vector var-vector var-binding)
max-size))
(else
(ddo:construct-pred-values
(caddar deep-predicates) context-set
(cons-var-vector var-vector var-binding))))))))))))))
(define (ddo:charlst->branch lst value)
(if (null? (cdr lst)) (list (car lst) (cons 'value value))
`(,(car lst) #f ,(ddo:charlst->branch (cdr lst) value))))
(define (ddo:add-var-to-tree var-name var-value tree)
(letrec
((add-lst-to-tree (lambda (lst tree)
(if
(null? lst) (cons (car tree)
(cons (cons 'value var-value) (cddr tree)))
(let ((curr-char (car lst)))
(let iter-alist ((alist (cddr tree))
(res (list (cadr tree) (car tree))))
(cond
((null? alist) (reverse
(cons
(ddo:charlst->branch lst var-value)
res)))
((char=? (caar alist) curr-char) (if
(null? (cdr alist)) (reverse
(cons
(add-lst-to-tree (cdr lst) (car alist))
res))
(append
(reverse
(cons
(add-lst-to-tree (cdr lst) (car alist))
res))
(cdr alist))))
((char>? (caar alist) curr-char)
(if
(null? (cdr alist)) (reverse
(cons
(car alist)
(cons (ddo:charlst->branch lst var-value)
res)))
(append
(reverse
(cons
(ddo:charlst->branch lst var-value)
res))
alist)))
(else
(iter-alist (cdr alist)
(cons (car alist) res))))))))))
(add-lst-to-tree (string->list (symbol->string var-name))
tree)))
(define (ddo:var-binding->tree var-binding)
(let loop ((var-binding (cdr var-binding))
(tree
(list '*top*
#f
(ddo:charlst->branch
(string->list
(symbol->string (caar var-binding))) (cdar var-binding)))))
(if (null? var-binding)
tree
(loop (cdr var-binding)
(ddo:add-var-to-tree
(caar var-binding) (cdar var-binding) tree)))))
(define (ddo:get-var-value-from-tree var-name tree)
(let loop ((lst (string->list (symbol->string var-name)))
(tree tree))
(cond
((and (not (null? lst))
(assv (car lst) (cddr tree)))
=> (lambda (new-tree)
(loop (cdr lst) new-tree)))
((and (null? lst) (cadr tree) )
(cdadr tree))
(else
(sxml:xpath-error "variable reference: unbound variable: ~e" var-name)
'() ))))
(define (ddo:ast-axis-specifier op num-anc single-level? requires-position?)
(cond
((not (eq? (car op) 'axis-specifier)) (draft:signal-semantic-error "not an AxisSpecifier - " op))
(requires-position?
(case (caadr op) ((ancestor)
(list ddo:ancestor-pos
#f #f #t))
((ancestor-or-self)
(list ddo:ancestor-or-self-pos
#f #f #t))
((attribute)
(list draft:attribute
(draft:na-minus-nneg num-anc 1) single-level? #f))
((child)
(if single-level?
(list draft:child
(draft:na-minus-nneg num-anc 1) #t #f)
(list ddo:child-pos
(draft:na-minus-nneg num-anc 1) #f #t)))
((descendant)
(if single-level?
(list draft:descendant
(draft:na-minus-nneg num-anc 1) #f #f)
(list ddo:descendant-pos
(draft:na-minus-nneg num-anc 1) #f #t)))
((descendant-or-self)
(if single-level?
(list draft:descendant-or-self
num-anc #f #f)
(list ddo:descendant-or-self-pos
num-anc #f #t)))
((following)
(list ddo:following-single-level-pos
#f #f #t))
((following-sibling)
(list (if single-level?
ddo:following-sibling-single-level-pos
ddo:following-sibling-pos)
(draft:na-max num-anc 1) single-level? #t))
((namespace)
(list draft:namespace
(draft:na-minus-nneg num-anc 1) single-level? #f))
((parent)
(list (if single-level? ddo:parent-single-level-pos ddo:parent-pos)
(draft:na+ num-anc 1) single-level? #t))
((preceding)
(list ddo:preceding-single-level-pos
#f #f #t))
((preceding-sibling)
(list (if single-level?
ddo:preceding-sibling-single-level-pos
ddo:preceding-sibling-pos)
(draft:na-max num-anc 1) single-level? #t))
((self)
(list draft:self num-anc single-level? #f))
(else
(draft:signal-semantic-error "unknown AxisName - " op))))
(else (case (caadr op) ((ancestor)
(list ddo:ancestor #f #f))
((ancestor-or-self)
(list ddo:ancestor-or-self #f #f))
((attribute)
(list draft:attribute
(draft:na-minus-nneg num-anc 1) single-level?))
((child)
(list (if single-level? draft:child ddo:child)
(draft:na-minus-nneg num-anc 1) single-level?))
((descendant)
(list (if single-level? draft:descendant ddo:descendant)
(draft:na-minus-nneg num-anc 1) #f))
((descendant-or-self)
(list (if single-level?
draft:descendant-or-self ddo:descendant-or-self)
num-anc #f))
((following)
(list (if single-level? ddo:following-single-level ddo:following)
#f #f))
((following-sibling)
(list (if single-level?
ddo:following-sibling-single-level ddo:following-sibling)
(draft:na-max num-anc 1) single-level?))
((namespace)
(list draft:namespace
(draft:na-minus-nneg num-anc 1) single-level?))
((parent)
(list (if single-level? ddo:parent-single-level ddo:parent)
(draft:na+ num-anc 1) single-level?))
((preceding)
(list (if single-level? ddo:preceding-single-level ddo:preceding)
#f #f))
((preceding-sibling)
(list (if single-level?
ddo:preceding-sibling-single-level ddo:preceding-sibling)
(draft:na-max num-anc 1) single-level?))
((self)
(list draft:self num-anc single-level?))
(else
(draft:signal-semantic-error "unknown AxisName - " op))))))
(define (ddo:ast-location-path
op num-anc single-level? pred-nesting vars2offsets)
(case (car op)
((absolute-location-path)
(ddo:ast-absolute-location-path
op num-anc single-level? pred-nesting vars2offsets))
((relative-location-path)
(ddo:ast-relative-location-path
op num-anc single-level? pred-nesting vars2offsets))
(else
(draft:signal-semantic-error "improper LocationPath - " op))))
(define (ddo:ast-absolute-location-path
op num-anc single-level? pred-nesting vars2offsets)
(cond
((not (eq? (car op) 'absolute-location-path))
(draft:signal-semantic-error "not an AbsoluteLocationPath - " op))
((null? (cdr op)) (list
(lambda (nodeset position+size var-binding)
(draft:reach-root nodeset))
#f #t #f ddo:type-nodeset
'() vars2offsets
))
(else
(and-let*
((steps-res (ddo:ast-step-list
(cdr op) num-anc #t pred-nesting vars2offsets)))
(let ((impl (if
(null? (cdar steps-res)) (let ((step-impl (caar steps-res)))
(lambda (nodeset position+size var-binding)
(step-impl
(draft:reach-root nodeset) position+size var-binding)))
(let ((converters (car steps-res)))
(lambda (nodeset position+size var-binding)
(let rpt ((nset (draft:reach-root nodeset))
(fs converters))
(if (null? fs)
nset
(rpt ((car fs) nset position+size var-binding)
(cdr fs)))))))))
(if
(> pred-nesting 0) (let ((vars2offsets (list-ref steps-res 6)))
(list
(ddo:get-abs-lpath-value (car vars2offsets))
#f (caddr steps-res) #f ddo:type-nodeset
(cons
(list (car vars2offsets) 'absolute-location-path impl)
(list-ref steps-res 5) )
(cons (+ (car vars2offsets) 1)
(cdr vars2offsets))))
(cons impl
(cons #f (cddr steps-res) ))))))))
(define (ddo:ast-relative-location-path
op num-anc single-level? pred-nesting vars2offsets)
(if
(not (eq? (car op) 'relative-location-path))
(draft:signal-semantic-error "not a RelativeLocationPath - " op)
(and-let*
((steps-res
(ddo:ast-step-list
(cdr op) num-anc single-level? pred-nesting vars2offsets)))
(cons
(if
(null? (cdar steps-res)) (caar steps-res)
(let ((converters (car steps-res)))
(lambda (nodeset position+size var-binding)
(let rpt ((nset nodeset)
(fs converters))
(if (null? fs)
nset
(rpt ((car fs) nset position+size var-binding)
(cdr fs)))))))
(cdr steps-res) ))))
(define (ddo:ast-step op num-anc single-level? pred-nesting vars2offsets)
(cond
((eq? (car op) 'range-to)
(draft:signal-semantic-error "range-to function not implemented"))
((eq? (car op) 'filter-expr)
(ddo:ast-filter-expr op num-anc single-level? pred-nesting vars2offsets))
((eq? (car op) 'lambda-step) (let ((proc (cadr op)))
(list
(if
(and num-anc (zero? num-anc)) (lambda (nodeset position+size var-binding)
(proc (draft:contextset->nodeset (as-nodeset nodeset))
(if (and (pair? var-binding) (eq? (caar var-binding) '*var-vector*))
(cdr var-binding) var-binding)))
(lambda (nodeset position+size var-binding)
(draft:find-proper-context
(proc (draft:contextset->nodeset (as-nodeset nodeset))
(if (and (pair? var-binding) (eq? (caar var-binding) '*var-vector*))
(cdr var-binding) var-binding))
(map sxml:context->content (as-nodeset nodeset))
num-anc)))
num-anc #f #f ddo:type-any
'() vars2offsets
)))
((eq? (car op) 'step)
(if
(null? (cdddr op)) (and-let*
((axis-lst (ddo:ast-axis-specifier
(cadr op) num-anc single-level? #f))
(ntest (draft:ast-node-test (caddr op))))
(let ((axis ((car axis-lst) ntest num-anc)))
(list
(lambda (nodeset position+size var-binding)
(axis nodeset))
(cadr axis-lst)
(caddr axis-lst)
#f
ddo:type-nodeset
'() vars2offsets
)))
(and-let*
((preds-res (ddo:ast-predicate-list
(cdddr op) 0 #t (+ pred-nesting 1) vars2offsets))
(preds-res
(if (and (list-ref preds-res 3) (< pred-nesting 3)) (ddo:ast-predicate-list (cdddr op) 0 #t
(+ pred-nesting 2) vars2offsets
)
preds-res ))
(axis-lst (ddo:ast-axis-specifier
(cadr op)
(draft:na-max num-anc (cadr preds-res))
single-level?
(list-ref preds-res 3) ))
(ntest (draft:ast-node-test (caddr op))))
(let ((axis ((car axis-lst)
ntest (draft:na-max num-anc (cadr preds-res))))
(pred-impl-lst (car preds-res)))
(list
(cond
((not (list-ref preds-res 3)) (ddo:location-step-non-pos axis pred-impl-lst))
((list-ref axis-lst 3) (ddo:location-step-pos axis pred-impl-lst))
(else (ddo:location-step-non-intersect axis pred-impl-lst)))
(cadr axis-lst) (caddr axis-lst) #f ddo:type-nodeset
(list-ref preds-res 5) (list-ref preds-res 6) )))))
(else
(draft:signal-semantic-error "not a Step - " op))))
(define (ddo:ast-step-list
step-lst num-anc single-level? pred-nesting vars2offsets)
(let ((step-lst (ddo:rewrite-step* step-lst))
(calculate-single-level
(lambda (step-lst single-level?)
(let iter-steps ((steps step-lst)
(sl? single-level?)
(res '()))
(cond
((null? steps) res)
((or (memq (caar steps) '(range-to filter-expr lambda-step))
(not sl?))
(append (map
(lambda (step) #f)
steps) res))
(else (and-let*
((axis-lst (ddo:ast-axis-specifier
(cadar steps) 0 sl? #f)))
(iter-steps (cdr steps)
(caddr axis-lst) (cons sl? res)))))))))
(and-let*
((single-level-lst (calculate-single-level step-lst single-level?)))
(let loop ((steps-to-view (reverse step-lst))
(sl?-lst single-level-lst)
(res-lst '())
(num-anc num-anc)
(deep-predicates '())
(vars2offsets vars2offsets))
(if
(null? steps-to-view) (list res-lst
num-anc (car single-level-lst) #f
ddo:type-nodeset deep-predicates vars2offsets)
(and-let*
((step-res
(ddo:ast-step
(car steps-to-view) num-anc (car sl?-lst)
pred-nesting vars2offsets)))
(loop
(cdr steps-to-view)
(cdr sl?-lst)
(cons (car step-res) res-lst)
(cadr step-res)
(append (list-ref step-res 5) deep-predicates)
(list-ref step-res 6) )))))))
(define (ddo:ast-predicate op num-anc single-level? pred-nesting vars2offsets)
(if
(not (eq? (car op) 'predicate))
(draft:signal-semantic-error "not an Predicate - " op)
(and-let*
((expr-res (ddo:ast-expr (cadr op) 0 #t pred-nesting vars2offsets)))
(let ((requires-position?
(or (cadddr expr-res) (memq (list-ref expr-res 4) '(ddo:type-number ddo:type-any))))
(vars2offsets (list-ref expr-res 6)))
(call-with-values
(lambda ()
(if
(or (> pred-nesting 3)
)
(let ((pred-id (car vars2offsets)
))
(values
((if requires-position?
ddo:get-pred-value-pos ddo:get-pred-value)
pred-id)
(cons
(list pred-id
requires-position?
(car expr-res) )
(list-ref expr-res 5) )
(cons (+ (car vars2offsets) 1)
(cdr vars2offsets))))
(values (car expr-res) (list-ref expr-res 5)
vars2offsets)))
(lambda (pred-impl deep-predicates vars2offsets)
(list pred-impl
(cadr expr-res) (caddr expr-res) requires-position?
(list-ref expr-res 4) deep-predicates
vars2offsets)))))))
(define (ddo:ast-predicate-list
op-lst num-anc single-level? pred-nesting vars2offsets)
(let ((pred-res-lst
(ddo:foldr
(lambda (op init)
(cons
(ddo:ast-predicate
op 0 #t pred-nesting
(if (or (null? init) (not (car init)))
vars2offsets
(list-ref (car init) 6) ))
init))
'()
op-lst)))
(and
(not (memv #f pred-res-lst)) (list (map car pred-res-lst)
(apply draft:na-max (map cadr pred-res-lst))
#t
(apply ddo:or (map cadddr pred-res-lst))
ddo:type-any
(apply append (map
(lambda (pred-res) (list-ref pred-res 5))
pred-res-lst))
(list-ref (car pred-res-lst) 6) ))))
(define (ddo:ast-expr op num-anc single-level? pred-nesting vars2offsets)
(case (car op)
((or)
(ddo:ast-or-expr op num-anc single-level? pred-nesting vars2offsets))
((and)
(ddo:ast-and-expr op num-anc single-level? pred-nesting vars2offsets))
((= !=)
(ddo:ast-equality-expr op num-anc single-level? pred-nesting vars2offsets))
((< > <= >=)
(ddo:ast-relational-expr
op num-anc single-level? pred-nesting vars2offsets))
((+ -)
(ddo:ast-additive-expr op num-anc single-level? pred-nesting vars2offsets))
((* div mod)
(ddo:ast-multiplicative-expr
op num-anc single-level? pred-nesting vars2offsets))
((union-expr)
(ddo:ast-union-expr op num-anc single-level? pred-nesting vars2offsets))
((path-expr)
(ddo:ast-path-expr op num-anc single-level? pred-nesting vars2offsets))
((filter-expr)
(ddo:ast-filter-expr op num-anc single-level? pred-nesting vars2offsets))
((variable-reference)
(ddo:ast-variable-reference
op num-anc single-level? pred-nesting vars2offsets))
((literal)
(ddo:ast-literal op num-anc single-level? pred-nesting vars2offsets))
((number)
(ddo:ast-number op num-anc single-level? pred-nesting vars2offsets))
((function-call)
(ddo:ast-function-call op num-anc single-level? pred-nesting vars2offsets))
((absolute-location-path)
(ddo:ast-absolute-location-path
op num-anc single-level? pred-nesting vars2offsets))
((relative-location-path)
(ddo:ast-relative-location-path
op num-anc single-level? pred-nesting vars2offsets))
(else
(draft:signal-semantic-error "unknown Expr - " op))))
(define (ddo:apply-ast-procedure
ast-procedure op-lst num-anc single-level? pred-nesting vars2offsets)
(ddo:foldr
(lambda (expr init)
(cons
(ast-procedure
expr num-anc single-level? pred-nesting
(if (or (null? init) (not (car init)) )
vars2offsets
(list-ref (car init) 6) ))
init))
'()
op-lst))
(define (ddo:ast-or-expr op num-anc single-level? pred-nesting vars2offsets)
(let ((expr-res-lst
(ddo:apply-ast-procedure
ddo:ast-expr
(cdr op) 0 single-level? pred-nesting vars2offsets)))
(and
(not (memv #f expr-res-lst)) (let ((expr-impls (map car expr-res-lst)))
(list
(lambda (nodeset position+size var-binding)
(let rpt ((fs expr-impls))
(cond
((null? fs) #f)
((sxml:boolean ((car fs) nodeset position+size var-binding)) #t)
(else (rpt (cdr fs))))))
(apply draft:na-max (map cadr expr-res-lst)) #t (apply ddo:or (map cadddr expr-res-lst)) ddo:type-boolean
(apply append (map
(lambda (expr-res) (list-ref expr-res 5))
expr-res-lst))
(list-ref (car expr-res-lst) 6) )))))
(define (ddo:ast-and-expr op num-anc single-level? pred-nesting vars2offsets)
(let ((expr-res-lst
(ddo:apply-ast-procedure
ddo:ast-expr
(cdr op) 0 single-level? pred-nesting vars2offsets)))
(and
(not (memv #f expr-res-lst)) (let ((expr-impls (map car expr-res-lst)))
(list
(lambda (nodeset position+size var-binding)
(let rpt ((fs expr-impls))
(cond
((null? fs) #t)
((not
(sxml:boolean ((car fs) nodeset position+size var-binding)))
#f)
(else (rpt (cdr fs))))))
(apply draft:na-max (map cadr expr-res-lst)) #t (apply ddo:or (map cadddr expr-res-lst)) ddo:type-boolean
(apply append (map
(lambda (expr-res) (list-ref expr-res 5))
expr-res-lst))
(list-ref (car expr-res-lst) 6) )))))
(define (ddo:ast-equality-expr
op num-anc single-level? pred-nesting vars2offsets)
(and-let*
((left-lst
(ddo:ast-expr (cadr op) 0 single-level? pred-nesting vars2offsets))
(right-lst
(ddo:ast-expr (caddr op) 0 single-level? pred-nesting
(list-ref left-lst 6) )))
(let ((cmp-op (cadr (assq (car op) `((= ,sxml:equal?)
(!= ,sxml:not-equal?)))))
(left (car left-lst))
(right (car right-lst)))
(list
(lambda (nodeset position+size var-binding)
(cmp-op
(draft:contextset->nodeset
(left nodeset position+size var-binding))
(draft:contextset->nodeset
(right nodeset position+size var-binding))))
(draft:na-max (cadr left-lst) (cadr right-lst)) #t (or (cadddr left-lst) (cadddr right-lst)) ddo:type-boolean
(append (list-ref left-lst 5) (list-ref right-lst 5))
(list-ref right-lst 6) ))))
(define (ddo:ast-relational-expr
op num-anc single-level? pred-nesting vars2offsets)
(and-let*
((left-lst
(ddo:ast-expr (cadr op) 0 single-level? pred-nesting vars2offsets))
(right-lst
(ddo:ast-expr (caddr op) 0 single-level? pred-nesting
(list-ref left-lst 6) )))
(let ((cmp-op
(sxml:relational-cmp
(cadr (assq (car op) `((< ,<) (> ,>) (<= ,<=) (>= ,>=))))))
(left (car left-lst))
(right (car right-lst)))
(list
(lambda (nodeset position+size var-binding)
(cmp-op
(draft:contextset->nodeset
(left nodeset position+size var-binding))
(draft:contextset->nodeset
(right nodeset position+size var-binding))))
(draft:na-max (cadr left-lst) (cadr right-lst)) #t (or (cadddr left-lst) (cadddr right-lst)) ddo:type-boolean
(append (list-ref left-lst 5) (list-ref right-lst 5))
(list-ref right-lst 6) ))))
(define (ddo:ast-additive-expr
op num-anc single-level? pred-nesting vars2offsets)
(let ((expr-res-lst
(ddo:apply-ast-procedure
ddo:ast-expr
(cdr op) 0 single-level? pred-nesting vars2offsets)))
(and
(not (memv #f expr-res-lst)) (let ((add-op (cadr (assq (car op) `((+ ,+) (- ,-)))))
(expr-impls (map car expr-res-lst)))
(list
(lambda (nodeset position+size var-binding)
(apply
add-op
(map
(lambda (expr)
(sxml:number
(draft:contextset->nodeset
(expr nodeset position+size var-binding))))
expr-impls)))
(apply draft:na-max (map cadr expr-res-lst)) #t (apply ddo:or (map cadddr expr-res-lst)) ddo:type-number
(apply append (map
(lambda (expr-res) (list-ref expr-res 5))
expr-res-lst))
(list-ref (car expr-res-lst) 6) )))))
(define (ddo:ast-multiplicative-expr
op num-anc single-level? pred-nesting vars2offsets)
(and-let*
((left-lst
(ddo:ast-expr (cadr op) 0 single-level? pred-nesting vars2offsets))
(right-lst
(ddo:ast-expr (caddr op) 0 single-level? pred-nesting
(list-ref left-lst 6) )))
(let ((mul-op
(sxml:relational-cmp
(cadr (assq (car op) `((* ,*) (div ,/) (mod ,remainder))))))
(left (car left-lst))
(right (car right-lst)))
(list
(lambda (nodeset position+size var-binding)
(mul-op
(sxml:number
(draft:contextset->nodeset
(left nodeset position+size var-binding)))
(sxml:number
(draft:contextset->nodeset
(right nodeset position+size var-binding)))))
(draft:na-max (cadr left-lst) (cadr right-lst)) #t (or (cadddr left-lst) (cadddr right-lst)) ddo:type-number
(append (list-ref left-lst 5) (list-ref right-lst 5))
(list-ref right-lst 6) ))))
(define (ddo:ast-union-expr op num-anc single-level? pred-nesting vars2offsets)
(let ((expr-res-lst
(ddo:foldr
(lambda (expr init)
(let ((expr-res
(if
(or (null? init) (not (car init)))
(ddo:ast-expr
expr num-anc single-level? pred-nesting vars2offsets)
(ddo:ast-expr
expr #f single-level? pred-nesting
(list-ref (car init) 6) ))))
(cons
(if
(not (or (eq? (list-ref expr-res 4) ddo:type-nodeset)
(eq? (list-ref expr-res 4) ddo:type-any)))
(draft:signal-semantic-error
"expression to be unioned evaluates to a non-nodeset - "
expr)
expr-res)
init)))
'()
(cdr op))))
(and
(not (memv #f expr-res-lst)) (let ((expr-impls (map car expr-res-lst)))
(list
(lambda (nodeset position+size var-binding)
(let rpt ((res '())
(fs expr-impls))
(if
(null? fs)
res
(let ((nset ((car fs) nodeset position+size var-binding)))
(rpt
(ddo:unite-2-contextsets
res
(cond
((not (nodeset? nset))
(sxml:xpath-type-error "union" "nodeset" nset)
'())
(else nset)))
(cdr fs))))))
#f #f (apply ddo:or (map cadddr expr-res-lst)) ddo:type-nodeset
(apply append (map
(lambda (expr-res) (list-ref expr-res 5))
expr-res-lst))
(list-ref (car expr-res-lst) 6) )))))
(define (ddo:ast-path-expr op num-anc single-level? pred-nesting vars2offsets)
(and-let*
((steps-res (ddo:ast-step-list
(cddr op) num-anc
#f pred-nesting
vars2offsets))
(filter-lst (ddo:ast-filter-expr
(cadr op)
(cadr steps-res) single-level?
pred-nesting
(list-ref steps-res 6) )))
(if
(not (or (eq? (list-ref filter-lst 4) ddo:type-nodeset)
(eq? (list-ref filter-lst 4) ddo:type-any)))
(draft:signal-semantic-error
"location steps are applied to a non-nodeset result - " (cadr op))
(let ((init-impl (car filter-lst))
(converters (car steps-res)))
(list
(lambda (nodeset position+size var-binding)
(let ((nset
(init-impl nodeset position+size var-binding)))
(let rpt ((nset
(cond
((nodeset? nset) nset)
(else
(sxml:xpath-type-error "path" "nodeset" nset)
'())))
(fs converters))
(if (null? fs)
nset
(rpt ((car fs) nset position+size var-binding)
(cdr fs))))))
(cadr filter-lst) (cadddr steps-res) (cadddr filter-lst) ddo:type-nodeset
(append (list-ref filter-lst 5) (list-ref steps-res 5))
(list-ref filter-lst 6) )))))
(define (ddo:ast-filter-expr op num-anc single-level? pred-nesting vars2offsets)
(cond
((not (eq? (car op) 'filter-expr))
(draft:signal-semantic-error "not an FilterExpr - " op))
((not (eq? (caadr op) 'primary-expr))
(draft:signal-semantic-error "not an PrimaryExpr - " (cadr op)))
((null? (cddr op)) (ddo:ast-expr (cadadr op) num-anc single-level? pred-nesting vars2offsets))
((and (null? (cdddr op)) (ddo:check-special-predicate (caddr op)))
=> (lambda (special-pred-impl)
(and-let*
((expr-lst (ddo:ast-expr
(cadadr op)
num-anc single-level? pred-nesting vars2offsets)))
(list
(ddo:filter-expr-special-predicate
(car expr-lst) special-pred-impl)
(cadr expr-lst) (caddr expr-lst) (cadddr expr-lst) ddo:type-nodeset
(list-ref expr-lst 5) (list-ref expr-lst 6) ))))
(else (and-let*
((preds-res (ddo:ast-predicate-list
(cddr op) 0 #t (+ pred-nesting 1) vars2offsets))
(expr-lst (ddo:ast-expr
(cadadr op)
(draft:na-max num-anc (cadr preds-res)) single-level? pred-nesting
(list-ref preds-res 6) )))
(if
(not (or (eq? (list-ref expr-lst 4) ddo:type-nodeset)
(eq? (list-ref expr-lst 4) ddo:type-any)))
(draft:signal-semantic-error
"expression to be filtered evaluates to a non-nodeset - " (cadr op))
(let ((expr-impl (car expr-lst))
(pred-impl-lst (car preds-res)))
(list
(if
(list-ref preds-res 3) (ddo:filter-expr-general expr-impl pred-impl-lst)
(ddo:filter-expr-non-pos expr-impl pred-impl-lst))
(cadr expr-lst) (caddr expr-lst) (cadddr expr-lst) ddo:type-nodeset
(append (list-ref expr-lst 5) (list-ref preds-res 5))
(list-ref expr-lst 6) )))))))
(define (ddo:ast-variable-reference
op num-anc single-level? pred-nesting vars2offsets)
(let ((name (string->symbol (cadr op))))
(call-with-values
(lambda ()
(cond
((assq name (cdr vars2offsets)) => (lambda (pair)
(values (cdr pair) vars2offsets)))
(else (values (car vars2offsets)
(cons
(+ (car vars2offsets) 1)
(cons (cons name (car vars2offsets))
(cdr vars2offsets)))))))
(lambda (var-offset new-vars2offsets)
(list
(lambda (nodeset position+size var-binding)
(cond
((and (not (null? var-binding))
(eq? (caar var-binding) '*var-vector*))
(vector-ref (cdar var-binding) var-offset))
((assq name var-binding)
=> cdr)
(else
(sxml:xpath-error "variable reference: unbound variable: ~e" name)
'())))
0
#t #f
ddo:type-any '() new-vars2offsets)))))
(define (ddo:ast-literal op num-anc single-level? pred-nesting vars2offsets)
(let ((literal (cadr op)))
(list
(lambda (nodeset position+size var-binding) literal)
0 #t #f ddo:type-string '() vars2offsets)))
(define (ddo:ast-number op num-anc single-level? pred-nesting vars2offsets)
(let ((number (cadr op)))
(list
(lambda (nodeset position+size var-binding) number)
0 #t #f ddo:type-number '() vars2offsets)))
(define (ddo:ast-function-call
op num-anc single-level? pred-nesting vars2offsets)
(let ((core-alist
`((last 0 0 0 ,draft:core-last
#t #t ,ddo:type-number)
(position 0 0 0 ,draft:core-position
#t #t ,ddo:type-number)
(count 1 1 0 ,draft:core-count
#t #f ,ddo:type-number)
(id 1 1 #f ,draft:core-id
#f #f ,ddo:type-nodeset)
(local-name 0 1 0 ,draft:core-local-name
#t #f ,ddo:type-string)
(namespace-uri 0 1 0 ,draft:core-namespace-uri
#t #f ,ddo:type-string)
(name 0 1 0 ,draft:core-name
#t #f ,ddo:type-string)
(string 0 1 0 ,draft:core-string
#t #f ,ddo:type-string)
(concat 2 -1 0 ,draft:core-concat
#t #f ,ddo:type-string)
(starts-with 2 2 0 ,draft:core-starts-with
#t #f ,ddo:type-boolean)
(contains 2 2 0 ,draft:core-contains
#t #f ,ddo:type-boolean)
(substring-before 2 2 0 ,draft:core-substring-before
#t #f ,ddo:type-boolean)
(substring-after 2 2 0 ,draft:core-substring-after
#t #f ,ddo:type-boolean)
(substring 2 3 0 ,draft:core-substring
#t #f ,ddo:type-boolean)
(string-length 0 1 0 ,draft:core-string-length
#t #f ,ddo:type-number)
(normalize-space 0 1 0 ,draft:core-normalize-space
#t #f ,ddo:type-string)
(translate 3 3 0 ,draft:core-translate
#t #f ,ddo:type-string)
(boolean 1 1 0 ,draft:core-boolean
#t #f ,ddo:type-boolean)
(not 1 1 0 ,draft:core-not
#t #f ,ddo:type-boolean)
(true 0 0 0 ,draft:core-true
#t #f ,ddo:type-boolean)
(false 0 0 0 ,draft:core-false
#t #f ,ddo:type-boolean)
(lang 1 1 #f ,draft:core-lang
#t #f ,ddo:type-boolean)
(number 0 1 0 ,draft:core-number
#t #f ,ddo:type-number)
(sum 1 1 0 ,draft:core-sum
#t #f ,ddo:type-number)
(floor 1 1 0 ,draft:core-floor
#t #f ,ddo:type-number)
(ceiling 1 1 0 ,draft:core-ceiling
#t #f ,ddo:type-number)
(round 1 1 0 ,draft:core-round
#t #f ,ddo:type-number))))
(cond
((not (eq? (caadr op) 'function-name))
(draft:signal-semantic-error "not an FunctionName - " (cadr op)))
((assq (string->symbol (cadadr op)) core-alist)
=> (lambda (description) (cond
((< (length (cddr op)) (cadr description))
(draft:signal-semantic-error
"too few arguments for the Core Function call - "
(cadadr op)))
((and (>= (caddr description) 0)
(> (length (cddr op)) (caddr description)))
(draft:signal-semantic-error
"too many arguments for the Core Function call - "
(cadadr op)))
(else (and-let*
((args-impl-lst (ddo:ast-function-arguments
(cddr op) single-level? pred-nesting vars2offsets)))
(list
(apply (list-ref description 4)
num-anc
(map car args-impl-lst))
(apply draft:na-max
(cons
(list-ref description 3) (map cadr args-impl-lst) ))
(list-ref description 5) (or (list-ref description 6) (not (null?
(filter cadddr args-impl-lst))))
(list-ref description 7) (apply append (map
(lambda (arg-res) (list-ref arg-res 5))
args-impl-lst))
(if (null? args-impl-lst) vars2offsets
(list-ref (car args-impl-lst) 6))
))))))
(else (draft:signal-semantic-error
"function call to an unknown function - " (cadadr op))))))
(define (ddo:ast-function-arguments
op-lst single-level? pred-nesting vars2offsets)
(let ((arg-res-lst
(ddo:foldr
(lambda (op init)
(cons
(if
(not (eq? (car op) 'argument))
(draft:signal-semantic-error "not an Argument - " op)
(ddo:ast-expr
(cadr op) 0 single-level? pred-nesting
(if (or (null? init) (not (car init)))
vars2offsets
(list-ref (car init) 6) )))
init))
'()
op-lst)))
(and
(not (memv #f arg-res-lst)) arg-res-lst)))
(define (ddo:api-helper grammar-parser ast-parser)
(lambda (xpath-string . ns+na)
(call-with-values
(lambda () (draft:arglist->ns+na ns+na))
(lambda (ns-binding num-anc)
(and-let*
((ast (grammar-parser xpath-string ns-binding))
(impl-lst (ast-parser ast num-anc
#t 0 '(0) )))
(let ((impl-lambda
(if
(and num-anc (zero? num-anc))
(let ((impl-car (car impl-lst)))
(lambda (node position+size var-binding)
(draft:contextset->nodeset
(impl-car node position+size var-binding))))
(car impl-lst))))
(lambda (node . var-binding) (impl-lambda
(as-nodeset node)
(cons 1 1)
(ddo:add-vector-to-var-binding
(list-ref impl-lst 6) (reverse (list-ref impl-lst 5))
node
(if (null? var-binding) var-binding (car var-binding)))))))))))
(define ddo:txpath (ddo:api-helper txp:xpath->ast ddo:ast-location-path))
(define ddo:xpath-expr (ddo:api-helper txp:expr->ast ddo:ast-expr))
(define ddo:sxpath (ddo:api-helper txp:sxpath->ast ddo:ast-expr))