Beispiel #1
0
		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);
			}
		}
Beispiel #2
0
        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
            };
        }
Beispiel #3
0
 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");
 }
Beispiel #4
0
		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;
		}
Beispiel #5
0
        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 }));
        }
Beispiel #6
0
        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;
        }
Beispiel #7
0
 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);
     }
 }
Beispiel #8
0
		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;
		}
Beispiel #9
0
        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);
            }
        }
Beispiel #10
0
        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);
            }
        }