private void Shift(int stateIndex) { #if TRACE_ACTIONS Console.Error.Write("Shifting token {0}, ", TerminalToString(NextToken)); #endif FsaState = states[stateIndex]; valueStack.Push(scanner.yylval); StateStack.Push(FsaState); LocationStack.Push(scanner.yylloc); if (recovering) { if (NextToken != errorToken) { tokensSinceLastError++; } if (tokensSinceLastError > 5) { recovering = false; } } if (NextToken != endOfFileToken) { NextToken = 0; } }
/// <summary> /// Find error recovery state. /// </summary> /// <returns>result.</returns> private bool FindErrorRecoveryState() { while (true) // pop states until one found that accepts error token { if (FsaState.ParserTable != null && FsaState.ParserTable.ContainsKey(errorToken) && FsaState.ParserTable[errorToken] > 0) // shift { return(true); } StateStack.Pop(); ValueStack.Pop(); LocationStack.Pop(); if (StateStack.IsEmpty()) { return(false); } else { FsaState = StateStack.TopElement(); } } }
/// <summary> /// Shift. /// </summary> /// <param name="stateIndex">state index.</param> private void Shift(int stateIndex) { FsaState = states[stateIndex]; ValueStack.Push(Scanner.yylval); StateStack.Push(FsaState); LocationStack.Push(Scanner.yylloc); if (recovering) { if (NextToken != errorToken) { tokensSinceLastError++; } if (tokensSinceLastError > 5) { recovering = false; } } if (NextToken != endOfFileToken) { NextToken = 0; } }
private void Reduce(int ruleNumber) { #if TRACE_ACTIONS DisplayRule(ruleNumber); #endif Rule rule = rules[ruleNumber]; // // Default actions for unit productions. // if (rule.RightHandSide.Length == 1) { CurrentSemanticValue = valueStack.TopElement(); // Default action: $$ = $1; CurrentLocationSpan = LocationStack.TopElement(); // Default action "@$ = @1; } else { if (rule.RightHandSide.Length == 0) { // Create a new blank value. // Explicit semantic action may mutate this value CurrentSemanticValue = default(TValue); // The location span for an empty production will start with the // beginning of the next lexeme, and end with the finish of the // previous lexeme. This gives the correct behaviour when this // nonsense value is used in later Merge operations. CurrentLocationSpan = (scanner.yylloc != null && LastSpan != null ? scanner.yylloc.Merge(LastSpan) : default(TSpan)); } else { // Default action: $$ = $1; CurrentSemanticValue = valueStack.TopElement(); // Default action "@$ = @1.Merge(@N)" for location info. TSpan at1 = LocationStack[LocationStack.Depth - rule.RightHandSide.Length]; TSpan atN = LocationStack[LocationStack.Depth - 1]; CurrentLocationSpan = ((at1 != null && atN != null) ? at1.Merge(atN) : default(TSpan)); } } DoAction(ruleNumber); for (int i = 0; i < rule.RightHandSide.Length; i++) { StateStack.Pop(); valueStack.Pop(); LocationStack.Pop(); } FsaState = StateStack.TopElement(); if (FsaState.Goto.ContainsKey(rule.LeftHandSide)) { FsaState = states[FsaState.Goto[rule.LeftHandSide]]; } StateStack.Push(FsaState); valueStack.Push(CurrentSemanticValue); LocationStack.Push(CurrentLocationSpan); }
StageValue ProcessVertexAttrib(NewVertexAttrib s) { var vertexAttributeType = ProcessValue(s.VertexAttributeType); var vertexBuffer = ProcessValue(s.VertexBuffer); var vertexOffset = ProcessValue(s.VertexBufferOffset); var vertexStride = ProcessValue(s.VertexBufferStride); var indexType = ProcessValue(s.OptionalIndexType); var indexBuffer = ProcessValue(s.OptionalIndexBuffer); var loc = LocationStack.Last(); var mp = GetProperty(loc); var name = CreateShaderName(mp, loc); int attrIndex = DrawState.VertexAttributes.Count; DetectVertexCount(indexBuffer.Value != null ? indexBuffer : vertexBuffer); ProcessIndexBuffer(s.Source, indexBuffer, indexType); DrawState.VertexAttributes.Add(new VertexAttribute(s.ReturnType, name, ProcessStage(vertexAttributeType, MetaStage.Volatile, MetaStage.Volatile).Value, ProcessVertexBuffer(vertexBuffer), ProcessStage(vertexOffset, MetaStage.Volatile, MetaStage.Volatile).Value, ProcessStage(vertexStride, MetaStage.Volatile, MetaStage.Volatile).Value)); return(new StageValue(new LoadVertexAttrib(s.Source, DrawState, attrIndex), MetaStage.Vertex, MetaStage.Vertex)); }
private bool FindErrorRecoveryState() { while (true) // pop states until one found that accepts error token { if (FsaState.ParserTable != null && FsaState.ParserTable.ContainsKey(errorToken) && FsaState.ParserTable[errorToken] > 0) // shift { return(true); } #if TRACE_ACTIONS Console.Error.WriteLine("Error: popping state {0}", StateStack.TopElement().number); #endif StateStack.Pop(); valueStack.Pop(); LocationStack.Pop(); #if TRACE_ACTIONS DisplayStack(); #endif if (StateStack.IsEmpty()) { #if TRACE_ACTIONS Console.Error.WriteLine("Aborting: didn't find a state that accepts error token"); #endif return(false); } else { FsaState = StateStack.TopElement(); } } }
Expression ProcessVertexBuffer(StageValue vertexBuffer) { Expression result; if (!VertexBuffers.TryGetValue(vertexBuffer.Value.ToString(), out result)) { var src = vertexBuffer.Value.Source; var type = ILFactory.GetType(src, "Uno.Graphics.VertexBuffer"); if (vertexBuffer.Value.ReturnType.Equals(type)) { result = ProcessStage(vertexBuffer, MetaStage.Volatile, MetaStage.Volatile).Value; VertexBuffers.Add(vertexBuffer.Value.ToString(), result); return(result); } var loc = LocationStack.Last(); var mp = GetProperty(loc); var name = CreateFieldName(mp, loc); var owner = Path.DrawBlock.Method.DeclaringType; var field = new Field(src, owner, name, null, Modifiers.Private | Modifiers.Generated, 0, type); owner.Fields.Add(field); result = new LoadField(src, new This(src, owner), field); VertexBuffers.Add(vertexBuffer.Value.ToString(), result); if (vertexBuffer.MinStage > MetaStage.Volatile) { Log.Error(src, ErrorCode.E5025, "Vertex buffer cannot be accessed from " + vertexBuffer.MinStage + " stage"); return(result); } else if (vertexBuffer.MinStage == MetaStage.Volatile) { InitScope.Statements.Add( new StoreField(src, new This(src, owner), field, ILFactory.NewObject(src, "Uno.Graphics.VertexBuffer", ILFactory.GetExpression(src, "Uno.Graphics.BufferUsage.Dynamic")))); FrameScope.Statements.Add( ILFactory.CallMethod(src, new LoadField(src, new This(src, owner), field), "Update", vertexBuffer.Value)); } else { InitScope.Statements.Add( new StoreField(src, new This(src, owner), field, ILFactory.NewObject(src, "Uno.Graphics.VertexBuffer", vertexBuffer.Value, ILFactory.GetExpression(src, "Uno.Graphics.BufferUsage.Immutable")))); } FreeScope.Statements.Add( ILFactory.CallMethod(src, new LoadField(src, new This(src, owner), field), "Dispose")); } return(result); }
private void CurrentLocationTapped(object sender, EventArgs e) { if (!_isNearByExpanded) { return; } var pageHeight = Height; var isLocationLabelVisible = LblLocation.IsVisible; var recentLocationStackSize = RecentLocationStack.Measure(double.PositiveInfinity, double.PositiveInfinity); var currentAndRecentLocationSize = CurrentAndRecentLocationStack.Measure(double.PositiveInfinity, double.PositiveInfinity); var suggestionHeight = LocationSuggestionStack.Measure(double.PositiveInfinity, double.PositiveInfinity); var suggestionMinHeight = Height * 0.28; var heighToBeSet = Math.Max(suggestionMinHeight, suggestionHeight.Request.Height); LocationSuggestionStack.HeightRequest = heighToBeSet; var locationStackSize = LocationStack.Measure(double.PositiveInfinity, double.PositiveInfinity); var locationStackHeight = Math.Max(currentAndRecentLocationSize.Request.Height + heighToBeSet + 90, locationStackSize.Request.Height); FrNearBy.TranslateTo(0, pageHeight - ((pageHeight * _topPosition) + (isLocationLabelVisible ? 71 : 0)), AppThemeConstants.AnimationSpeed, Easing.SinInOut); Thickness bottomGridMargin = BottomContainerGrid.Margin; bottomGridMargin.Bottom += isLocationLabelVisible ? -71 : 71; BottomContainerGrid.Margin = bottomGridMargin; System.Diagnostics.Debug.WriteLine($"Location Stack Height : {locationStackHeight}, {isLocationLabelVisible}"); if (isLocationLabelVisible) { LblLocation.TranslateTo(-80, 30, AppThemeConstants.AnimationSpeed, Easing.SinInOut); LblLocationSymbol.TranslateTo(-80, 30, AppThemeConstants.AnimationSpeed, Easing.SinInOut); SvBottomContainer.TranslateTo(0, locationStackHeight, AppThemeConstants.AnimationSpeed, Easing.SinInOut); LblLocation.IsVisible = false; LocationStack.Animate("ShowLocationStack", (x) => { LocationStack.HeightRequest = locationStackHeight * x; }); LocationWithZipCodeStack.TranslateTo(0, 0, AppThemeConstants.AnimationSpeed, Easing.SinInOut); } else { LocationWithZipCodeStack.TranslateTo(80, -30, AppThemeConstants.AnimationSpeed, Easing.SinInOut); SvBottomContainer.TranslateTo(0, 0, AppThemeConstants.AnimationSpeed, Easing.SinInOut); LocationStack.Animate("HideLocationStack", (x) => { LocationStack.HeightRequest = locationStackHeight * (1 - x); }, finished: (x, y) => { System.Diagnostics.Debug.WriteLine($"Finished callback : {x}, {y}"); LblLocation.IsVisible = true; }); LblLocationSymbol.TranslateTo(0, 0, AppThemeConstants.AnimationSpeed, Easing.SinInOut); LblLocation.TranslateTo(0, 0, AppThemeConstants.AnimationSpeed, Easing.SinInOut); } }
private void Reduce(int ruleNumber) { #if TRACE_ACTIONS DisplayRule(ruleNumber); #endif Rule rule = rules[ruleNumber]; if (rule.RightHandSide.Length == 1) { CurrentSemanticValue = valueStack.TopElement(); CurrentLocationSpan = LocationStack.TopElement(); } else { if (rule.RightHandSide.Length == 0) { CurrentSemanticValue = default(TValue); CurrentLocationSpan = (scanner.yylloc != null && LastSpan != null ? scanner.yylloc.Merge(LastSpan) : default(TSpan)); } else { CurrentSemanticValue = valueStack.TopElement(); TSpan at1 = LocationStack[LocationStack.Depth - rule.RightHandSide.Length]; TSpan atN = LocationStack[LocationStack.Depth - 1]; CurrentLocationSpan = ((at1 != null && atN != null) ? at1.Merge(atN) : default(TSpan)); } } DoAction(ruleNumber); for (int i = 0; i < rule.RightHandSide.Length; i++) { StateStack.Pop(); valueStack.Pop(); LocationStack.Pop(); } #if TRACE_ACTIONS DisplayStack(); #endif FsaState = StateStack.TopElement(); if (FsaState.Goto.ContainsKey(rule.LeftHandSide)) { FsaState = states[FsaState.Goto[rule.LeftHandSide]]; } StateStack.Push(FsaState); valueStack.Push(CurrentSemanticValue); LocationStack.Push(CurrentLocationSpan); }
internal StageValue ProcessStage(StageValue sym, MetaStage min, MetaStage max) { var loc = LocationStack.Last(); var mp = GetProperty(loc); if (max < sym.MinStage) { Log.Error(sym.Value.Source, ErrorCode.E5015, sym.MinStage.ToLiteral().Quote() + " cannot be accessed from stage " + max.ToLiteral().Quote() + " while processing " + mp.Name.Quote() + " at " + mp.Source + " in " + Path.Quote() + " at " + Path.Source); return(new StageValue(Expression.Invalid, MetaStage.Const)); } // Handle stage change if necessary or default to lowest possible stage if (min > sym.MaxStage || min > sym.MinStage && sym.Value != null && !InlineOnStage(min, sym.Value)) { return(ProcessStageChange(sym, sym.MinStage, min, loc, mp)); } return(sym); }
StageValue ProcessPixelSampler(NewPixelSampler s) { var texture = ProcessValuesToStage(MetaStage.Volatile, s.Texture); int index; if (!PixelSamplers.TryGetValue(texture.ToString(), out index)) { var loc = LocationStack.Last(); var mp = GetProperty(loc); index = DrawState.PixelSamplers.Count; DrawState.PixelSamplers.Add(new PixelSampler(GetSamplerType(s.Source, texture.ReturnType), CreateShaderName(mp, loc, texture), texture)); PixelSamplers.Add(texture.ToString(), index); if (s.OptionalState != null) { DrawState.PixelSamplers[index].OptionalState = ProcessValuesToStage(MetaStage.Volatile, s.OptionalState); } } else { var oldState = DrawState.PixelSamplers[index].OptionalState; var newState = s.OptionalState != null ? ProcessValuesToStage(MetaStage.Volatile, s.OptionalState) : null; if (oldState == null && newState != null || oldState != null && newState == null || oldState != null && !oldState.IsInvalid && newState != null && !newState.IsInvalid && oldState.ToString() != newState.ToString()) { Log.Warning(s.Source, ErrorCode.W0000, "Ignoring sampler state. Texture is already sampled using a different sampler state in " + Path.Quote() + ". Reuse the existing sampler state to remove this warning."); } } return(new StageValue(new LoadPixelSampler(s.Source, DrawState, index), MetaStage.Pixel, MetaStage.Pixel)); }
/// <summary> /// Main entry point of the Shift-Reduce Parser. /// </summary> /// <returns>True if parse succeeds, else false for /// unrecoverable errors</returns> public bool Parse() { Initialize(); // allow derived classes to instantiate rules, states and nonTerminals NextToken = 0; FsaState = states[0]; StateStack.Push(FsaState); valueStack.Push(CurrentSemanticValue); LocationStack.Push(CurrentLocationSpan); while (true) { #if TRACE_ACTIONS Console.Error.WriteLine("Entering state {0} ", FsaState.number); DisplayStack(); #endif int action = FsaState.defaultAction; if (FsaState.ParserTable != null) { if (NextToken == 0) { // We save the last token span, so that the location span // of production right hand sides that begin or end with a // nullable production will be correct. LastSpan = scanner.yylloc; NextToken = scanner.yylex(); #if TRACE_ACTIONS Console.Error.WriteLine("Reading: Next token is {0}", TerminalToString(NextToken)); #endif } #if TRACE_ACTIONS else { Console.Error.WriteLine("Next token is still {0}", TerminalToString(NextToken)); } #endif if (FsaState.ParserTable.ContainsKey(NextToken)) { action = FsaState.ParserTable[NextToken]; } } if (action > 0) // shift { Shift(action); } else if (action < 0) // reduce { try { Reduce(-action); if (action == -1) // accept { return(true); } } catch (AbortException) { return(false); } catch (AcceptException) { return(true); } catch (ErrorException) { if (!ErrorRecovery()) { return(false); } else { throw; // Rethrow x, preserving information. } } } else if (action == 0 && !ErrorRecovery()) // error { return(false); } } }
/// <summary> /// Reduce. /// </summary> /// <param name="ruleNumber">The rule to reduce by.</param> private void Reduce(int ruleNumber) { Rule rule = rules[ruleNumber]; // // Default actions for unit productions. // if (rule.RightHandSide.Length == 1) { CurrentSemanticValue = ValueStack.TopElement(); // Default action: $$ = $1; CurrentLocationSpan = LocationStack.TopElement(); // Default action "@$ = @1; } else { if (rule.RightHandSide.Length == 0) { // Create a new blank value. // Explicit semantic action may mutate this value CurrentSemanticValue = default(TValue); // The location span for an empty production will start with the // beginning of the next lexeme, and end with the finish of the // previous lexeme. This gives the correct behaviour when this // nonsense value is used in later Merge operations. CurrentLocationSpan = (Scanner.yylloc != null && LastSpan != null ? Scanner.yylloc.Merge(LastSpan) : default(TSpan)); } else { // Default action: $$ = $1; CurrentSemanticValue = ValueStack.TopElement(); // Default action "@$ = @1.Merge(@N)" for location info. TSpan at1 = LocationStack[LocationStack.Depth - rule.RightHandSide.Length]; TSpan atN = LocationStack[LocationStack.Depth - 1]; CurrentLocationSpan = ((at1 != null && atN != null) ? at1.Merge(atN) : default(TSpan)); } } DoAction(ruleNumber); for (int i = rule.RightHandSide.Length - 1; i >= 0; i--) { _valueParameterList[i] = ValueStack.Pop(); // capture the values - added by Nate Wallace StateStack.Pop(); LocationStack.Pop(); } if (!_errorOccured) { ProcessReduce(rule.LeftHandSide, _valueParameterList, rule.RightHandSide.Length); // process the reduce action - added by Nate Wallace } else { _errorOccured = false; } FsaState = StateStack.TopElement(); if (FsaState.Goto.ContainsKey(rule.LeftHandSide)) { FsaState = states[FsaState.Goto[rule.LeftHandSide]]; } StateStack.Push(FsaState); ValueStack.Push(CurrentSemanticValue); LocationStack.Push(CurrentLocationSpan); }
/// <summary> /// Main entry point of the Shift-Reduce Parser. /// </summary> /// <returns>True if parse succeeds, else false for /// unrecoverable errors</returns> public bool Parse() { _valueParameterList = new TValue[15]; // added Nate Wallace _errorOccured = false; Initialize(); // allow derived classes to instantiate rules, states and nonTerminals NextToken = 0; FsaState = states[0]; StateStack.Push(FsaState); ValueStack.Push(CurrentSemanticValue); LocationStack.Push(CurrentLocationSpan); while (true) { int action = FsaState.defaultAction; if (FsaState.ParserTable != null) { if (NextToken == 0) { // We save the last token span, so that the location span // of production right hand sides that begin or end with a // nullable production will be correct. LastSpan = Scanner.yylloc; NextToken = Scanner.yylex(); } if (FsaState.ParserTable.ContainsKey(NextToken)) { action = FsaState.ParserTable[NextToken]; } } if (action > 0) // shift { Shift(action); } else if (action < 0) // reduce { try { Reduce(-action); if (action == -1) // accept { return(true); } } catch (Exception x) { if (x is AbortException) { return(false); } else if (x is AcceptException) { return(true); } else if (x is ErrorException && !ErrorRecovery()) { return(false); } else { throw; // Rethrow x, preserving information. } } } else if (action == 0) // error { _tokenOnError = NextToken; _locationOnError = Scanner.yylloc; if (!ErrorRecovery()) { return(false); } } } }
void ProcessIndexBuffer(Source vaSrc, StageValue indexBuffer, StageValue indexType) { if (IndexBuffer == null && indexBuffer.Value == null && IndexType == null && indexType.Value == null || indexBuffer.Value != null && IndexBuffer == indexBuffer.Value.ToString() && indexType.Value != null && IndexType == indexType.Value.ToString()) { // OK return; } if (IndexBuffer != null || indexBuffer.Value == null || IndexType != null || indexType.Value == null) { Log.Error(vaSrc, ErrorCode.E5023, "Index buffer argument must be consistent for all <vertex_attrib>s in " + Path.Quote()); return; } var src = indexBuffer.Value.Source; var type = ILFactory.GetType(src, "Uno.Graphics.IndexBuffer"); IndexBuffer = indexBuffer.Value.ToString(); IndexType = indexType.Value.ToString(); if (indexBuffer.Value.ReturnType.Equals(type)) { DrawState.OptionalIndices = new IndexBinding( ProcessStage(indexType, MetaStage.Volatile, MetaStage.Volatile).Value, ProcessStage(indexBuffer, MetaStage.Volatile, MetaStage.Volatile).Value); return; } var loc = LocationStack.Last(); var mp = GetProperty(loc); var name = CreateFieldName(mp, loc); var owner = Path.DrawBlock.Method.DeclaringType; var field = new Field(src, owner, name, null, Modifiers.Private | Modifiers.Generated, 0, type); owner.Fields.Add(field); DrawState.OptionalIndices = new IndexBinding( ProcessStage(indexType, MetaStage.Volatile, MetaStage.Volatile).Value, new LoadField(src, new This(src, owner), field)); if (indexBuffer.MinStage > MetaStage.Volatile) { Log.Error(src, ErrorCode.E5024, "Index buffer cannot be accessed from " + indexBuffer.MinStage + " stage"); return; } if (indexBuffer.MinStage == MetaStage.Volatile) { InitScope.Statements.Add( new StoreField(src, new This(src, owner), field, ILFactory.NewObject(src, "Uno.Graphics.IndexBuffer", ILFactory.GetExpression(src, "Uno.Graphics.BufferUsage.Dynamic")))); FrameScope.Statements.Add( ILFactory.CallMethod(src, new LoadField(src, new This(src, owner), field), "Update", indexBuffer.Value)); } else { InitScope.Statements.Add( new StoreField(src, new This(src, owner), field, ILFactory.NewObject(src, "Uno.Graphics.IndexBuffer", indexBuffer.Value, ILFactory.GetExpression(src, "Uno.Graphics.BufferUsage.Immutable")))); } FreeScope.Statements.Add( ILFactory.CallMethod(src, new LoadField(src, new This(src, owner), field), "Dispose")); }
public bool Parse() { Initialize(); NextToken = 0; FsaState = states[0]; StateStack.Push(FsaState); valueStack.Push(CurrentSemanticValue); LocationStack.Push(CurrentLocationSpan); while (true) { #if TRACE_ACTIONS Console.Error.WriteLine("Entering state {0} ", FsaState.number); #endif int action = FsaState.defaultAction; if (FsaState.ParserTable != null) { if (NextToken == 0) { #if TRACE_ACTIONS Console.Error.Write("Reading a token: "); #endif LastSpan = scanner.yylloc; NextToken = scanner.yylex(); } #if TRACE_ACTIONS Console.Error.WriteLine("Next token is {0}", TerminalToString(NextToken)); #endif if (FsaState.ParserTable.ContainsKey(NextToken)) { action = FsaState.ParserTable[NextToken]; } } if (action > 0) { Shift(action); } else if (action < 0) { try { Reduce(-action); if (action == -1) { return(true); } } catch (Exception x) { if (x is AbortException) { return(false); } else if (x is AcceptException) { return(true); } else if (x is ErrorException && !ErrorRecovery()) { return(false); } else { throw; } } } else if (action == 0) { if (!ErrorRecovery()) { return(false); } } } }
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); }
internal StageValue ProcessValue(Expression e) { if (e == null) { return(new StageValue(null, MetaStage.Const)); } switch (e.ExpressionType) { case ExpressionType.StageOp: { var s = e as StageOp; var op = ProcessValue(s.Operand); if (s.Stage > MetaStage.Volatile) { op = ProcessStage(op, s.Stage, s.Stage); } else if (op.MinStage > MetaStage.Volatile) { Log.Error(s.Operand.Source, ErrorCode.E0000, "Invalid " + s.Stage.ToLiteral() + " expression in " + Path.Quote()); return(new StageValue(Expression.Invalid, s.Stage, s.Stage)); } op.MinStage = s.Stage; return(op); } case ExpressionType.NewVertexAttrib: return(ProcessVertexAttrib(e as NewVertexAttrib)); case ExpressionType.NewPixelSampler: return(ProcessPixelSampler(e as NewPixelSampler)); case ExpressionType.GetMetaProperty: { var s = e as GetMetaProperty; var loc = TryGetLocation(LocationStack.Last(), s.Name, s.Offset); if (loc == null) { if (s.Offset == 0) { Log.Error(s.Source, ErrorCode.E5019, s.Name.Quote() + " was not found in " + Path.Quote()); } else { Log.Error(s.Source, ErrorCode.E5020, "Previous declaration of " + s.Name.Quote() + " was not found in " + Path.Quote()); } return(new StageValue(Expression.Invalid, MetaStage.Const)); } return(ProcessMetaProperty(loc.Value)); } case ExpressionType.GetMetaObject: { var s = e as GetMetaObject; var obj = TryGetObject(LocationStack.Last()); if (obj == null || !obj.ReturnType.IsSubclassOfOrEqual(s.ReturnType)) { Log.Error(s.Source, ErrorCode.E0000, "Unable to resolve instance of " + s.ReturnType.Quote() + " in " + Path.Quote()); } var objStage = ProcessValue(obj); return(new StageValue(objStage.Value, objStage.MinStage, objStage.MaxStage)); } case ExpressionType.Invalid: case ExpressionType.Constant: case ExpressionType.Default: case ExpressionType.ExternOp: case ExpressionType.ExternString: return(new StageValue(e, MetaStage.Const)); case ExpressionType.This: case ExpressionType.Base: case ExpressionType.TypeOf: return(new StageValue(e, MetaStage.ReadOnly, MetaStage.Volatile)); case ExpressionType.CapturedArgument: case ExpressionType.CapturedLocal: case ExpressionType.LoadArgument: return(new StageValue(e, MetaStage.Volatile, MetaStage.Volatile)); case ExpressionType.RuntimeConst: return(new StageValue(e, MetaStage.Vertex, MetaStage.Pixel)); case ExpressionType.LoadUniform: return(new StageValue(e, MetaStage.Vertex, MetaStage.Pixel)); case ExpressionType.LoadVarying: return(new StageValue(e, MetaStage.Pixel, MetaStage.Pixel)); case ExpressionType.LoadVertexAttrib: return(new StageValue(e, MetaStage.Vertex, MetaStage.Vertex)); case ExpressionType.FixOp: { var s = e as FixOp; var ps = ProcessValue(s.Operand); return(new StageValue(new FixOp(s.Source, s.Operator, ps.Value), ps.MinStage, ps.MaxStage)); } case ExpressionType.AddressOf: { var s = e as AddressOf; var ps = ProcessValue(s.Operand); return(new StageValue(new AddressOf(ps.Value, s.AddressType), ps.MinStage, ps.MaxStage)); } case ExpressionType.BranchOp: { var s = e as BranchOp; Expression left, right; MetaStage minStage, maxStage; ProcessValues(out minStage, out maxStage, s.Left, out left, s.Right, out right); return(new StageValue(new BranchOp(s.Source, s.ReturnType, s.BranchType, left, right), minStage, maxStage)); } case ExpressionType.ReferenceOp: { var s = e as ReferenceOp; Expression left, right; MetaStage minStage, maxStage; ProcessValues(out minStage, out maxStage, s.Left, out left, s.Right, out right); return(new StageValue(new ReferenceOp(s.Source, s.ReturnType, s.EqualityType, left, right), minStage, maxStage)); } case ExpressionType.SequenceOp: { var s = e as SequenceOp; Expression left, right; MetaStage minStage, maxStage; ProcessValues(out minStage, out maxStage, s.Left, out left, s.Right, out right); return(new StageValue(new SequenceOp(left, right), minStage, maxStage)); } case ExpressionType.ConditionalOp: { var s = e as ConditionalOp; var ps = ProcessValue(s.Condition); Expression a, b; MetaStage minStage, maxStage; ProcessValues(ref ps, out minStage, out maxStage, s.True, out a, s.False, out b); return(new StageValue(new ConditionalOp(s.Source, ps.Value, a, b), minStage, maxStage)); } case ExpressionType.NullOp: { var s = e as NullOp; var ps = StageValue.Default; if (ps.MaxStage > MetaStage.Volatile) { ps.MaxStage = MetaStage.Volatile; } Expression left, right; MetaStage minStage, maxStage; ProcessValues(ref ps, out minStage, out maxStage, s.Left, out left, s.Right, out right); return(new StageValue(new NullOp(s.Source, left, right), minStage, maxStage)); } case ExpressionType.IsOp: { var s = e as IsOp; var ps = ProcessValue(s.Operand); if (ps.MaxStage > MetaStage.Volatile) { ps.MaxStage = MetaStage.Volatile; } return(new StageValue(new IsOp(s.Source, ps.Value, s.TestType, s.ReturnType), ps.MinStage, ps.MaxStage)); } case ExpressionType.AsOp: { var s = e as AsOp; var ps = ProcessValue(s.Operand); if (ps.MaxStage > MetaStage.Volatile) { ps.MaxStage = MetaStage.Volatile; } return(new StageValue(new AsOp(s.Source, ps.Value, s.ReturnType), ps.MinStage, ps.MaxStage)); } case ExpressionType.LoadField: { var s = e as LoadField; var ps = ProcessValue(s.Object); AdjustInstanceStageRange(ref ps, s.Field.DeclaringType, true); return(new StageValue(new LoadField(s.Source, ps.Value, s.Field), ps.MinStage, ps.MaxStage)); } case ExpressionType.LoadElement: { var s = e as LoadElement; var ps = ProcessValue(s.Array); Expression index; MetaStage minStage, maxStage; ProcessValues(ref ps, out minStage, out maxStage, s.Index, out index); return(new StageValue(new LoadElement(s.Source, ps.Value, index), minStage, maxStage)); } case ExpressionType.Swizzle: { var s = e as Swizzle; var ps = ProcessValue(s.Object); AdjustInstanceStageRange(ref ps, s.Object.ReturnType, true); return(new StageValue(new Swizzle(s.Source, s.Constructor, ps.Value, s.Fields), ps.MinStage, ps.MaxStage)); } case ExpressionType.GetProperty: { var s = e as GetProperty; var ps = ProcessValue(s.Object); AdjustInstanceStageRange(ref ps, s.Property.DeclaringType, true); AdjustFunctionStageRange(ref ps, s.Property.GetMethod); MetaStage minStage, maxStage; var args = ProcessValues(ref ps, out minStage, out maxStage, s.Arguments); return(new StageValue(new GetProperty(s.Source, ps.Value, s.Property, args), minStage, maxStage)); } case ExpressionType.NewObject: { var s = e as NewObject; var ps = new StageValue(null, MetaStage.ReadOnly, s.ReturnType.IsReferenceType ? MetaStage.Volatile : MetaStage.Max); AdjustFunctionStageRange(ref ps, s.Constructor); MetaStage minStage, maxStage; var args = ProcessValues(ref ps, out minStage, out maxStage, s.Arguments); return(new StageValue(new NewObject(s.Source, s.Constructor, args), minStage, maxStage)); } case ExpressionType.NewArray: { var s = e as NewArray; var ps = new StageValue(null, MetaStage.ReadOnly, s.ArrayType.ElementType.IsReferenceType ? MetaStage.Volatile : MetaStage.Max); if (s.Size == null) { MetaStage minStage, maxStage; var initializers = ProcessValues(ref ps, out minStage, out maxStage, s.Initializers); return(new StageValue(new NewArray(s.Source, (RefArrayType)s.ReturnType, initializers), minStage, maxStage)); } else { Expression size; MetaStage minStage, maxStage; ProcessValues(ref ps, out minStage, out maxStage, s.Size, out size); return(new StageValue(new NewArray(s.Source, (RefArrayType)s.ReturnType, size), minStage, maxStage)); } } case ExpressionType.CallMethod: { var s = e as CallMethod; var ps = ProcessValue(s.Object); AdjustInstanceStageRange(ref ps, s.Method.DeclaringType, false); AdjustFunctionStageRange(ref ps, s.Method); MetaStage minStage, maxStage; var args = ProcessValues(ref ps, out minStage, out maxStage, s.Arguments); return(new StageValue(new CallMethod(s.Source, ps.Value, s.Method, args), minStage, maxStage)); } case ExpressionType.CallCast: { var s = e as CallCast; var ps = ProcessValue(s.Operand); AdjustFunctionStageRange(ref ps, s.Cast); return(new StageValue(new CallCast(s.Source, s.Cast, ps.Value), ps.MinStage, ps.MaxStage)); } case ExpressionType.CallBinOp: { var s = e as CallBinOp; var ps = StageValue.Default; AdjustFunctionStageRange(ref ps, s.Operator); Expression left, right; MetaStage minStage, maxStage; ProcessValues(ref ps, out minStage, out maxStage, s.Left, out left, s.Right, out right); return(new StageValue(new CallBinOp(s.Source, s.Operator, left, right), minStage, maxStage)); } case ExpressionType.CallUnOp: { var s = e as CallUnOp; var ps = ProcessValue(s.Operand); AdjustFunctionStageRange(ref ps, s.Operator); return(new StageValue(new CallUnOp(s.Source, s.Operator, ps.Value), ps.MinStage, ps.MaxStage)); } case ExpressionType.CastOp: { var s = e as CastOp; var ps = ProcessValue(s.Operand); if (ps.MaxStage > MetaStage.Volatile) { ps.MaxStage = MetaStage.Volatile; } return(new StageValue(new CastOp(s.Source, s.ReturnType, ps.Value), ps.MinStage, ps.MaxStage)); } case ExpressionType.StoreElement: case ExpressionType.StoreField: case ExpressionType.StoreArgument: case ExpressionType.StoreLocal: case ExpressionType.SetProperty: Log.Error(e.Source, ErrorCode.E5021, "Not allowed to use assign operators inside meta property definitions"); return(new StageValue(Expression.Invalid, MetaStage.Const)); } Log.Error(e.Source, ErrorCode.I5022, "<" + e.ExpressionType + "> is not supported by ShaderGenerator"); return(new StageValue(Expression.Invalid, MetaStage.Const)); }