void CompileMetaPropertyDefinitions(AstMetaProperty ast, MetaProperty mp) { var defs = new MetaDefinition[ast.Definitions.Count]; for (int i = 0; i < defs.Length; i++) { var fc = new FunctionCompiler(_compiler, mp); foreach (var req in ast.Definitions[i].Requirements) { DataType dt = null; if (req.Type != null) { dt = _resolver.GetType(mp.Parent, req.Type); } fc.AddReqStatement(new ReqProperty(req.Source, req.Name.Symbol, dt, req.Offset, req.Tag)); } var fixedInit = ast.Definitions[i].Value as AstFixedArrayInitializer; Statement s; if (fixedInit != null) { s = fc.CompileFixedArrayDeclaration(mp.Source, mp.ReturnType, mp.Name, fixedInit); } else { s = fc.CompileStatement(ast.Definitions[i].Value); if (s is Expression) { s = fc.CompileImplicitCast(mp.Source, mp.ReturnType, s as Expression); } } // Find implicit req statements if (s is Expression) { var e = s as Expression; new ReqStatementFinder(fc).VisitNullable(ref e); } else { new ReqStatementFinder(fc).VisitNullable(ref s); } defs[i] = new MetaDefinition(s, ast.Definitions[i].Tags, fc.ReqStatements); } mp.SetDefinitions(defs); }
public Expression SetProperty(Source src, DataType dt, Expression obj, string property, Expression value) { var fc = new FunctionCompiler(_compiler, dt, obj); foreach (var m in dt.Properties) { if (m.UnoName == property && m.SetMethod != null) { return(new SetProperty(src, obj, m, fc.CompileImplicitCast(src, m.ReturnType, value))); } } Log.Error(src, ErrorCode.E0000, "No matching property: '" + dt + "." + property + ".set'"); return(Expression.Invalid); }
public void Generate() { // Verify and add path to meta property cache for (int i = 0; i < Path.Nodes.Length; i++) { for (int j = Path.Nodes[i].Top; j <= Path.Nodes[i].Bottom; j++) { var mp = (MetaProperty)Path.Nodes[i].Block.Members[j]; var loc = new MetaLocation(i, j); MetaLocation ploc; if (MetaProperties.TryGetValue(mp.Name, out ploc)) { var pmp = GetProperty(ploc); // TODO: This is not correct if (!pmp.ReturnType.Equals(mp.ReturnType)) { Log.Error(mp.Source, ErrorCode.E5000, mp.Name.Quote() + " does not have the same type as the previous declaration at " + pmp.Source + " when exposed from " + Path.Quote() + " at " + Path.Source); } PrevProperties.Add(loc, ploc); } MetaProperties[mp.Name] = loc; } } // Resolve terminal properties foreach (var tp in Backend.ShaderBackend.OutputProperties) { MetaLocation loc; if (!MetaProperties.TryGetValue(tp.Name, out loc)) { Log.Error(Path.Source, ErrorCode.I5001, "Terminal property " + tp.Name.Quote() + " was not found in " + Path.Quote()); continue; } var mp = GetProperty(loc); var dt = ILFactory.GetType(Path.Source, tp.TypeString); if (!mp.ReturnType.Equals(dt)) { Log.Error(Path.Source, ErrorCode.I5001, "Terminal property " + tp.Name.Quote() + " was found with type " + mp.ReturnType.Quote() + " when " + dt.Quote() + " was expected"); continue; } var sym = ProcessMetaProperty(loc, tp.Required); if (sym.Value == null) { continue; } LocationStack.Add(loc); switch (tp.Stage) { case MetaStage.Vertex: sym = ProcessStage(sym, MetaStage.Vertex, MetaStage.Vertex); DrawState.VertexShader.Terminals[tp.Name] = sym.Value; break; case MetaStage.Pixel: sym = ProcessStage(sym, MetaStage.Pixel, MetaStage.Pixel); DrawState.PixelShader.Terminals[tp.Name] = sym.Value; break; default: sym = ProcessStage(sym, MetaStage.Volatile, MetaStage.Volatile); DrawState.Terminals[tp.Name] = sym.Value; break; } LocationStack.RemoveLast(); } if (!DrawState.Terminals.ContainsKey("VertexCount")) { var loc = MetaProperties["VertexCount"]; var mp = GetProperty(loc); if (DetectedVertexCounts.Count == 1) { LocationStack.Add(loc); var fc = new FunctionCompiler(Compiler, IL); DrawState.Terminals["VertexCount"] = fc.CompileImplicitCast(DetectedVertexCounts[0].Value.Source, mp.ReturnType, ProcessStage(DetectedVertexCounts[0], MetaStage.Volatile, MetaStage.Volatile).Value); LocationStack.RemoveLast(); } else { Log.Error(CreateTrace(mp, loc, null), ErrorCode.E5002, "Unable to auto detect 'VertexCount' in " + Path.Quote()); } } MetaPropertyEmitter.Emit(this); ShaderProcessor.ProcessShader(this, DrawState.VertexShader); ShaderProcessor.ProcessShader(this, DrawState.PixelShader); ProcessStructs(); var p = new IndirectionTransform(Compiler.Pass); DrawState.VertexShader.Visit(p); DrawState.PixelShader.Visit(p); }