コード例 #1
0
 public FunctionNode(Token sourceToken, IdentifierNode identifier, FunctionParameterNode[] parameters, TypeIdentifierNode type, BlockNode body) : base(sourceToken)
 {
     Identifier = identifier;
     Parameters = parameters;
     Type       = type;
     Body       = body;
 }
コード例 #2
0
        public ASTNode Parse(Token sourceToken, ParseContext context)
        {
            var typeID = TypeIdentifierNode.Parse(context);

            // stupid hack: if we parsed an array type, then "peel off" the last array expression and use it as an array initializer
            // dumb? yes. works? also yes.
            if (typeID.IsArray)
            {
                if (typeID.ArraySizeExpression == null)
                {
                    throw new CompileException(typeID.Source, "Array size expected");
                }

                ASTNode sizeExpr = typeID.ArraySizeExpression;
                typeID.IsArray             = false; // TODO: really ought to support nested arrays
                typeID.ArraySizeExpression = null;

                return(new NewArrayNode(sourceToken, typeID, sizeExpr));
            }
            else
            {
                // otherwise this is a new object expression which invokes a constructor
                if (!typeID.IsMinimal)
                {
                    context.Errors.Add(new CompileError(typeID.Source, "Incompatible type for 'new' keyword here"));
                }

                context.Expect(TokenType.OpenParenthesis);

                List <ASTNode> args = new List <ASTNode>();

                if (!context.TryMatch(TokenType.CloseParenthesis))
                {
                    do
                    {
                        args.Add(context.ParseExpression());
                    } while(context.TryMatch(TokenType.Comma));

                    context.Expect(TokenType.CloseParenthesis);
                }

                return(new NewNode(sourceToken, typeID, args.ToArray()));
            }
        }
コード例 #3
0
        public ASTNode Parse(Token sourceToken, ParseContext context)
        {
            IdentifierNode            interfaceID = context.ParseExpression <IdentifierNode>();
            List <TypeIdentifierNode> interfaces  = new List <TypeIdentifierNode>();

            if (context.TryMatch(TokenType.Colon))
            {
                do
                {
                    TypeIdentifierNode interfaceType = TypeIdentifierNode.ParseMinimal(context);
                    interfaces.Add(interfaceType);
                } while(context.TryMatch(TokenType.Comma));
            }

            BlockNode block = context.ParseExpression <BlockNode>();

            List <FunctionNode> functions = new List <FunctionNode>();

            foreach (var expr in block.Children)
            {
                if (expr is FunctionNode func)
                {
                    if (func.Body != null)
                    {
                        context.Errors.Add(new CompileError(func.Source, "Interface function definition must be abstract"));
                    }
                    else
                    {
                        functions.Add(func);
                    }
                }
                else
                {
                    context.Errors.Add(new CompileError(expr.Source, "Only functions can be declared in an interface block"));
                }
            }

            return(new InterfaceNode(sourceToken, interfaceID, interfaces.ToArray(), functions.ToArray()));
        }
コード例 #4
0
        public ASTNode Parse(Token sourceToken, ParseContext context)
        {
            var identifier = context.ParseExpression <IdentifierNode>();

            context.Expect(TokenType.OpenParenthesis);

            List <FunctionParameterNode> parameters = new List <FunctionParameterNode>();

            if (!context.TryMatch(TokenType.CloseParenthesis))
            {
                do
                {
                    parameters.Add(FunctionParameterNode.Parse(context));
                } while(context.TryMatch(TokenType.Comma));

                context.Expect(TokenType.CloseParenthesis);
            }

            // note: type is optional, but if omitted means "void" is assumed
            TypeIdentifierNode type = null;

            if (context.TryMatch(TokenType.Colon))
            {
                type = TypeIdentifierNode.Parse(context);
            }

            if (context.TryMatch(TokenType.Semicolon))
            {
                return(new FunctionNode(sourceToken, identifier, parameters.ToArray(), type, null));
            }
            else
            {
                BlockNode body = context.ParseExpression <BlockNode>();
                return(new FunctionNode(sourceToken, identifier, parameters.ToArray(), type, body));
            }
        }
コード例 #5
0
ファイル: NewNode.cs プロジェクト: GlaireDaggers/cozi-lang
 public NewNode(Token sourceToken, TypeIdentifierNode type, ASTNode[] args)
     : base(sourceToken)
 {
     Type = type;
     ConstructorArguments = args;
 }
コード例 #6
0
 public NewArrayNode(Token sourceToken, TypeIdentifierNode type, ASTNode sizeExpr)
     : base(sourceToken)
 {
     Type     = type;
     SizeExpr = sizeExpr;
 }