UNPKG

expexp

Version:

The express model io and express model and data representation.

397 lines (376 loc) 12.8 kB
function traverseType(path, json, afterFct, beforeFct, afterArr, beforeArr) { beforeFct(json, path, -1) path.push(json) if ('bounds' in json) { traverseBounds(path, json.bounds, afterFct, beforeFct, afterArr, beforeArr) } if ('spec' in json) { if (json.t != 'string' && json.t != 'binary') { traverseType(path, json.spec, afterFct, beforeFct, afterArr, beforeArr) } else { // For string and binary the bounds are called spec. traverseBounds(path, json.spec, afterFct, beforeFct, afterArr, beforeArr) } } path.pop() // json afterFct(json, path, -1) } function traverseBounds(path, json, afterFct, beforeFct, afterArr, beforeArr) { beforeFct(json, path, -1) path.push(json) if ('from' in json) { traverseSimpleExpression(path, json.from, afterFct, beforeFct, afterArr, beforeArr) } if ('to' in json) { traverseSimpleExpression(path, json.to, afterFct, beforeFct, afterArr, beforeArr) } path.pop() // json afterFct(json, path, -1) } function traverseExpression(path, json, afterFct, beforeFct, afterArr, beforeArr) { if (json) { // can be null (for local assignment) beforeFct(json, path, -1) path.push(json) traverseSimpleExpression(path, json.arg0, afterFct, beforeFct, afterArr, beforeArr) if (json.op) { beforeFct(json.op, path, -1) afterFct(json.op, path, -1) } if (json.arg1) { traverseSimpleExpression(path, json.arg1, afterFct, beforeFct, afterArr, beforeArr) } path.pop() afterFct(json, path, -1) } } function traverseSimpleExpression(path, json, afterFct, beforeFct, afterArr, beforeArr) { beforeArr(json, path, -1) path.push(json) for (const [i, too] of json.entries()) { // term or add_like_op if (Array.isArray(too)) { // term is an array beforeArr(too, path, i) path.push(too) for (const [j, fom] of too.entries()) { // factor or multiplication_like_op beforeFct(fom, path, j) path.push(fom) if (fom.t == 'factor') { traverseSimpleFactor(path, fom.arg0, afterFct, beforeFct, afterArr, beforeArr) beforeArr(fom.quals0, path, -1) path.push(fom.quals0) for (const [k, q] of fom.quals0.entries()) { traverseQualifier(path, k, q, afterFct, beforeFct, afterArr, beforeArr) } path.pop() // quals0 afterArr(fom.quals0, path, -1) if (fom.arg1) { traverseSimpleFactor(path, fom.arg1, afterFct, beforeFct, afterArr, beforeArr) } if (Array.isArray(fom.quals1)) { beforeArr(fom.quals1, path, -1) path.push(fom.quals1) for (const [k, q] of fom.quals1.entries()) { traverseQualifier(path, k, q, afterFct, beforeFct, afterArr, beforeArr) } path.pop() // fom.quals1 afterArr(fom.quals1, path, -1) } //} else { // multiplication_like_op (visited as fom) } path.pop() // fom afterFct(fom, path, j) } path.pop() // too afterArr(too, path, i) } else { // add_like_op beforeFct(too, path, i) afterFct(too, path, i) } } path.pop() // json afterArr(json, path, -1) } function traverseSimpleFactor(path, json, afterFct, beforeFct, afterArr, beforeArr) { beforeFct(json, path, -1) path.push(json) switch (json.t) { case 'bifct': case 'func_call': case 'foeot': // Support also traversal of the original tree from the parser. // if json is unfortunately an array it has a function named values beforeArr(json.values, path, -1) path.push(json.values) for (const [i, vj] of json.values.entries()) { traverseExpression(path, vj, afterFct, beforeFct, afterArr, beforeArr) // recur } path.pop() // json.values afterArr(json.values, path, -1) break case 'parenthesis': traverseExpression(path, json.expr, afterFct, beforeFct, afterArr, beforeArr) break case 'unary': traverseSimpleFactor(path, json.arg, afterFct, beforeFct, afterArr, beforeArr) beforeFct(json.op, path, -1) afterFct(json.op, path, -1) break case 'aggr': // has values like bifct and foeot but the elements are different beforeArr(json.values, path, -1) path.push(json.values) for (const [i, vj] of json.values.entries()) { traverseElement(path, i, vj, afterFct, beforeFct, afterArr, beforeArr) } path.pop() // json.values afterArr(json.values, path, -1) break case 'query': traverseSimpleExpression(path, json.src, afterFct, beforeFct, afterArr, beforeArr) // recur traverseExpression(path, json.cond, afterFct, beforeFct, afterArr, beforeArr) // recur break case 'interval': traverseSimpleExpression(path, json.argl, afterFct, beforeFct, afterArr, beforeArr) // recur traverseSimpleExpression(path, json.arg, afterFct, beforeFct, afterArr, beforeArr) // recur traverseSimpleExpression(path, json.argr, afterFct, beforeFct, afterArr, beforeArr) // recur break } path.pop() // json afterFct(json, path, -1) } function traverseQualifier(path, i, json, afterFct, beforeFct, afterArr, beforeArr) { beforeFct(json, path, i) if (json.t == 'idx_qual') { path.push(json) traverseSimpleExpression(path, json.idxStart, afterFct, beforeFct, afterArr, beforeArr) // recur traverseSimpleExpression(path, json.idxEnd, afterFct, beforeFct, afterArr, beforeArr) // recur path.pop() // json } afterFct(json, path, i) } function traverseElement(path, i, json, afterFct, beforeFct, afterArr, beforeArr) { beforeFct(json, path, i) path.push(json) traverseExpression(path, json.arg, afterFct, beforeFct, afterArr, beforeArr) traverseSimpleExpression(path, json.mult, afterFct, beforeFct, afterArr, beforeArr) path.pop() // json afterFct(json, path, i) } function traverseWhere(path, json, afterFct, beforeFct, afterArr, beforeArr) { // The json is visited externally. if ('wheres' in json) { beforeArr(json.wheres, path, -1) path.push(json.wheres) for (const [i, wj] of json.wheres.entries()) { beforeFct(wj, path, i) path.push(wj) traverseExpression(path, wj.expr, afterFct, beforeFct, afterArr, beforeArr) beforeFct(wj.id, path, -1) afterFct(wj.id, path, -1) path.pop() // wj afterFct(wj, path, i) } path.pop() // json.wheres afterArr(json.wheres, path, -1) } } function traverseContent(path, content, afterFct, beforeFct, afterArr, beforeArr) { beforeArr(content, path, -1) path.push(content) for (const [i,json] of content.entries()) { beforeFct(json, path, i) path.push(json) if ('spec' in json) { path.push(json.spec) if ('values' in json.spec) { beforeArr(json.spec.values, path, -1) path.push(json.spec.values) for (const [k, vl] of json.spec.values.entries()) { beforeFct(vl, path, k) afterFct(vl, path, k) } path.pop() // json.spec.values afterArr(json.spec.values, path, -1) } if ('refs' in json.spec) { beforeArr(json.spec.refs, path, -1) path.push(json.spec.refs) for (const [k,ref] of json.spec.refs.entries()) { beforeFct(ref, path, k) afterFct(ref, path, k) } path.pop() // json.spec.refs afterArr(json.spec.refs, path, -1) } path.pop() // json.spec traverseType(path, json.spec, afterFct, beforeFct, afterArr, beforeArr) } // entity if ('attrs' in json) { beforeArr(json.attrs, path, -1) path.push(json.attrs) for (const [k,aj] of json.attrs.entries()) { beforeFct(aj, path, k) path.push(aj) beforeArr(aj.ids, path, -1) path.push(aj.ids) for (const [l, ij] of aj.ids.entries()) { beforeFct(ij, path, l) afterFct(ij, path, l) } path.pop() // aj.ids afterArr(aj.ids, path, -1) traverseType(path, aj.type, afterFct, beforeFct, afterArr, beforeArr) path.pop() // aj afterFct(aj, path, k) } path.pop() // json.attrs afterArr(json.attrs, path, -1) } if ('derives' in json) { beforeArr(json.derives, path, -1) path.push(json.derives) for (const [k, dj] of json.derives.entries()) { beforeFct(dj, path, k) path.push(dj) beforeFct(dj.id, path, -1) if ('nttRef' in dj.id) { path.push(dj.id) beforeFct(dj.id.nttRef, path, -1) afterFct(dj.id.nttRef, path, -1) path.pop() // dj.id } afterFct(dj.id, path, -1) traverseType(path, dj.type, afterFct, beforeFct, afterArr, beforeArr) traverseExpression(path, dj.expr, afterFct, beforeFct, afterArr, beforeArr) path.pop() // dj afterFct(dj, path, k) } path.pop() // json.derives afterArr(json.derives, path, -1) } if ('inverses' in json) { beforeArr(json.inverses, path, -1) path.push(json.inverses) for (const [k, ij] of json.inverses.entries()) { beforeFct(ij, path, k) path.push(ij) beforeFct(ij.id, path, -1) afterFct(ij.id, path, -1) traverseBounds(path, ij.aggrBnds, afterFct, beforeFct, afterArr, beforeArr) beforeFct(ij.invRef, path, -1) afterFct(ij.invRef, path, -1) beforeFct(ij.nttRef, path, -1) afterFct(ij.nttRef, path, -1) path.pop() // ij afterFct(ij, path, k) } path.pop() // json.inverses afterArr(json.inverses, path, -1) } if ('uniques' in json) { beforeArr(json.uniques, path, -1) path.push(json.uniques) for (const [k, uj] of json.uniques.entries()) { beforeFct(uj, path, k) path.push(uj) beforeArr(uj.args, path, -1) path.push(uj.args) for (const [l, ua] of uj.args.entries()) { beforeFct(ua, path, l) path.push(ua) // TODO also here recur into a qualifier chain if ('nttRef' in ua && ua.nttRef) { // qual_attr beforeFct(ua.nttRef, path, -1) afterFct(ua.nttRef, path, -1) } path.pop() // ua afterFct(ua, path, l) } path.pop() // uj.args afterArr(uj.args, path, -1) path.pop() // uj afterFct(uj, path, k) } path.pop() // json.uniques afterArr(json.uniques, path, -1) } traverseWhere(path, json, afterFct, beforeFct, afterArr, beforeArr) // entity or types where // function or procedure if ('params' in json) { beforeArr(json.params, path, -1) path.push(json.params) for (const [k, pj] of json.params.entries()) { beforeFct(pj, path, k) path.push(pj) beforeArr(pj.ids, path, -1) path.push(pj.ids) for (const [l, ij] of pj.ids.entries()) { beforeFct(ij, path, l) afterFct(ij, path, l) } path.pop() // pj.ids afterArr(pj.ids, path, -1) traverseType(path, pj.type, afterFct, beforeFct, afterArr, beforeArr) path.pop() // pj afterFct(pj, path, k) } path.pop() // json.params afterArr(json.params, path, -1) } if ('locals' in json) { beforeArr(json.locals, path, -1) path.push(json.locals) for (const [k,lj] of json.locals.entries()) { beforeFct(lj, path, k) path.push(lj) beforeArr(lj.ids, path, -1) path.push(lj.ids) for (const [l,ij] of lj.ids.entries()) { beforeFct(ij, path, l) afterFct(ij, path, l) } path.pop() // lj.ids afterArr(lj.ids, path, -1) traverseType(path, lj.type, afterFct, beforeFct, afterArr, beforeArr) traverseExpression(path, lj.expr, afterFct, beforeFct, afterArr, beforeArr) path.pop() // lj afterFct(lj, path, k) } path.pop() // json.locals afterArr(json.locals, path, -1) } if ('result' in json) { traverseType(path, json.result, afterFct, beforeFct, afterArr, beforeArr) } path.pop() // json afterFct(json, path, i) } path.pop() // content afterArr(content, path, -1) } const noOp = function(){} function traverseContentExternal(content, afterFct, beforeFct = noOp, afterArr = noOp, beforeArr = noOp, path = []) { traverseContent(path, content, afterFct, beforeFct, afterArr, beforeArr) } function traverseSimpleExpressionExternal(json, afterFct, beforeFct = noOp, afterArr = noOp, beforeArr = noOp, path = []) { traverseSimpleExpression(path, json, afterFct, beforeFct, afterArr, beforeArr) } function traverseExpressionExternal(json, afterFct, beforeFct = noOp, afterArr = noOp, beforeArr = noOp, path = []) { traverseExpression(path, json, afterFct, beforeFct, afterArr, beforeArr) } function traverseSimpleFactorExternal(content, afterFct, beforeFct = noOp, afterArr = noOp, beforeArr = noOp, path = []) { traverseSimpleFactor(path, content, afterFct, beforeFct, afterArr, beforeArr) } function traverseTypeExternal(json, afterFct, beforeFct = noOp, afterArr = noOp, beforeArr = noOp, path = []) { traverseType(path, json, afterFct, beforeFct, afterArr, beforeArr) } function traverseBoundsExternal(json, afterFct, beforeFct = noOp, afterArr = noOp, beforeArr = noOp, path = []) { traverseBounds(path, json, afterFct, beforeFct, afterArr, beforeArr) } export { traverseContentExternal as traverseContent, traverseSimpleExpressionExternal as traverseSimpleExpression, traverseExpressionExternal as traverseExpression, traverseSimpleFactorExternal as traverseSimpleFactor, traverseTypeExternal as traverseType, traverseBoundsExternal as traverseBounds }