private void AddToRulelist(Declaration Rule, List<Declaration> List) { if (List.Count == 0) List.Add(Rule); else { var insertSpot = List.Count - 1; while (insertSpot != 0 && RuleAIsMoreSpecializedThanB(Rule, List[insertSpot])) --insertSpot; List.Insert(insertSpot, Rule); } }
public static Control Create( Declaration Declaration, ControlBlockType BlockType, Func<List<Ast.Node>, Ast.Node, Ast.Node> TransformationFunction) { return new Control { DeclarationTerms = Declaration.Terms, TransformationFunction = TransformationFunction, BlockType = BlockType }; }
public static void EmitDebugDump(Declaration declaration) { DebugWrite(declaration.Type.ToString() + ":\n"); DebugWrite(" TERMS: "); foreach (var term in declaration.Terms) DebugWrite(term.ToString() + " "); //Console.WriteLine(); if (declaration.WhenClause != null) { //DebugWrite("\n WHEN AST:\n"); //declaration.WhenClause.Body.Debug(0); DebugWrite("\n WHEN ENTRY: " + declaration.WhenClause.EntryPoint + "\n"); } else DebugWrite("\n NO WHEN CLAUSE\n"); //DebugWrite(" AST:\n"); //declaration.Body.Body.Debug(0); DebugWrite(" ENTRY: " + declaration.Body.EntryPoint + "\n"); }
private bool RuleAIsMoreSpecializedThanB(Declaration A, Declaration B) { //Assume A and B have compatible terms. They shouldn't have made it this far if not. for (var i = 0; i < A.Terms.Count; ++i) { if (A.Terms[i].Type != DeclarationTermType.Term) continue; if (A.Terms[i].IsGlobalReference && !B.Terms[i].IsGlobalReference) return true; var BType = B.Terms[i].DeclaredType; var AType = A.Terms[i].DeclaredType; if (AType.ID == BType.ID) continue; //They are the same type, so try the next term. return AIsDerivedFromB(AType, BType); } //All terms are equal if (B.WhenClause == null && A.WhenClause != null) return true; //When clauses make it more specific... if (PriorityRank(A) > PriorityRank(B)) return true; return false; }
public static Ast.Node CreateConversionInvokation( ParseScope Scope, Declaration ConversionMacro, Ast.Node Value) { return Ast.StaticInvokation.CreateCorrectInvokationNode(Value.Source, Scope, ConversionMacro, new List<Ast.Node>(new Ast.Node[] { Value })); }
public static Declaration Parse(String Header) { var tokenIterator = new TokenStream(new StringIterator(Header), new ParseContext()); var headerTerms = EtcScriptLib.Parse.ParseMacroDeclarationHeader(tokenIterator, EtcScriptLib.Parse.DeclarationHeaderTerminatorType.StreamEnd); var r = new Declaration(); r.ReturnTypeName = "VOID"; if (!tokenIterator.AtEnd() && tokenIterator.Next().Type == TokenType.Colon) { tokenIterator.Advance(); if (tokenIterator.Next().Type != TokenType.Identifier) throw new CompileError("Expected identifier", tokenIterator); r.ReturnTypeName = tokenIterator.Next().Value.ToUpper(); tokenIterator.Advance(); } if (!tokenIterator.AtEnd()) throw new CompileError("Header did not end when expected"); r.Terms = headerTerms; r.Body = new LambdaBlock(null); return r; }
internal void AddChildLambda(Declaration Function) { if (Type == ScopeType.Function) { if (ReturnJumpSources == null) throw new InvalidProgramException(); ChildLambdas.Add(Function); } else { if (Parent == null) throw new InvalidProgramException(); Parent.AddChildLambda(Function); } }
private int PriorityRank(Declaration A) { if ((A.OrderOperator & OrderOperator.HIGH) == OrderOperator.HIGH) return 2; if ((A.OrderOperator & OrderOperator.LOW) == OrderOperator.LOW) return 0; return 1; }
internal static Declaration ParseRuleDeclaration(TokenStream Stream, ParseContext Context) { if (Stream.AtEnd()) throw new CompileError("[02F] Impossible error: ParseRuleDeclaration entered at end of stream.", Stream); try { var r = new Declaration(); r.ReturnTypeName = "RULE-RESULT"; if (Stream.Next().Type != TokenType.Identifier) throw new CompileError("[030] Expected identifier", Stream.Next()); r.Type = DeclarationType.Rule; Stream.Advance(); r.Terms = ParseMacroDeclarationHeader(Stream, DeclarationHeaderTerminatorType.OpenBraceOrWhen); foreach (var t in r.Terms) if (t.Type == DeclarationTermType.Operator) throw new CompileError("Rule headers cannot contain operators", Stream); if (Stream.Next().Type == TokenType.Colon) { Stream.Advance(); if (Stream.Next().Type != TokenType.Identifier) throw new CompileError("[02A] Expected identifier", Stream); r.ReturnTypeName = Stream.Next().Value.ToUpper(); Stream.Advance(); } if (Stream.Next().Value.ToUpper() == "WHEN") { Stream.Advance(); r.WhenClause = new WhenClause(ParseExpression(Stream, Context, (stream) => { if (stream.Next().Type == TokenType.OpenBrace) return true; if (stream.Next().Type == TokenType.Identifier && (stream.Next().Value.ToUpper() == "WITH" || stream.Next().Value.ToUpper() == "ORDER")) return true; return false; })); } r.OrderOperator = OrderOperator.NONE; if (Stream.Next().Value.ToUpper() == "ORDER") { Stream.Advance(); var temp = OrderOperator.NONE; if (!Enum.TryParse(Stream.Next().Value.ToUpper(), out temp)) throw new CompileError("Expected FIRST or LAST", Stream); if (temp != OrderOperator.FIRST && temp != OrderOperator.LAST) throw new CompileError("Expected FIRST or LAST", Stream); Stream.Advance(); r.OrderOperator |= temp; } if (Stream.Next().Value.ToUpper() == "WITH") { Stream.Advance(); var temp = OrderOperator.NONE; if (!Enum.TryParse(Stream.Next().Value.ToUpper(), out temp)) throw new CompileError("Expected HIGH or LOW", Stream); if (temp != OrderOperator.HIGH && temp != OrderOperator.LOW) throw new CompileError("Expected HIGH or LOW", Stream); Stream.Advance(); if (Stream.Next().Value.ToUpper() != "PRIORITY") throw new CompileError("Expected PRIORITY", Stream); Stream.Advance(); r.OrderOperator |= temp; } if (Stream.Next().Type == TokenType.OpenBrace) { r.Body = new LambdaBlock(ParseBlock(Stream, Context)); } else { throw new CompileError("[031] Expected block", Stream); } if (!Stream.AtEnd() && Stream.Next().Type == TokenType.QuestionMark) { Stream.Advance(); if (Stream.Next().Type != TokenType.String) throw new CompileError("Expected documentation", Stream); r.Documentation = Stream.Next().Value; Stream.Advance(); } return r; } catch (CompileError ce) { throw ce; } catch (Exception e) { throw new CompileError(e.Message + e.StackTrace, Stream); } }
internal static Declaration ParseMacroDeclaration(TokenStream Stream, ParseContext Context) { if (Stream.AtEnd()) throw new CompileError("[028] Impossible error: ParseDeclaration entered at end of stream.", Stream); try { var r = new Declaration(); r.ReturnTypeName = "VOID"; if (Stream.Next().Type != TokenType.Identifier) throw new CompileError("[029] Expected identifier", Stream.Next()); r.Type = DeclarationType.Macro; Stream.Advance(); r.Terms = ParseMacroDeclarationHeader(Stream, DeclarationHeaderTerminatorType.OpenBrace); foreach (var t in r.Terms) if (t.Type == DeclarationTermType.Operator) r.DefinesOperator = true; if (r.DefinesOperator) { if (r.Terms.Count != 3 || r.Terms[0].Type != DeclarationTermType.Term || r.Terms[1].Type != DeclarationTermType.Operator || r.Terms[2].Type != DeclarationTermType.Term) throw new CompileError("Operator macros must be of the form 'term op term'", Stream); r.Terms[1].Type = DeclarationTermType.Keyword; } if (!Stream.AtEnd() && Stream.Next().Type == TokenType.Colon) { Stream.Advance(); if (Stream.Next().Type != TokenType.Identifier) throw new CompileError("[02A] Expected identifier", Stream); r.ReturnTypeName = Stream.Next().Value.ToUpper(); Stream.Advance(); } if (r.DefinesOperator && r.ReturnTypeName == "VOID") throw new CompileError("Operator macros must return a value.", Stream); if (!Stream.AtEnd() && Stream.Next().Type == TokenType.OpenBrace) { r.Body = new LambdaBlock(ParseBlock(Stream, Context)); } else throw new CompileError("[02B] Expected block", Stream); if (!Stream.AtEnd() && Stream.Next().Type == TokenType.QuestionMark) { Stream.Advance(); if (Stream.Next().Type != TokenType.String) throw new CompileError("Expected documentation", Stream); r.Documentation = Stream.Next().Value; Stream.Advance(); } return r; } catch (CompileError ce) { throw ce; } catch (Exception e) { throw new CompileError(e.Message + e.StackTrace, Stream); } }