internal ConsiderRuleBookFunctionNode( EtcScriptLib.Token Source, Rulebook Rulebook ) : base(Source) { this.Rulebook = Rulebook; }
private void StyleToken(EtcScriptLib.Token Token, int Style, int FoldLevel) { var range = new ScintillaNET.Range(Token.Location.Index, Token.Location.EndIndex, scintilla1); range.SetStyle(Style); //range.StartingLine.FoldLevel = FoldLevel; ////range.StartingLine.Indentation = FoldLevel; //if (FoldLevel > this.FoldLevel) // range.StartingLine.IsFoldPoint = true; //else // range.StartingLine.IsFoldPoint = false; //this.FoldLevel = FoldLevel; }
public override void Emit(VirtualMachine.InstructionList Instructions, EtcScriptLib.Ast.OperationDestination Destination) { bool useFallThrough = Rulebook.ResultTypeName == "RULE-RESULT"; //Try each rule in Rulebook until one of them returns not-null. List<int> JumpToEndPositions = new List<int>(); var parameterCount = Rulebook.DeclarationTerms.Count(t => t.Type == DeclarationTermType.Term); foreach (var Rule in Rulebook.Rules) { var skipPoints = new List<int>(); var sourceTerms = new List<DeclarationTerm>(Rule.Terms.Where(t => t.Type == DeclarationTermType.Term)); for (int i = 0; i < parameterCount; ++i) { if (sourceTerms[i].IsGlobalReference) { Instructions.AddInstructions("LOAD_PARAMETER NEXT PUSH", (-parameterCount - 2) + i); Instructions.AddInstructions("LOAD_RSO_M PEEK NEXT R", 0); Instructions.AddInstructions("EQUAL R NEXT R", BoxType.ID); //Is this a boxed type? Instructions.AddInstructions("IF_TRUE R"); Instructions.AddInstructions("LOAD_RSO_M PEEK NEXT PEEK", 2); //Grab boxed value instead. var global = DeclarationScope.FindVariable(sourceTerms[i].Name); Instructions.AddInstructions("LOAD_STATIC NEXT R", global.Offset); Instructions.AddInstructions("EQUAL R POP R"); } else { Instructions.AddInstructions("LOAD_PARAMETER NEXT PUSH", (-parameterCount - 2) + i); Instructions.AddInstructions("LOAD_RSO_M PEEK NEXT R", 0); //Load type ID Instructions.AddInstructions("EQUAL R NEXT PUSH", BoxType.ID); //Is this a boxed type? Instructions.AddInstructions("IF_TRUE POP"); Instructions.AddInstructions("LOAD_RSO_M PEEK NEXT R", 1); //Grab boxed typed instead. Instructions.AddInstructions("MOVE POP"); //Clean off parameter. var argumentTypeID = sourceTerms[i].DeclaredType.ID; Instructions.AddInstructions("IS_ANCESTOR_OF R NEXT R", argumentTypeID); } Instructions.AddInstructions("IF_FALSE R", "JUMP NEXT", 0); skipPoints.Add(Instructions.Count - 1); } if (Rule.WhenClause != null) { DuplicateArguments(Instructions, parameterCount); Instructions.AddInstructions("CALL NEXT", 0); Rule.WhenClause.CallPoints.Add(Instructions.Count - 1); Instructions.AddInstructions("CLEANUP NEXT", parameterCount); Instructions.AddInstructions("IF_FALSE R", "JUMP NEXT", 0); skipPoints.Add(Instructions.Count - 1); } DuplicateArguments(Instructions, parameterCount); Instructions.AddInstructions("CALL NEXT", 0); Rule.Body.CallPoints.Add(Instructions.Count - 1); Instructions.AddInstructions("CLEANUP NEXT", parameterCount); if (useFallThrough) { Instructions.AddInstructions("EQUAL NEXT R R", 0, "IF_TRUE R"); } else { Instructions.AddInstructions("LOAD_RSO_M R NEXT PUSH #Check if NEVERMIND was returned", 0, "EQUAL POP NEXT PUSH", 1, "IF_TRUE POP"); } Instructions.AddInstructions("JUMP NEXT", 0); JumpToEndPositions.Add(Instructions.Count - 1); foreach (var i in skipPoints) Instructions[i] = Instructions.Count; } if (Rulebook.DefaultValue != null) { DuplicateArguments(Instructions, parameterCount); Instructions.AddInstructions("CALL NEXT", 0); Rulebook.DefaultValue.Body.CallPoints.Add(Instructions.Count - 1); Instructions.AddInstructions("CLEANUP NEXT", parameterCount); } foreach (var spot in JumpToEndPositions) Instructions[spot] = Instructions.Count; if (!useFallThrough) Instructions.AddInstructions("LOAD_RSO_M R NEXT R", 1); if (Destination != Ast.OperationDestination.R && Destination != Ast.OperationDestination.Discard) Instructions.AddInstructions("MOVE R " + WriteOperand(Destination)); }
internal ConsiderRuleBookNode( EtcScriptLib.Token Source, EtcScriptLib.Ast.Node Arguments ) : base(Source) { if (Arguments is Ast.StaticInvokation) this.Arguments = (Arguments as Ast.StaticInvokation).Arguments; else throw new CompileError("Argument to ConsiderRule must be static invokation", Source); }