// Closure capture for the ast function, prevent collision with existing AST functions var functionNode_webgl = (function() { /// /// Function: functionNode_webgl /// /// [INTERNAL] Takes in a function node, and does all the AST voodoo required to generate its respective webGL code. /// /// Parameter: /// inNode - {functionNode} The function node object /// /// Returns: /// the converted webGL function string /// function functionNode_webgl( inNode ) { inNode.webglFunctionString_array = ast_generic( inNode.getJS_AST(), [], inNode ); inNode.webglFunctionString = inNode.webglFunctionString_array.join("").trim(); return inNode.webglFunctionString; } /// the AST error, with its location. To throw /// /// @TODO: add location support fpr the AST error /// /// @param error the error message output /// @param ast the AST object where the error is /// @param funcParam FunctionNode, that tracks compilation state function ast_errorOutput(error, ast, funcParam) { console.error(error, ast, funcParam); return error; } /// Prases the abstract syntax tree, genericially to its respective function /// /// @param ast the AST object to parse /// @param retArr return array string /// @param funcParam FunctionNode, that tracks compilation state /// /// @returns the prased openclgl string array function ast_generic(ast, retArr, funcParam) { if(ast === null) { throw ast_errorOutput("NULL ast", ast, funcParam); } else { if (Array.isArray(ast)) { for (var i=0; i 0 ) { retArr.push(", "); } retArr.push( funcParam.paramType[i] ); retArr.push(" "); retArr.push( funcParam.paramNames[i] ); } // Function opening retArr.push(") {\n"); // Body statement iteration for(var i=0; i 0) { retArr.push(","); } ast_generic(vardecNode.declarations[i], retArr, funcParam); } retArr.push(";"); return retArr; } function ast_VariableDeclarator(ivardecNode, retArr, funcParam) { ast_generic(ivardecNode.id, retArr, funcParam); if (ivardecNode.init !== null) { retArr.push("="); ast_generic(ivardecNode.init, retArr, funcParam); } return retArr; } function ast_IfStatement(ifNode, retArr, funcParam) { retArr.push("if("); ast_generic(ifNode.test, retArr, funcParam); retArr.push(")"); ast_generic(ifNode.consequent, retArr, funcParam); retArr.push("else"); ast_generic(ifNode.alternate, retArr, funcParam); return retArr; } function ast_Break(brNode, retArr, funcParam) { retArr.push("break;\n"); return retArr; } function ast_Continue(crNode, retArr, funcParam) { retArr.push("continue;\n"); return retArr; } function ast_LogicalExpression(logNode, retArr, funcParam) { ast_generic(logNode.left, retArr, funcParam); ast_generic(logNode.operator, retArr, funcParam); ast_generic(logNode.right, retArr, funcParam); return retArr; } function ast_UpdateExpression(uNode, retArr, funcParam) { if(uNode.prefix) { retArr.push(uNode.operator); ast_generic(uNode.argument, retArr, funcParam); } else { ast_generic(uNode.argument, retArr, funcParam); retArr.push(uNode.operator); } return retArr; } function ast_UnaryExpression(uNode, retArr, funcParam) { if(uNode.prefix) { retArr.push(uNode.operator); ast_generic(uNode.argument, retArr, funcParam); } else { ast_generic(uNode.argument, retArr, funcParam); retArr.push(uNode.operator); } return retArr; } function ast_ThisExpression(tNode, retArr, funcParam) { retArr.push("this"); return retArr; } function ast_MemberExpression(mNode, retArr, funcParam) { if(mNode.computed) { if (mNode.object.type == "Identifier") { retArr.push("get("); ast_generic(mNode.object, retArr, funcParam); retArr.push(", vec2("); ast_generic(mNode.object, retArr, funcParam); retArr.push("Size[0],"); ast_generic(mNode.object, retArr, funcParam); retArr.push("Size[1]), vec3("); ast_generic(mNode.object, retArr, funcParam); retArr.push("Dim[0],"); ast_generic(mNode.object, retArr, funcParam); retArr.push("Dim[1],"); ast_generic(mNode.object, retArr, funcParam); retArr.push("Dim[2]"); retArr.push("), "); } else { ast_generic(mNode.object, retArr, funcParam); var last = retArr.pop(); retArr.push(","); } ast_generic(mNode.property, retArr, funcParam); retArr.push(")"); } else { ast_generic(mNode.object, retArr, funcParam); retArr.push("."); ast_generic(mNode.property, retArr, funcParam); } return retArr; } function ast_SequenceExpression(sNode, retArr, funcParam) { for (var i = 0; i < sNode.expressions.length; i++) { if (i > 0) { retArr.push(","); } ast_generic(sNode.expressions, retArr, funcParam); } return retArr; } /// Utility function for ast_CallExpression. /// /// Prases the abstract syntax tree, binary expression. /// /// @param ast the AST object to parse /// /// @returns {String} the function namespace call, unrolled function ast_CallExpression_unroll(ast, funcParam) { if( ast.type == "Identifier" ) { return ast.name; } if( ast.type == "MemberExpression" ) { if( ast.object && ast.property ) { return ( ast_CallExpression_unroll( ast.object, funcParam ) + "." + ast_CallExpression_unroll( ast.property, funcParam ) ); } } // Failure, unknown expression throw ast_errorOutput( "Unknown CallExpression_unroll", ast, funcParam ); } // The math prefix to use var jsMathPrefix = "Math."; /// Prases the abstract syntax tree, binary expression /// /// @param ast the AST object to parse /// @param retArr return array string /// @param funcParam FunctionNode, that tracks compilation state /// /// @returns the appened retArr function ast_CallExpression(ast, retArr, funcParam) { if( ast.callee ) { // Get the full function call, unrolled var funcName = ast_CallExpression_unroll(ast.callee); // Its a math operator, remove the prefix if( funcName.indexOf(jsMathPrefix) === 0 ) { funcName = funcName.slice( jsMathPrefix.length ); } // Register the function into the called registry if( funcParam.calledFunctions.indexOf(funcName) < 0 ) { funcParam.calledFunctions.push(funcName); } // Call the function retArr.push( funcName ); // Open arguments space retArr.push( "(" ); // Add the vars for(var i=0; i 0) { retArr.push(", "); } ast_generic(ast.arguments[i],retArr,funcParam); } // Close arguments space retArr.push( ")" ); return retArr; } // Failure, unknown expression throw ast_errorOutput( "Unknown CallExpression", ast, funcParam ); return retArr; } return functionNode_webgl; })();