예제 #1
0
파일: Indexer.cs 프로젝트: Blecki/EtcScript
        public override Node Transform(ParseScope Scope)
        {
            Object = Object.Transform(Scope);
            Index = Index.Transform(Scope);

            if (IsAssignmentTarget)
            {
                //Try to find an indexer macro for this type.
                var setterArguments = DummyArguments(Keyword("SET"), Keyword("AT"), Term(Index.ResultType),
                    Keyword("IN"), Term(Object.ResultType), Keyword("TO"), TermOfAnyType());
                var matchingSetter = Scope.FindAllPossibleMacroMatches(setterArguments).Where(d =>
                    ExactDummyMatch(d.Terms, setterArguments)).FirstOrDefault();
                if (matchingSetter != null)
                    return new ExplicitIndexSetter(Source, matchingSetter, Object, Index).Transform(Scope);
                else
                    throw new CompileError("No macro of the form SET AT " + Index.ResultType.Name + " IN " +
                            Object.ResultType.Name + " TO VALUE found.", Source);
            }
            else
            {
                //Try to find an access macro for this type.
                var getterArguments = DummyArguments(Keyword("GET"), Keyword("AT"), Term(Index.ResultType),
                    Keyword("FROM"), Term(Object.ResultType));
                var matchingGetter = Scope.FindAllPossibleMacroMatches(getterArguments).Where(d =>
                    ExactDummyMatch(d.Terms, getterArguments)).FirstOrDefault();
                if (matchingGetter != null)
                    return StaticInvokation.CreateCorrectInvokationNode(Source, Scope, matchingGetter,
                        new List<Node>(new Node[] { Index, Object })).Transform(Scope);
                else
                    throw new CompileError("No macro of the form GET AT " + Index.ResultType.Name + " FROM " +
                        Object.ResultType.Name + " found.", Source);
            }
        }
예제 #2
0
 public ForeachIn(Token Source, String VariableName, Ast.Node List, Ast.Node Body)
     : base(Source)
 {
     this.VariableName = VariableName;
     this.List = List;
     this.Body = Body;
 }
예제 #3
0
 public ControlInvokation(Token Source, Control Control, List<Node> Arguments, Node Body)
     : base(Source)
 {
     this.Control = Control;
     this.Arguments = Arguments;
     this.Body = Body;
 }
예제 #4
0
 public GenericSetter(Token Source, Declaration Function, String MemberName, Node Object)
     : base(Source)
 {
     this.Function = Function;
     this.Object = Object;
     this.MemberName = MemberName;
 }
예제 #5
0
파일: Cast.cs 프로젝트: Blecki/EtcScript
 public override Node Transform(ParseScope Scope)
 {
     ResultType = Scope.FindType(Typename);
     if (ResultType == null) throw new CompileError("Could not find type '" + Typename + "'.", Source);
     Value = Value.Transform(Scope);
     return this;
 }
예제 #6
0
파일: Return.cs 프로젝트: Blecki/EtcScript
        public override Node Transform(ParseScope Scope)
        {
            ResultType = Type.Void;
            if (Value != null)
            {
                Value = Value.Transform(Scope);

                if (Scope.OwnerFunction.Type == DeclarationType.Rule
                    && Scope.OwnerFunctionReturnType.Name != "RULE-RESULT")
                {
                    Value = new RuleResultNode(Source, Value).Transform(Scope);
                }
                else
                {
                    var conversionInfo = Type.AreTypesCompatible(Value.ResultType, Scope.OwnerFunctionReturnType, Scope);
                    if (!conversionInfo.Compatible)
                        Type.ThrowConversionError(Value.ResultType, Scope.OwnerFunctionReturnType, Source);

                    if (conversionInfo.ConversionRequired)
                        Value = Type.CreateConversionInvokation(Scope, conversionInfo.ConversionMacro, Value).Transform(Scope);
                }
            }
            else
            {
                if (!Object.ReferenceEquals(Scope.OwnerFunctionReturnType, Type.Void))
                    throw new CompileError("This function must return a value", Source);
            }
            DeclarationScope = Scope;
            return this;
        }
예제 #7
0
 public ExplicitIndexSetter(Token Source, Declaration Function, Node Object, Node Index)
     : base(Source)
 {
     this.Function = Function;
     this.Object = Object;
     this.Index = Index;
 }
예제 #8
0
 public override Ast.Node Transform(ParseScope Scope)
 {
     ResultType = Type.Void;
     Condition = Condition.Transform(Scope);
     Body = Body.Transform(Scope);
     return this;
 }
예제 #9
0
 public ForeachFrom(Token Source, String VariableName, Ast.Node Min, Ast.Node Max, Ast.Node Body)
     : base(Source)
 {
     this.VariableName = VariableName;
     this.Min = Min;
     this.Max = Max;
     this.Body = Body;
 }
예제 #10
0
        public BinaryOperator(Token Source, ParseContext.Operator Operator,
			Node LHS, Node RHS)
            : base(Source)
        {
            this.Operator = Operator;
            this.LHS = LHS;
            this.RHS = RHS;
        }
예제 #11
0
파일: If.cs 프로젝트: Blecki/EtcScript
 public override Node Transform(ParseScope Scope)
 {
     ResultType = Type.Void;
     Header = Header.Transform(Scope);
     ThenBlock = ThenBlock.Transform(Scope);
     if (ElseBlock != null) ElseBlock = ElseBlock.Transform(Scope);
     return this;
 }
예제 #12
0
        public Node TransformAssignment(ParseScope Scope, Let Let, Node Value)
        {
            var arguments = new List<Node>();
            arguments.Add(Object);
            arguments.Add(Value);

            return StaticInvokation.CreateCorrectInvokationNode(Source, Scope, Function, arguments);
        }
예제 #13
0
        public RawBinaryOperator(Token Source, VirtualMachine.InstructionSet Instruction,
			Node LHS, Node RHS, Type ResultType)
            : base(Source)
        {
            this.Instruction = Instruction;
            this.LHS = LHS;
            this.RHS = RHS;
            this.ResultType = ResultType;
        }
예제 #14
0
 public override Node Transform(ParseScope Scope)
 {
     Object = Object.Transform(Scope);
     if (Object.ResultType.Origin == TypeOrigin.System) throw new InvalidOperationException();
     MemberVariable = Object.ResultType.FindMember(MemberName);
     if (MemberVariable == null) throw new CompileError("Could not find member '" + MemberName + "' on type '" +
         Object.ResultType.Name + "'.", Source);
     this.ResultType = MemberVariable.DeclaredType;
     return this;
 }
예제 #15
0
            public EachXInListWhereNode(
				Token Source, 
				String VariableName, 
				Ast.Node List, 
				Ast.Node Condition)
                : base(Source)
            {
                this.VariableName = VariableName;
                this.List = List;
                this.Condition = Condition;
            }
예제 #16
0
        public override Node Transform(ParseScope Scope)
        {
            ResultType = Type.Void;

            Value = Value.Transform(Scope);
            Member = ObjectType.FindMember(MemberName);
            if (Member == null) throw new CompileError("Unable to find member '" + MemberName + "' of " + ObjectType.Name);

            var compatibilityResult = Type.AreTypesCompatible(Value.ResultType, Member.DeclaredType, Scope);
            if (!compatibilityResult.Compatible)
                Type.ThrowConversionError(Value.ResultType, Member.DeclaredType, Source);

            if (compatibilityResult.ConversionRequired)
                Value = Type.CreateConversionInvokation(Scope, compatibilityResult.ConversionMacro, Value).Transform(Scope);

            return this;
        }
예제 #17
0
파일: Let.cs 프로젝트: Blecki/EtcScript
        public override Node Transform(ParseScope Scope)
        {
            ResultType = Type.Void;
            LHS.IsAssignmentTarget = true;
            LHS = LHS.Transform(Scope);
            if (!(LHS is IAssignable)) throw new CompileError("Assignment target is not an lvalue", Source);
            Value = Value.Transform(Scope);

            var compatibilityResult = Type.AreTypesCompatible(Value.ResultType, (LHS as IAssignable).DestinationType, Scope);
            if (!compatibilityResult.Compatible)
                Type.ThrowConversionError(Value.ResultType, (LHS as IAssignable).DestinationType, Source);

            if (compatibilityResult.ConversionRequired)
                Value = Type.CreateConversionInvokation(Scope, compatibilityResult.ConversionMacro, Value)
                    .Transform(Scope);

            return (LHS as IAssignable).TransformAssignment(Scope, this, Value);
        }
예제 #18
0
        public override Node Transform(ParseScope Scope)
        {
            //var existingVariable = Scope.FindVariable(Name);
            //if (existingVariable != null)
            //    throw new CompileError("A variable called '" + Name +
            //        "' can't be defined here because it would hide a variable already defined with that name.", Source);

            if (String.IsNullOrEmpty(Typename))
                ResultType = Type.Generic;
            else
            {
                ResultType = Scope.FindType(Typename);
                if (ResultType == null) throw new CompileError("Could not find type '" + Typename + "'.", Source);
            }

            if (Value != null)
            {
                Value = Value.Transform(Scope);

                if (!String.IsNullOrEmpty(Typename))
                {
                    var compatibilityResult = Type.AreTypesCompatible(Value.ResultType, ResultType, Scope);
                    if (!compatibilityResult.Compatible)
                        Type.ThrowConversionError(Value.ResultType, ResultType, Source);

                    if (compatibilityResult.ConversionRequired)
                        Value = Type.CreateConversionInvokation(Scope, compatibilityResult.ConversionMacro, Value)
                            .Transform(Scope);
                }
                else //Infer the type of the variable from the expression assigned to it.
                    ResultType = Value.ResultType;
            }

            Variable = Scope.NewLocal(Name.ToUpper(), ResultType);
            Variable.DeclaredTypeName = Typename;
            Variable.DeclaredType = ResultType;

            return this;
        }
예제 #19
0
        public override Node Transform(ParseScope Scope)
        {
            LHS = LHS.Transform(Scope);
            RHS = RHS.Transform(Scope);

            //Generics behave dynamically with operators.
            if (Object.ReferenceEquals(LHS.ResultType, Type.Generic) || Object.ReferenceEquals(RHS.ResultType, Type.Generic))
                return new RawBinaryOperator(Source, Operator.instruction, LHS, RHS, Type.Generic);

            //Equality works with everything.
            if (Operator.token == "==" || Operator.token == "!=")
                return new RawBinaryOperator(Source, Operator.instruction, LHS, RHS, Scope.FindType("BOOLEAN"));

            if (Object.ReferenceEquals(LHS.ResultType, RHS.ResultType))
            {
                PopulateRawOperators();
                if (RawOperators.ContainsKey(LHS.ResultType.Name))
                    if (RawOperators[LHS.ResultType.Name].Contains(Operator.token))
                    {
                        //Return type is always boolean for raw comparisons.
                        if (Operator.token == ">" || Operator.token == ">=" || Operator.token == "<" || Operator.token == "<=")
                            return new RawBinaryOperator(Source, Operator.instruction, LHS, RHS, Scope.FindType("BOOLEAN"));
                        return new RawBinaryOperator(Source, Operator.instruction, LHS, RHS, LHS.ResultType);
                    }
            }

            //Try to find an operator macro for these types.
            var operatorArguments = DummyArguments(Term(LHS.ResultType), Keyword(Operator.token), Term(RHS.ResultType));
            var matchingOperator = Scope.FindAllPossibleMacroMatches(operatorArguments).Where(d =>
                    ExactDummyMatch(d.Terms, operatorArguments)).FirstOrDefault();
            if (matchingOperator != null)
            {
                return StaticInvokation.CreateCorrectInvokationNode(Source, Scope, matchingOperator,
                    new List<Node>(new Node[] { LHS, RHS })).Transform(Scope);
            }
            else
                throw new CompileError("No operator macro of the form " + LHS.ResultType.Name + " " +
                    Operator.token + " " + RHS.ResultType.Name + " found.", Source);
        }
예제 #20
0
파일: Cast.cs 프로젝트: Blecki/EtcScript
 public Cast(Token Source, Node Value, String Typename)
     : base(Source)
 {
     this.Value = Value;
     this.Typename = Typename;
 }
예제 #21
0
파일: Let.cs 프로젝트: Blecki/EtcScript
 public Let(Token Source, Node Object, Node Value)
     : base(Source)
 {
     this.LHS = Object;
     this.Value = Value;
 }
예제 #22
0
파일: Box.cs 프로젝트: Blecki/EtcScript
 public override Node Transform(ParseScope Scope)
 {
     ResultType = Scope.FindType("BOXED");
     Value = Value.Transform(Scope);
     return this;
 }
예제 #23
0
        private Node Convert(Node Node, Type StringType, ParseScope Scope)
        {
            var conversionInfo = Type.AreTypesCompatible(Node.ResultType, StringType, Scope);
            if (!conversionInfo.Compatible)
                Type.ThrowConversionError(Node.ResultType, StringType, Source);

            if (conversionInfo.ConversionRequired)
                return Type.CreateConversionInvokation(Scope, conversionInfo.ConversionMacro, Node).Transform(Scope);
            return Node;
        }
예제 #24
0
 public While(Token Source, Ast.Node Condition, Ast.Node Body)
     : base(Source)
 {
     this.Condition = Condition;
     this.Body = Body;
 }
예제 #25
0
 public ExplicitSetter(Token Source, Declaration Function, Node Object)
     : base(Source)
 {
     this.Function = Function;
     this.Object = Object;
 }
예제 #26
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;
            }
예제 #27
0
 public LambdaBlock(Ast.Node Body)
 {
     this.Body = Body;
 }
예제 #28
0
파일: Box.cs 프로젝트: Blecki/EtcScript
 public Box(Token Source, Node Value)
     : base(Source)
 {
     this.Value = Value;
 }
예제 #29
0
 public void Transform(ParseScope DeclarationScope)
 {
     Body = Body.Transform(DeclarationScope);
 }
예제 #30
0
 public Node TransformAssignment(ParseScope Scope, Let Let, Node Value)
 {
     return Let;
 }