parseFunction(callee){ var source = callee.toString() if(source.indexOf('function')!== 0) source = 'function '+source // parse it, should never not work since it already parsed try{ var ast = parsecache[source] || (parsecache[source] = parser.parse(source)) } catch(e){ throw this.SyntaxErr(callee, "Cant parse function " + source) } return ast }
static generateGLSL(root, fn, varyIn, mapexception, litFloats, litInts){ var gen = new this() // geometry props gen.geometryProps = {} // instance props gen.instanceProps = {} // all samplers gen.samplers = {} // all uniforms found gen.uniforms = {} // literal values gen.literalFloats = litFloats gen.literalInts = litInts // all structs used gen.structs = {} // varyIngs found gen.varyOut = {} // varyIng inputs gen.varyIn = varyIn // structs used gen.structs = {} // outputs used gen.outputs = {} // functions generated gen.genFunctions = [] // the function object info of the current function var source = fn.toString() if(source.indexOf('function') !== 0){ source = 'function ' + source } gen.curFunction = { deps:{}, inout:{}, scope:{}, callee:fn, source:source } // textures used gen.textures = {} // do our indentation gen.indent = '\t' gen.root = root gen.ctxprefix = '' gen.context = root var ast = parsecache[source] || (parsecache[source] = parser.parse(source)) if(mapexception){ // very ugly. try{ gen.main = gen.block(ast.body[0].body.body) } catch(error){ gen.mapException(error) } } else{ gen.main = gen.block(ast.body[0].body.body) } return gen }
//Identifier:{name:0}, Identifier(node){ var name = node.name if(name === '$' || name === '_$') return '' // cant use $ in shaders so just return the value directly if(name.indexOf('$') === 0) return name // first we check the scope var scopeinfer = this.curFunction.scope[name] if(scopeinfer){ node.infer = scopeinfer return name } // native functions var glslfn = this.glslfunctions[name] if(glslfn){ node.infer = { kind: 'function', glsl: name, callee: glslfn } return name } // native functions var glslvar = this.glslvariables[name] if(glslvar){ node.infer = { kind: 'value', lvalue:true, type:glslvar, glsl: name } return name } // then we check the native types var glsltype = this.glsltypes[name] if(glsltype){ node.infer = { kind: 'type', type: glsltype } return name } if(name === 'base'){ // lets find the current function on the protochain var fn = this.curFunction var proto = this.root var basecallee while(proto){ if(proto.hasOwnProperty(fn.name) && proto[fn.name] === fn.callee){ // found it! proto = Object.getPrototypeOf(proto) basecallee = proto[fn.name] break } proto = Object.getPrototypeOf(proto) } var ret = 'base_'+fn.fullname node.infer = { kind:'function', fullname:ret, callee:basecallee, } return ret } // check defines var defstr = this.context !== this.root && this.context.defines && this.context.defines[name] || this.root._defines && this.root._defines[name] if(defstr){ // expand the define try{ var ast = parsecache[defstr] || (parsecache[defstr] = parser.parse(defstr)) } catch(e){ throw this.SyntaxErr(node, "Cant parse define " + defstr) } // just jump to it var astnode = ast.body[0] var ret = this[astnode.type](astnode)//.walk(astnode) node.infer = astnode.infer return ret } // struct on context var structtype = this.context !== this.root && this.context._structs && this.context._structs[name] if(structtype){ // return struct node.infer = { kind: 'type', type: structtype } this.structs[name] = structtype return name } // struct on root structtype = this.root._structs && this.root._structs[name] if(structtype){ // return struct node.infer = { kind: 'type', type: structtype } this.structs[name] = structtype return name } // requires on context var required = this.context !== this.root && this.context._requires && this.context._requires[name] if(required){ // return struct node.infer = { kind: 'require', require: required } return this.ctxprefix + name } // requires on root required = this.root._requires && this.root._requires[name] if(structtype){ // return struct node.infer = { kind: 'require', require: required } return name } // otherwise type it throw this.ResolveErr(node, 'Cannot resolve '+name) }