Пример #1
0
 public override Ast.Node Transform(ParseScope Scope)
 {
     ResultType = Type.Void;
     Condition = Condition.Transform(Scope);
     Body = Body.Transform(Scope);
     return this;
 }
Пример #2
0
        public virtual void EmitInstructions(ParseScope DeclarationScope, VirtualMachine.InstructionList Into)
        {
            if (Instructions != null) throw new InvalidOperationException("Instructions should not be emitted twice");

            CleanupPoint = Into.Count;

            if (CleanupCall >= 0)
                Into[CleanupCall] = CleanupPoint;

            Into.AddInstructions("CLEANUP NEXT #Cleanup " + Name, DeclarationScope.Owner.ActualParameterCount, "RETURN POP");

            Instructions = Into;
            EntryPoint = Into.Count;
            Instructions.AddInstructions("MOVE F PUSH #Enter " + Name, "MARK_STACK F");
            Body.Emit(Instructions, Ast.OperationDestination.Discard);
            //Instructions.AddInstructions("MOVE NEXT R", 0); //If a function has no return statement, it returns 0.
            var returnJumpPoint = Instructions.Count;
            Instructions.AddInstructions(
                "RESTORE_STACK F",
                "MOVE POP F",
                "RETURN POP");

            System.Diagnostics.Debug.Assert(DeclarationScope.Type == ScopeType.Function);
            System.Diagnostics.Debug.Assert(DeclarationScope.ReturnJumpSources != null);

            foreach (var point in DeclarationScope.ReturnJumpSources)
                Instructions[point] = returnJumpPoint;
        }
Пример #3
0
 public void ResolveType(ParseScope ActiveScope)
 {
     if (String.IsNullOrEmpty(DeclaredTypeName))
         DeclaredType = Type.Generic;
     else
     {
         DeclaredType = ActiveScope.FindType(DeclaredTypeName);
         if (DeclaredType == null) throw new CompileError("Could not find type '" + DeclaredTypeName + "'.");
     }
 }
Пример #4
0
        public override void EmitInstructions(ParseScope DeclarationScope, VirtualMachine.InstructionList Into)
        {
            if (Instructions != null) throw new InvalidOperationException("Instructions should not be emitted twice");

            CleanupPoint = Into.Count;

            if (CleanupCall >= 0)
                Into[CleanupCall] = CleanupPoint;

            Into.AddInstructions("CLEANUP NEXT #Cleanup when clause for " + Name,
                DeclarationScope.Owner.ActualParameterCount, "RETURN POP");

            Instructions = Into;
            EntryPoint = Into.Count;
            Instructions.AddInstructions("MOVE F PUSH #Enter " + Name, "MARK_STACK F");
            Body.Emit(Instructions, Ast.OperationDestination.R);
            Instructions.AddInstructions(
                "RESTORE_STACK F",
                "MOVE POP F",
                "RETURN POP");
        }
Пример #5
0
        public void ResolveTypes(ParseScope ActiveScope)
        {
            if (String.IsNullOrEmpty(SuperTypename))
                Super = null;
            else
            {
                Super = ActiveScope.FindType(SuperTypename);
                if (Super == null) throw new CompileError("Could not find type '" + SuperTypename + "'.");
            }

            if (Super == null)
                Members.Insert(0, new Variable
                {
                    Name = "__type",
                    DeclaredTypeName = "NUMBER",
                    StorageMethod = VariableStorageMethod.Member
                });

            var search = Super;
            while (search != null)
            {
                if (Object.ReferenceEquals(search, this)) throw new CompileError("Inheritance loop detected.");
                search = search.Super;
            }

            if (Origin == TypeOrigin.Script)
                foreach (var member in Members)
                {
                    if (String.IsNullOrEmpty(member.DeclaredTypeName))
                        member.DeclaredType = Type.Generic;
                    else
                    {
                        member.DeclaredType = ActiveScope.FindType(member.DeclaredTypeName);
                        if (member.DeclaredType == null) throw new CompileError("Could not find type '" +
                            member.DeclaredTypeName + "'.");
                    }
                }
        }
Пример #6
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 }));
        }
Пример #7
0
        public static TypeCompatibilityResult AreTypesCompatible(Type Source, Type Destination, ParseScope Scope)
        {
            if (Object.ReferenceEquals(Destination, Generic)) return TypeCompatibilityResult.NoConversionRequired;
            if (Object.ReferenceEquals(Source, Destination)) return TypeCompatibilityResult.NoConversionRequired;

            var super = Source.Super;
            while (super != null)
            {
                if (Object.ReferenceEquals(super, Destination)) return TypeCompatibilityResult.NoConversionRequired;
                super = super.Super;
            }

            var conversionArguments = new List<Ast.Node>();
            conversionArguments.Add(new Ast.Identifier(new Token { Type = TokenType.Identifier, Value = "convert" }));
            conversionArguments.Add(new Ast.Identifier(new Token { Type = TokenType.Identifier, Value = "0" }) { ResultType = Source });
            conversionArguments.Add(new Ast.Identifier(new Token { Type = TokenType.Identifier, Value = "to" }));
            conversionArguments.Add(new Ast.Identifier(new Token { Type = TokenType.Identifier, Value = Destination.Name }));

            var possibleConversions = Scope.FindAllPossibleMacroMatches(conversionArguments);
            Declaration matchingConversion = null;
            foreach (var possibleConversion in possibleConversions)
                if (Object.ReferenceEquals(Source, possibleConversion.Terms[1].DeclaredType))
                {
                    matchingConversion = possibleConversion;
                    break;
                }

            if (matchingConversion != null)
            {
                if (!Object.ReferenceEquals(matchingConversion.ReturnType, Destination))
                    throw new CompileError("Conversion function does not return the correct type.",
                        matchingConversion.Body.Body.Source);

                return new TypeCompatibilityResult
                {
                    Compatible = true,
                    ConversionRequired = true,
                    ConversionMacro = matchingConversion
                };
            }

            return TypeCompatibilityResult.Incompatible;
        }
Пример #8
0
        public void ResolveTypes(ParseScope Scope)
        {
            try
            {
                DeclarationScope = Scope.Push(ScopeType.Function);
                DeclarationScope.Owner = this;

                if (!String.IsNullOrEmpty(ReturnTypeName))
                {
                    ReturnType = Scope.FindType(ReturnTypeName);
                    if (ReturnType == null)
                    {
                        if (Body != null && Body.Body != null)
                            throw new CompileError("Could not find type '" +
                                ReturnTypeName + "'.", Body.Body.Source);
                        else
                            throw new CompileError("Could not find type '" +
                                ReturnTypeName + "'.");
                    }
                }
                else
                    ReturnType = EtcScriptLib.Type.Void;

                CreateParameterDescriptors();

                var header = DescriptiveHeader;
                if (Body != null) Body.Name = header;
                if (WhenClause != null) WhenClause.Name = header + " : when ...";
            }
            catch (Exception e)
            {
                throw new CompileError(e.Message + " while resolving types on " + DescriptiveHeader + "\n" + e.StackTrace);
            }
        }
Пример #9
0
            public override Ast.Node Transform(ParseScope Scope)
            {
                List = List.Transform(Scope);
                ResultType = List.ResultType;

                //Try to find an access macro for this type.
                var getterArguments = DummyArguments(Keyword("GET"), Keyword("AT"), Term(Scope.FindType("NUMBER")),
                    Keyword("FROM"), Term(List.ResultType));
                var indexerMacro = Scope.FindAllPossibleMacroMatches(getterArguments).Where(d =>
                    ExactDummyMatch(d.Terms, getterArguments)).FirstOrDefault();
                if (indexerMacro == null)
                    throw new CompileError("No macro of the form GET AT NUMBER FROM " +
                        List.ResultType.Name + " found.", Source);

                var lengthArguments = DummyArguments(Keyword("LENGTH"), Keyword("OF"), Term(List.ResultType));
                var lengthMacro = Scope.FindAllPossibleMacroMatches(lengthArguments).Where(d =>
                    ExactDummyMatch(d.Terms, lengthArguments)).FirstOrDefault();
                if (lengthMacro == null)
                    throw new CompileError("No macro of the form LENGTH OF " + List.ResultType.Name + " found.", Source);

                var nestedScope = Scope.Push(ScopeType.Block);

                ResultVariable = nestedScope.NewLocal("__result@" + VariableName, Scope.FindType("LIST"));
                ListVariable = nestedScope.NewLocal("__list@" + VariableName, Scope.FindType("LIST"));
                TotalVariable = nestedScope.NewLocal("__total@" + VariableName, Scope.FindType("NUMBER"));
                CounterVariable = nestedScope.NewLocal("__counter@" + VariableName, Scope.FindType("NUMBER"));
                ValueVariable = nestedScope.NewLocal(VariableName, indexerMacro.ReturnType);

                Indexer = Ast.StaticInvokation.CreateCorrectInvokationNode(Source, nestedScope, indexerMacro,
                    new List<Ast.Node>(new Ast.Node[] {
                        new Ast.Identifier(new Token { Type = TokenType.Identifier, Value = "__counter@"+VariableName }),
                        new Ast.Identifier(new Token { Type = TokenType.Identifier, Value = "__list@"+VariableName })
                    })).Transform(nestedScope);

                LengthFunc = Ast.StaticInvokation.CreateCorrectInvokationNode(Source, nestedScope, lengthMacro,
                    new List<Ast.Node>(new Ast.Node[] {
                        new Ast.Identifier(new Token { Type = TokenType.Identifier, Value = "__list@"+VariableName })
                    })).Transform(nestedScope);

                Condition = Condition.Transform(nestedScope);
                if (Condition.ResultType.Name != "BOOLEAN")
                    throw new CompileError("Condition to where clause must return boolean", Source);
                return this;
            }
Пример #10
0
 public void Transform(ParseScope DeclarationScope)
 {
     Body = Body.Transform(DeclarationScope);
 }
Пример #11
0
 public ParseScope Push(ScopeType Type)
 {
     var r = new ParseScope(Type);
     r.Parent = this;
     r.VariableIndex = (Type == ScopeType.Function ? 0 : this.VariableIndex);
     r.EnvironmentContext = this.EnvironmentContext;
     return r;
 }
Пример #12
0
            public override EtcScriptLib.Ast.Node Transform(ParseScope Scope)
            {
                var rulebook = Scope.EnvironmentContext.Rules.FindMatchingRulebook(Arguments);
                if (rulebook == null)
                    return null; //Rulebook does not exist... no, this isn't an error!

                var arguments = Declaration.GenerateParameterListSyntaxTree(Arguments, rulebook.DeclarationTerms).Members;
                var boxedArguments = new List<Ast.Node>(arguments.Select(n =>
                {
                    n = n.Transform(Scope);
                    if (n.ResultType.Origin != TypeOrigin.Script)
                        return new Ast.Box(n.Source, n).Transform(Scope);
                    else
                        return n;
                }));

                //This only works because rulebook consider functions take only generics.
                return Ast.StaticInvokation.CreateCorrectInvokationNode(Source, Scope, rulebook.ConsiderFunction,
                    boxedArguments)
                    .Transform(Scope);
            }
Пример #13
0
 public override EtcScriptLib.Ast.Node Transform(ParseScope Scope)
 {
     DeclarationScope = Scope;
     BoxType = Scope.FindType("BOXED");
     ResultType = Rulebook.ResultType;
     return this;
 }
Пример #14
0
		public ParseContext()
		{
			ActiveScope = new ParseScope(ScopeType.Root) { EnvironmentContext = this };
			TopScope = ActiveScope;
		}
Пример #15
0
		public void PushNewScope(ScopeType Type)
		{
			var newScope = new ParseScope(Type) { Parent = ActiveScope, EnvironmentContext = this };
			ActiveScope = newScope;
		}
Пример #16
0
 public override Ast.Node Transform(ParseScope Scope)
 {
     ResultType = Type.Void;
     Max = Max.Transform(Scope);
     var nestedScope = Scope.Push(ScopeType.Block);
     TotalVariable = nestedScope.NewLocal("__total@" + VariableName, Scope.FindType("NUMBER"));
     Min = Min.Transform(nestedScope);
     CounterVariable = nestedScope.NewLocal("__counter@" + VariableName, Scope.FindType("NUMBER"));
     ValueVariable = nestedScope.NewLocal(VariableName, Scope.FindType("NUMBER"));
     Body = Body.Transform(nestedScope);
     return this;
 }