コード例 #1
0
		set:function(props){
			if(!this.hasOwnProperty('_props')){
				this._props = this._props?Object.create(this._props):{}
			}
			for(var key in props){
				var config = props[key]
				if(typeof config !== 'object' || Object.getPrototypeOf(config) !== Object.prototype){
					config = {value:config}
				}
				this._props[key] = config
				if(config.value !== undefined) this[key] = config.value
				if(!config.type) config.type = types.typeFromValue(config.value)
				if(!config.kind) config.kind = 'instance'
			}
		}
コード例 #2
0
	proto.MemberExpression = function(node){
		// just chuck This
		//if(node.object.type === 'ThisExpression' || node.object.type === 'Identifier' && ignore_objects[node.object.name]){
		//	var ret = this.walk(node.property)
		//	node.infer = node.property.infer
		//	return ret
		//}

		var objectstr = this.walk(node.object, node)

		if(node.computed){
			var objinfer = node.object.infer
			if(objinfer.kind !== 'value'){
				console.log(objinfer)
				throw this.InferErr(node, 'cannot use index[] on non value type')
			}
			var objtype = objinfer.type
			if(objtype.slots <= 1){
				throw this.InferErr(node, 'cannot use index[] on item with size 1')
			}
			var argstr = this.walk(node.property, node)

			var primtype = objtype.primary
	
			if(objtype.name === 'mat4'){
				primtype = types.vec4
			}
			else if(objtype.name === 'mat3'){
				primtype = types.vec3
			}
			else if(objtype.name === 'mat2'){
				primtype = types.vec2
			}

			node.infer = {
				kind:'value',
				type:primtype
			}
			return objectstr + '[' + argstr + ']'
		}
		else{
			var objectinfer = node.object.infer
			var propname = node.property.name
			if(objectinfer.kind === 'value'){
				var type = objectinfer.type
				if(!type.fields){
					throw this.InferErr(node, 'Object not a struct '+objectstr+'.'+propname)
				}
				var proptype = type.fields[propname]
				if(!proptype){ // do more complicated bits
					// check swizzling or aliases
					var proplen = propname.length
					if(proplen < 1 || proplen > 4) throw this.InferErr(node, 'Invalid property '+objectstr+'.'+propname)
					var typename = type.name

					proptype = types[proplen === 1? swizone[typename]: (swiztype[typename] + proplen)]

					var swiz = swizlut[typename]
					if(!swiz) throw this.InferErr(node, 'Invalid swizzle '+objectstr+'.'+propname)
					for(var i = 0, set = swiz.set[swiz.pick[propname.charCodeAt(0)]]; i < proplen; i++){
						if(!set || !set[propname.charCodeAt(i)]) throw this.InferErr(node, 'Invalid swizzle '+objectstr+'.'+propname)
					}
				}
				// look up property propname
				node.infer = {
					kind:'value',
					lvalue:objectinfer.lvalue, // propagate lvalue-ness
					type:proptype
				}
				return objectstr + '.' + propname
			}
			else if(objectinfer.kind === 'this'){

				var value = this.root[propname]
				var fullname = 'this_DOT_' + propname

				// its a function
				if(typeof value === 'function'){
					node.infer = {
						kind: 'function',
						name: propname,
						fullname: fullname,
						callee: value
					}
					return fullname
				}

				var props = this.root._props
				var config = props[propname]

				if(config !== undefined ){
					// we found a prop!
					// check kind
					if(config.kind === 'instance'){

						var value = config.value

						this.instanceProps[fullname] = {
							type:config.type,
							name:propname,
							config:config
						}

						node.infer = {
							kind:'value',
							lvalue:true,
							type:config.type
						}

						return fullname
					}
					else if(config.kind === 'uniform'){
						if(this.uniforms[fullname]){
							this.uniforms[fullname].refcount++
						}
						else{
							this.uniforms[fullname] = {
								type:config.type,
								config:config,
								name:propname,
								refcount:1
							}
						}
						node.infer = {
							kind:'value',
							type:config.type
						}
						return fullname
					}
					else if(config.kind === 'sampler'){
						var sampler = config.sampler
						this.samplers[fullname] = {
							name:propname,
							sampler:sampler
						}
						node.infer = {
							kind:'value',
							name:propname,
							sampler:sampler,
							type:sampler.type
						}
						return fullname
					}
					else if(config.kind === 'geometry'){
						proptype = config.type
						this.geometryProps[fullname] = {
							type:proptype,
							name:propname
						}

						node.infer = {
							kind:'value',
							lvalue:true,
							type:proptype
						}
						return fullname
					}
					else if(config.kind === 'output'){
						// its already defined
						var type = config.type
						if(prev){
							node.infer = {
								kind: 'value',
								lvalue:true,
								type: prev
							}
						}
						else{
							node.infer = {
								kind: 'outundef',
								lvalue:true,
								name: name
							}
						}
						return fullname
					}
				}

				// use of unconfigured sampler
				if(value instanceof painter.Texture){
					this.samplers[fullname] = {
						name:ret,
						sampler:sampler
					}
					var sampler = value.sampler || painter.SAMPLER2DNEAREST
					node.infer = {
						kind:'value',
						name:ret,
						sampler:sampler,
						type:sampler.type
					}
					return fullname
				}

				// check if its a mesh attribute
				if(value instanceof painter.Mesh){

					proptype = value.type
					this.geometryProps[fullname] = {
						type:proptype,
						name:propname
					}

					node.infer = {
						kind:'value',
						lvalue:true,
						type:proptype
					}
					return fullname
				}

				if(value === undefined){ // something undefined
					// its already defined
					var prev = this.varyOut[fullname] || this.varyIn && this.varyIn[fullname]

					if(prev){
						this.varyOut[fullname] = prev
						node.infer = {
							kind: 'value',
							lvalue:true,
							type: prev.type
						}
					}
					else{
						if(this.varyIn){
							var out = this.outputs[fullname]
							if(out){
								node.infer = {
									kind: 'value',
									lvalue:true,
									type:out
								}
							}
							else{
								node.infer = {
									kind: 'outundef',
									lvalue:true,
									name: propname
								}
							}
						}
						else{
							node.infer = {
								kind: 'varyundef',
								lvalue:true,
								name: propname
							}
						}
					}
					// lets check if node.infer holds property
					return fullname
				}

				// default to instanced property
				var type = types.typeFromValue(value)

				if(type){
					this.instanceProps[fullname] = {
						type:type,
						name:propname,
						config:{type:type}
					}

					node.infer = {
						kind:'value',
						lvalue:true,
						type:type
					}

					return fullname
				}

			}

			throw this.InferErr(node, 'Cant determine type for this.'+propname)
		}
	}