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>()); }
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); }
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)); }
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 } } }
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)); }
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); }
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); }
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); }
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)); }
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)); }
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)); }
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)); }
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)); }