Exemplo n.º 1
0
        public static IReadOnlyList <ExpressionNode> ParseIndex(ContextNode context, IAbstractSyntaxTree lexerNode)
        {
            Contract.Requires(lexerNode.Type == Lexer.TokenType.IndexNode);
            Contract.Requires(!IsEmptyIndexer(lexerNode));

            return(lexerNode.Children.AsEnumerable().Where(n => n.Type == Lexer.TokenType.Value).Select(n => ExpressionNode.Parse(context, n)).ToArray());
        }
        public static ExpressionNode Create(ContextNode context, ExpressionNode function, IEnumerable <ExpressionNode> args, SequencePoint point)
        {
            Contract.Ensures(Contract.Result <ExpressionNode>() != null);
            foreach (var arg in args)
            {
                if (!arg.IsGettable)
                {
                    ErrorCode.NotAnRValue.ReportAndThrow(arg.SequencePoint, "Arguments must be gettable");
                }
            }

            var method = AsObjectCreation(context, function, args, point);

            if (method != null)
            {
                return(method);
            }

            method = AsMethod(context, function, args, point);
            if (method != null)
            {
                return(method);
            }

            method = AsFunctor(context, function, args, point);
            if (method != null)
            {
                return(method);
            }

            ErrorCode.NotCallable.ReportAndThrow(point, "Unable to call symbol");
            return(Utils.Utils.Fail <ExpressionNode>());
        }
Exemplo n.º 3
0
        public static ExpressionNode Create(ContextNode context, BinaryOperatorNodeType op, ExpressionNode left, ExpressionNode right, SequencePoint point)
        {
            if (!left.IsGettable)
            {
                ErrorCode.NotAnRValue.ReportAndThrow(left.SequencePoint, "Binary operand is not gettable");
            }

            if (!right.IsGettable)
            {
                ErrorCode.NotAnRValue.ReportAndThrow(right.SequencePoint, "Binary operand is not gettable");
            }

            ExpressionNode ret = AsOverload(context, op, left, right, point);

            if (ret == null)
            {
                ret = AsBuiltIn(context, op, left, right, point);
            }

            if (ret == null)
            {
                OperatorMismatch(point, op, left.ExpressionReturnType, right.ExpressionReturnType);
            }

            Contract.Assume(ret != null);
            return(ret);
        }
        public static ExpressionNode Parse(ContextNode context, IAbstractSyntaxTree lexerNode, TypeReference expectedType = null)
        {
            Contract.Ensures(Contract.Result <ExpressionNode>() != null);
            ExpressionNode ret = null;

            switch (lexerNode.Type)
            {
            case Lexer.TokenType.FullSymbol:
            case Lexer.TokenType.Symbol:
                ret = DotOperatorNode.Parse(context, lexerNode);
                break;

            case Lexer.TokenType.LiteralNode:
                ret = LiteralNode.Parse(context, lexerNode);
                break;

            case Lexer.TokenType.Value:
                ret = ExpressionNode.Parse(context, lexerNode.Children[0], expectedType);
                break;

            case Lexer.TokenType.Function:
                ret = MethodNode.Parse(context, lexerNode);
                break;

            case Lexer.TokenType.InfixNode:
                ret = InfixParser.Parse(context, lexerNode);
                break;

            case Lexer.TokenType.PostfixNode:
            case Lexer.TokenType.PrefixNode:
                ret = UnaryOperators.Parse(context, lexerNode);
                break;

            case Lexer.TokenType.ParenthesesNode:
                ret = ExpressionNode.Parse(context, lexerNode.Children[1], expectedType);
                break;

            case Lexer.TokenType.ArrayLiteral:
                ret = ArrayCreationNode.Parse(context, lexerNode);
                break;

            case Lexer.TokenType.Null:
                ret = NullNode.Parse(context, lexerNode);
                break;

            default:
                ContractsHelper.AssumeUnreachable("Unknown expression type {0}", lexerNode.Type);
                break;
            }
            if (!(expectedType == null || expectedType.IsAuto()))
            {
                var ambiguous = ret as IAmbiguousNode;
                if (ambiguous != null)
                {
                    ret = ambiguous.RemoveAmbiguity(context, expectedType);
                }
            }

            return(ret);
        }
Exemplo n.º 5
0
        public static ExpressionNode Create(ContextNode context, ExpressionNode expression, InternalUnaryOperatorType op)
        {
            if (!expression.IsGettable)
            {
                ErrorCode.NotAnRValue.ReportAndThrow(expression.SequencePoint, "Unary operands must be gettable");
            }
            if (!expression.IsSettable && IsIncrementDecrement(op))
            {
                ErrorCode.NotAnLValue.ReportAndThrow(expression.SequencePoint, "Unary operation {0} requires a settable operand", op);
            }

            ExpressionNode result = AsBuiltIn(context, expression, op);

            if (result == null)
            {
                result = AsOverload(context, expression, op);
            }

            if (result == null)
            {
                OperatorMissmatch(expression.SequencePoint, op, expression.ExpressionReturnType);
            }

            Contract.Assume(result != null);
            return(result);
        }
        private static ExpressionNode AsMethod(ContextNode context, ExpressionNode node, IEnumerable <ExpressionNode> args, SequencePoint point)
        {
            var method = node as MethodNode;

            if (method != null)
            {
                if (MetadataHelpers.MatchesArgumentList(method.Method, args.Select(arg => arg.ExpressionReturnType).ToList()))
                {
                    return(new MethodCallNode(method, method.Method.GetReturnType(), args.ToList(), point));
                }
                else
                {
                    ErrorCode.TypeMismatch.ReportAndThrow(point, "Cannot call method, {0} requires parameters ({1}), called with ({2})",
                                                          method.Method.FullName,
                                                          String.Join(", ", method.Method.GetParameterTypes().Select(type => type.FullName)),
                                                          String.Join(", ", args.Select(a => a.ExpressionReturnType.FullName)));
                }
            }

            var ambiguous = node as AmbiguousMethodNode;

            if (ambiguous == null)
            {
                return(null);//not a method
            }
            method = ambiguous.RemoveAmbiguity(context, args.Select(a => a.ExpressionReturnType));
            if (method == null)
            {
                ErrorCode.TypeMismatch.ReportAndThrow(point, "Cannot call method, {0} with arguments ({1}), none of the overloads match",
                                                      ambiguous.Name,
                                                      String.Join(", ", args.Select(a => a.ExpressionReturnType.FullName)));
            }

            return(new MethodCallNode(method, method.Method.GetReturnType(), args.ToList(), point));
        }
Exemplo n.º 7
0
        private static ExpressionNode AsOverload(ContextNode context, ExpressionNode expression, InternalUnaryOperatorType op)
        {
            string name      = Overloads[op];
            var    point     = expression.SequencePoint;
            var    methods   = TypeUtils.GetOperatorMethods(context.Assembly, expression, name);
            var    argsTypes = expression.ExpressionReturnType.Enumerate();

            methods = methods.Where(m => MetadataHelpers.MatchesArgumentList(m, argsTypes));

            var method = AssemblyRegistry.GetCompatibleMethod(methods, argsTypes);

            if (method != null)
            {
                return(CreateOverload(context, expression, op, method));
            }
            else
            {
                if (methods.Count() == 0)
                {
                    return(null);
                }
                else
                {
                    ErrorCode.TypeMismatch.ReportAndThrow(point,
                                                          "Overloaded operator {0} for operand {1} is ambiguous",
                                                          name, expression.ExpressionReturnType.FullName);
                    return(null);//unreachable
                }
            }
        }
Exemplo n.º 8
0
        private static ExpressionNode AsBuiltIn(ContextNode context, ExpressionNode expression, InternalUnaryOperatorType op)
        {
            ExpressionNode instance = null;

            switch (op)
            {
            case InternalUnaryOperatorType.BinaryNot:
                instance = AsBinary(expression, op);
                break;

            case InternalUnaryOperatorType.LogicalNot:
                instance = AsLogical(expression, op);
                break;

            case InternalUnaryOperatorType.Negation:
                instance = AsNegation(expression, op);
                break;

            case InternalUnaryOperatorType.PostDecrement:
            case InternalUnaryOperatorType.PostIncrement:
            case InternalUnaryOperatorType.PreDecrement:
            case InternalUnaryOperatorType.PreIncrement:
                instance = AsInc(expression, op);
                break;

            default:
                ErrorCode.InvalidStructure.ReportAndThrow(expression.SequencePoint, "Unary op expected, '{0}' received", op);
                break;    //unreachable
            }
            return(instance);
        }
        public static ArrayCreationNode Parse(ContextNode context, IAbstractSyntaxTree lexerNode)
        {
            Contract.Requires(lexerNode.Type == Lexer.TokenType.ArrayLiteral);
            Contract.Ensures(Contract.Result <ArrayCreationNode>() != null);
            var point = context.Parser.GetSequencePoint(lexerNode);

            if (lexerNode.Children.Count == 1)
            {
                var initializer = InitializerList.Parse(context, lexerNode.Children[0]);
                return(Create(context, initializer, point));
            }
            else
            {
                var builder   = new TypeNode.TypeBuilder(context);
                var lexerType = lexerNode.Children[0];
                for (int i = 0; i < lexerType.Children.Count - 1; i++)
                {
                    builder.Append(lexerType.Children[i]);
                }
                //.Last() returns parameter list
                var last        = lexerType.Children.Last().Children[0];
                var elementType = builder.Type;
                IReadOnlyList <ExpressionNode> dims;
                if (ArrayAccessNode.IsEmptyIndexer(last))
                {
                    dims = Enumerable.Repeat((ExpressionNode)null, ArrayAccessNode.CountEmptyIndexerDims(last)).ToArray();
                }
                else
                {
                    dims = ArrayAccessNode.ParseIndex(context, last);
                }
                var initializer = InitializerList.Parse(context, lexerNode.Children[1]);
                return(Create(context, elementType, dims, initializer, point));
            }
        }
        public static MethodNode Parse(ContextNode context, IAbstractSyntaxTree lexerNode)
        {
            Contract.Requires(lexerNode.Type == Lexer.TokenType.Function);
            var method = FunctionDeclarationNode.ParseAsFunctor(context, lexerNode);

            return(new MethodNode(method.MethodReference, null, context, method.SequencePoint));
        }
        public override ExpressionNode GetSymbol(string name, ContextNode scope, SequencePoint point)
        {
            var field = GetField(name);

            if (field != null)
            {
                return(new FieldNode(null, field, scope, point));
            }

            var methods = GetMethods(name);

            if (scope.IsStaticContext())
            {
                methods = methods.Where(m => m.IsStatic());
            }

            if (methods.Count() > 0)
            {
                return(AmbiguousMethodNode.Create(methods, scope, null, point));
            }

            var type = GetContainedType(name);

            if (type != null)
            {
                return(TypeNode.Create(type, scope, point));
            }

            var namespaze = GetImportedNamespace(name, point);

            if (namespaze != null)
            {
                return(new NamespaceNode(namespaze, point));
            }

            type = GetImportedType(name, point);
            if (type != null)
            {
                return(TypeNode.Create(type, scope, point));
            }

            if (Parent != null)
            {
                return(Parent.GetSymbol(name, scope, point));
            }

            namespaze = Parser.ProjectParser.FindNamespace(name);
            if (namespaze != null)
            {
                return(new NamespaceNode(namespaze, point));
            }

            type = Parser.ProjectParser.FindType(name);
            if (type != null)
            {
                return(TypeNode.Create(type, scope, point));
            }

            return(null);
        }
        private ParameterDefinition ParseParameter(ContextNode parent, IAbstractSyntaxTree typeNode, IAbstractSyntaxTree nameNode)
        {
            var type = TypeNode.Parse(parent, typeNode);
            var name = nameNode.GetSingleSymbolOrThrow();

            return(new ParameterDefinition(name, ParameterAttributes.None, type));
        }
Exemplo n.º 13
0
        private void ResolveLiteralOperands(ContextNode context)
        {
            if (left.IsAssignableTo(right) || right.IsAssignableTo(left))
            {
                return;
            }

            if (right.ExpressionType == ExpressionNodeType.Literal)
            {
                var resolvedNode = ((LiteralNode)right).RemoveAmbiguity(context, left.ExpressionReturnType);

                if (resolvedNode.IsAssignableTo(left))
                {
                    right = resolvedNode;
                    return;
                }
            }

            if (left.ExpressionType == ExpressionNodeType.Literal)
            {
                var resolvedNode = ((LiteralNode)left).RemoveAmbiguity(context, right.ExpressionReturnType);

                if (resolvedNode.IsAssignableTo(right))
                {
                    left = resolvedNode;
                }
            }
        }
        public static CodeBlockNode Parse(ContextNode context, IAbstractSyntaxTree lexerNode)
        {
            Contract.Requires(lexerNode.Type.IsCodeConstruct());
            CodeBlockNode instance = null;

            if (lexerNode.Type == Lexer.TokenType.CodeBlockNode)
            {
                instance = new CodeBlockNode(context, context.Parser.GetSequencePoint(lexerNode));
                foreach (var node in lexerNode.Children)
                {
                    try
                    {
                        switch (node.Type)
                        {
                        case Lexer.TokenType.LeftCurlyBrace:
                        case Lexer.TokenType.RightCurlyBrace:
                            break;

                        default:
                            instance.AddNode(node);
                            break;
                        }
                    }
                    catch (CompilerException) { }//recover, continue parsing
                }
            }
            else
            {
                instance = new CodeBlockNode(context, context.Parser.GetSequencePoint(lexerNode));
                instance.AddNode(lexerNode);
            }
            return(instance);
        }
Exemplo n.º 15
0
        public static ExpressionNode AsOverload(ContextNode context, string name, ExpressionNode left, ExpressionNode right, SequencePoint point)
        {
            var methods = TypeUtils.GetOperatorMethods(context.Assembly, left, right, name);

            var args      = Utils.Utils.Enumerate(left, right);
            var argsTypes = args.Select(a => a.ExpressionReturnType).ToList();

            methods = methods.Where(m => MetadataHelpers.MatchesArgumentList(m, argsTypes));

            var method = AssemblyRegistry.GetCompatibleMethod(methods, argsTypes);

            if (method != null)
            {
                return(MethodCallNode.Create(context, new MethodNode(method, null, context, point), args, point));
            }
            else
            {
                if (methods.Count() == 0)
                {
                    return(null);
                }
                else
                {
                    ErrorCode.TypeMismatch.ReportAndThrow(point,
                                                          "Overloaded operator {0} for operands {1} and {2} is ambiguous",
                                                          name, left.ExpressionReturnType.FullName, right.ExpressionReturnType.FullName);
                    return(null);//unreachable
                }
            }
        }
        public new static TypeReference Parse(ContextNode parent, IAbstractSyntaxTree lexerNode)
        {
            Contract.Requires(lexerNode.Type == Lexer.TokenType.Type || lexerNode.Type == Lexer.TokenType.FullSymbol);
            Contract.Ensures(Contract.Result <TypeReference>() != null);
            if (lexerNode.Type == Lexer.TokenType.FullSymbol)
            {
                TypeNode node = DotOperatorNode.Parse(parent, lexerNode) as TypeNode;
                if (node != null)
                {
                    return(node.ParsedType);
                }
                else
                {
                    ErrorCode.TypeExpected.ReportAndThrow(parent.Parser.GetSequencePoint(lexerNode), "Type expected");
                }
            }

            TypeBuilder builder = new TypeBuilder(parent);

            foreach (var node in lexerNode.Children)
            {
                builder.Append(node);
            }

            return(builder.Type);
        }
Exemplo n.º 17
0
        public static ExpressionNode Parse(ContextNode context, IAbstractSyntaxTree lexerNode)
        {
            var left  = ExpressionNode.Parse(context, lexerNode.Children[0]);
            var right = ExpressionNode.Parse(context, lexerNode.Children[1], left.IsGettable ? left.ExpressionReturnType : null);
            var point = context.Parser.GetSequencePoint(lexerNode);

            return(Create(context, LexerToAssignemnt[lexerNode.Children[2].Type], left, right, point));
        }
        private static InitializerList CreateEmpty(ContextNode context, SequencePoint point)
        {
            var instace = new InitializerList(point);

            instace.Dimensions   = new int[] { 0 };
            instace.Initializers = Enumerable.Empty <ExpressionNode>();
            instace.ElementType  = context.Parser.Object;
            return(instace);
        }
Exemplo n.º 19
0
        public static ExpressionNode Parse(ContextNode context, IAbstractSyntaxTree lexerNode)
        {
            Contract.Requires(lexerNode.Type == Lexer.TokenType.InfixNode);
            var left   = ExpressionNode.Parse(context, lexerNode.Children[0]);
            var right  = ExpressionNode.Parse(context, lexerNode.Children[1]);
            var opType = lexerNode.Children[2].Type;

            return(Create(context, Operators[opType], left, right, context.Parser.GetSequencePoint(lexerNode)));
        }
        public static FunctionDeclarationNode ParseAsFunctor(ContextNode context, IAbstractSyntaxTree function)
        {
            Contract.Requires(function.Type == Lexer.TokenType.Function);
            var instance = new FunctionDeclarationNode(context, Modifiers.NoInstance | Modifiers.Private, context.GetClass().NewFunctionName(), function);

            context.GetClass().AddLambda(instance);
            instance.Emit();
            return(instance);
        }
        public override ExpressionNode GetSymbol(string name, ContextNode scope, SequencePoint point)
        {
            if (symbols.ContainsKey(name))
            {
                return(new ParameterNode(symbols[name], point));
            }

            return(Parent.GetSymbol(name, scope, point));
        }
 private TypeNode(TypeReference type, ContextNode scope, SequencePoint point)
     : base(type != null ? type.FullName : null, scope, point)
 {
     ParsedType = type;
     if (!type.IsAuto())
     {
         TypeUtils.VerifyAccessible(ParsedType, Scope.GetClass().TypeReference, point);
     }
 }
        public override ExpressionNode GetSymbol(string name, ContextNode scope, SequencePoint point)
        {
            if (name == variable.Variable.Name)
            {
                return(new LocalVariableNode(point, variable.Variable, true));
            }

            return(Parent.GetSymbol(name, scope, point));
        }
Exemplo n.º 24
0
 protected MemberNode(MemberReference member, ExpressionNode instance, ContextNode scope, SequencePoint point)
     : base(point)
 {
     Scope         = scope;
     DeclaringType = member.DeclaringType;
     Member        = member;
     TypeUtils.VerifyAccessible(Member, scope.GetClass().TypeReference, point);
     Instance = instance;
 }
        public static WhileBlock Parse(ContextNode context, IAbstractSyntaxTree lexerNode)
        {
            Contract.Requires(lexerNode.Type == TokenType.WhileLoop);
            var point     = context.Parser.GetSequencePoint(lexerNode);
            var condition = ExpressionNode.Parse(context, lexerNode.Children[2]);
            var block     = CodeBlockNode.Parse(context, lexerNode.Children[4]);

            return(Create(context, condition, block, point));
        }
Exemplo n.º 26
0
        public static LiteralNode Parse(ContextNode context, IAbstractSyntaxTree lexerNode)
        {
            Contract.Requires(lexerNode.Type == Lexer.TokenType.LiteralNode);
            lexerNode = lexerNode.Children[0];
            var point = context.Parser.GetSequencePoint(lexerNode);
            var type  = ParseLiteralType(context.Parser, lexerNode);

            return(ParseValue(context.Parser.ProjectParser, lexerNode.Content, type, point));
        }
Exemplo n.º 27
0
        public static SymbolDeclarationNode Create(ContextNode parent, Modifiers mods, TypeReference type, string name, ExpressionNode initializer, SequencePoint point)
        {
            if (initializer != null && !initializer.IsGettable)
            {
                ErrorCode.NotAnRValue.ReportAndThrow(point, "Initializer must be a gettable expression");
            }

            bool isConst = ParseModifiers(mods, point);

            if (isConst && initializer == null)
            {
                ErrorCode.MissingInit.ReportAndThrow(point, "Const variables require initialization");
            }

            if (type.IsAuto())
            {
                if (initializer == null)
                {
                    ErrorCode.MissingInit.ReportAndThrow(point, "Type inference requires initialization");
                    return(Utils.Utils.Fail <SymbolDeclarationNode>());
                }
                if (initializer.ExpressionReturnType.IsTypeless())
                {
                    ErrorCode.InferrenceFromTypeless.ReportAndThrow(initializer.SequencePoint, "Cannot infer type from a typeless expression");
                }
            }

            if (initializer != null)
            {
                if (type.IsAuto())
                {
                    type = initializer.ExpressionReturnType;
                }
                else
                {
                    var ambiguous = initializer as IAmbiguousNode;
                    if (ambiguous != null)
                    {
                        initializer = ambiguous.RemoveAmbiguity(parent, type);
                    }
                    if (!initializer.ExpressionReturnType.IsAssignableTo(type))
                    {
                        ErrorCode.TypeMismatch.ReportAndThrow(initializer.SequencePoint,
                                                              "Variable of type {0} initialized with {1}", type, initializer.ExpressionReturnType);
                    }
                }
            }

            if (type.IsVoid())
            {
                ErrorCode.VoidDeclaration.ReportAndThrow(point, "Cannot declare a variable of type void");
            }


            return(new SymbolDeclarationNode(new VariableDefinition(name, type), isConst, initializer, point));
        }
        public override ExpressionNode GetSymbol(string name, ContextNode scope, SequencePoint point)
        {
            if (symbols.ContainsKey(name))
            {
                SymbolDeclarationNode node = symbols[name];
                return(new LocalVariableNode(point, node.Variable, node.IsConst));
            }

            return(Parent.GetSymbol(name, scope, point));
        }
        public static ExpressionNode Parse(ContextNode context, IAbstractSyntaxTree lexerNode)
        {
            Contract.Requires(lexerNode.Type == Lexer.TokenType.PostfixNode);
            Contract.Requires(lexerNode.Children[1].Type == Lexer.TokenType.FunctionArgumentsList);
            var function = ExpressionNode.Parse(context, lexerNode.Children[0]);
            var args     = ParseArgList(context, lexerNode.Children[1]);
            var point    = context.Parser.GetSequencePoint(lexerNode.Children[1]);

            return(Create(context, function, args, point));
        }
Exemplo n.º 30
0
        public static SymbolDeclarationNode Parse(ContextNode context, IAbstractSyntaxTree lexerNode)
        {
            Contract.Requires(lexerNode.Type == Lexer.TokenType.DeclarationNode);
            var            info         = DeclarationInfo.Parse(context.Parser, lexerNode);
            var            name         = info.SymbolName.GetSingleSymbolOrThrow();
            var            declaredType = TypeNode.Parse(context, info.Type);
            var            point        = context.Parser.GetSequencePoint(lexerNode);
            ExpressionNode initializer  = info.Initializer == null ? null : ExpressionNode.Parse(context, info.Initializer, declaredType);

            return(Create(context, info.Modifiers, declaredType, name, initializer, point));
        }