UNPKG

polygonjs-engine

Version:

node-based webgl 3D engine https://polygonjs.com

134 lines (126 loc) 3.57 kB
import jsep from 'jsep'; import {CoreType} from '../../../core/Type'; jsep.addUnaryOp('@'); // self.jsep = jsep let precedence = 10; jsep.addBinaryOp('**', precedence); // precedence = 1 // jsep.addBinaryOp('`', precedence) // const HOUDINI_QUOTE_CODE = 96; // houdini quote // const JSEP_COMPOUND = 'Compound' const JSEP_IDENTIFIER = 'Identifier'; const JSEP_LITERAL = 'Literal'; // const JSEP_BINARY_EXPRESSION = 'BynaryExpression' const JSEP_CALL_EXPRESSION = 'CallExpression'; const STRING_EXPRESSION_SEPARATOR = '`'; export class ParsedTree { public node: jsep.Expression | undefined; public error_message: string | undefined; constructor() {} parse_expression(string: string) { try { this.reset(); this.node = jsep(string); } catch (e) { const message = `could not parse the expression '${string}' (error: ${e})`; this.error_message = message; } } parse_expression_for_string_param(string: string) { try { this.reset(); const elements = ParsedTree.string_value_elements(string); const nodes = []; for (let i = 0; i < elements.length; i++) { const element = elements[i]; let node; if (i % 2 == 1) { node = jsep(element); } else { node = { type: JSEP_LITERAL, value: `'${element}'`, raw: `'${element}'`, }; } nodes.push(node); // nodes.push({ // type: JSEP_CALL_EXPRESSION, // arguments: [node], // callee: { // type: JSEP_IDENTIFIER, // name: 'toString', // } // }) } // let last_plus_node; // for(let i=0; i<(nodes.length-1); i++){ // const plus_node = { // type: JSEP_BINARY_EXPRESSION, // operator: '+', // left: last_plus_node || nodes[i], // right: nodes[i+1], // } // last_plus_node = plus_node; // } // this.node = last_plus_node this.node = (<unknown>{ type: JSEP_CALL_EXPRESSION, arguments: nodes, callee: { type: JSEP_IDENTIFIER, name: 'strConcat', }, }) as jsep.Compound; } catch (e) { const message = `could not parse the expression '${string}' (error: ${e})`; this.error_message = message; } } static string_value_elements(v: string): string[] { if (v != null) { if (CoreType.isString(v)) { return v.split(STRING_EXPRESSION_SEPARATOR); } else { return []; } } else { return []; } } // static string_value_contains_expression(v:string): boolean{ // return ((this.string_value_elements(v).length - 1) % 2) === 0; // } // deep_parse_for_string_expressions(){ // // for string expressions which have more than a single `<expr>` element // // pt_`@ptnum` // // `@ptnum`_pt // // pt_`@ptnum`_`1+1` // if(this.node.type == JSEP_COMPOUND){ // const args = this.node.body // let arg; // for(let i=0; i<args.length; i++){ // arg = args[i] // if(arg.type == JSEP_LITERAL){ // const arg_node = jsep(arg.value) // args[i] = arg_node // } // } // } else { // // for string expressions which havea single `<expr>` element // // `@ptnum` // if(this.node.type == JSEP_LITERAL){ // const raw = this.node.raw // const first_char_code = raw.charCodeAt(0) // const last_char_code = raw.charCodeAt(raw.length-1) // if(first_char_code == HOUDINI_QUOTE_CODE && last_char_code == HOUDINI_QUOTE_CODE){ // this.node = jsep("''+"+this.node.value) // add the prefix ''+ to ensure we have a string as a result, and not a number // } // } // } // } private reset() { this.node = undefined; this.error_message = undefined; } }