Exemple #1
0
        Declaration ParseDeclaration()
        {
            var decl = new Declaration();

            if (PeekElement().Type == Token.GlobalIdentifier)
            {
                decl.Name = AcceptElement(Token.GlobalIdentifier).Data;

                AcceptElement(Token.Assign);

                AcceptElementIfNext(Token.Common);
                AcceptElementIfNext(Token.Private);
                bool ext = AcceptElementIfNext(Token.External);
                decl.External = ext;
                AcceptElementIfNext(Token.LocalUnnamedAddr);

                if (PeekElement().Type == Token.Global)
                {
                    AcceptElement(Token.Global);
                    decl.Global = true;
                    decl.Type   = ParseType();
                    Debug.Assert(decl.Type != null);

                    if (!ext)
                    {
                        if (AcceptElementIfNext(Token.ZeroInitializer))
                        {
                            decl.InitializeToZero = true;
                        }
                        else
                        {
                            if (PeekElement().Type != Token.Null)
                            {
                                decl.Expr = ParseExpression();
                            }
                            else
                            {
                                AcceptElement(Token.Null);
                            }
                        }
                    }
                }
                else
                {
                    while (PeekElement().Type == Token.Symbol)
                    {
                        AcceptElement(Token.Symbol);
                    }

                    decl.Constant = AcceptElementIfNext(Token.Constant);

                    if (PeekElement().Type == Token.BracketOpen)
                    {
                        AcceptElement(Token.BracketOpen);
                        var arr = new ArrayReference();

                        arr.ArrayX = int.Parse(AcceptElement(Token.IntegerLiteral).Data);
                        AcceptElement(Token.Symbol);
                        arr.BaseType = ParseType();

                        /*while (PeekElement().Type != Token.BracketClose)
                         * {
                         *
                         *  AcceptElement(PeekElement().Type);
                         * }*/
                        AcceptElement(Token.BracketClose);
                        decl.Type = arr;
                    }

                    if (PeekElement().Type == Token.StringLiteral)
                    {
                        decl.Value = AcceptElement(Token.StringLiteral).Data;
                    }
                    else
                    {
                        decl.Expr = ParseExpression();
                    }
                }

                if (AcceptElementIfNext(Token.Comma))
                {
                    if (PeekElement().Type == Token.Comdat)
                    {
                        AcceptElement(Token.Comdat);
                        AcceptElement(Token.Comma);
                    }

                    AcceptElement(Token.Align);
                    AcceptElement(Token.IntegerLiteral);
                }
            }
            else if (PeekElement().Type == Token.Declare)
            {
                decl.Declare = true;
                // declare i32 @printf(i8*, ...) #1

                AcceptElement(Token.Declare);
                AcceptElementIfNext(Token.ZeroExt); // TODO: Handle properly?
                ParseType();

                decl.Name = AcceptElement(Token.GlobalIdentifier).Data;
                AcceptElement(Token.ParenOpen);

                if (!AcceptElementIfNext(Token.Ellipsis))
                {
                    // TODO Refactor this idiocy.
                    if (PeekElement().Type != Token.ParenClose)
                    {
                        ParseType();
                        AcceptElementIfNext(Token.Byval);
                        if (AcceptElementIfNext(Token.Align))
                        {
                            AcceptElement(Token.IntegerLiteral);
                        }
                        AcceptElementIfNext(Token.NoCapture);
                        AcceptElementIfNext(Token.WriteOnly);
                        AcceptElementIfNext(Token.ReadOnly);

                        while (AcceptElementIfNext(Token.Comma))
                        {
                            if (AcceptElementIfNext(Token.Ellipsis))
                            {
                                break;
                            }
                            ParseType();
                            AcceptElementIfNext(Token.Byval);
                            if (AcceptElementIfNext(Token.Align))
                            {
                                AcceptElement(Token.IntegerLiteral);
                            }
                            AcceptElementIfNext(Token.NoCapture);
                            AcceptElementIfNext(Token.ReadOnly);
                        }
                    }
                }

                AcceptElement(Token.ParenClose);
                AcceptElementIfNext(Token.LocalUnnamedAddr);

                if (AcceptElementIfNext(Token.Hash))
                {
                    AcceptElement(Token.IntegerLiteral);
                }
            }
            return(decl);
        }
Exemple #2
0
        TypeReference ParseType()
        {
            TypeReference decl;// = new TypeReference();
            var           el = PeekElement();

            switch (el.Type)
            {
            case Token.I64:
            case Token.I32:
            case Token.I16:
            case Token.I8:
            case Token.I1:
            case Token.Void:
                decl = new DefinedTypeReference(internalTypes[el.Type]);
                AcceptElement(el.Type);
                break;

            case Token.BracketOpen:
            {
                AcceptElement(Token.BracketOpen);
                var arr = new ArrayReference();
                arr.ArrayX = int.Parse(AcceptElement(Token.IntegerLiteral).Data);
                AcceptElement(Token.Symbol);
                arr.BaseType = ParseType();
                //new DefinedTypeReference(internalTypes[AcceptElement(Token.I32, Token.I16, Token.I8).Type]);
                AcceptElement(Token.BracketClose);
                decl = arr;
            }
            break;

            case Token.LocalIdentifier:
            {
                var id = AcceptElement(Token.LocalIdentifier);
                if (types.ContainsKey(id.Data))
                {
                    decl = new DefinedTypeReference(types[id.Data]);
                }
                else
                {
                    decl = new DefinedTypeReference(id.Data);
                }
            }
            break;

            default:
                throw new Exception();
            }

            while (PeekElement().Type == Token.Asterisk)
            {
                AcceptElement(Token.Asterisk);
                var ptr = new PointerReference();
                ptr.BaseType = decl;
                decl         = ptr;
            }

            if (PeekElement().Type == Token.ParenOpen)
            {
                var ftype = new FunctionTypeReference
                {
                    ReturnValue = decl
                };
                decl = ftype;
                AcceptElement(Token.ParenOpen);
                // Parameter list
                while (true)
                {
                    if (PeekElement().Type == Token.Ellipsis)
                    {
                        AcceptElement(Token.Ellipsis);
                        break;
                    }

                    ftype.Parameters.Add(ParseType());
                    if (PeekElement().Type == Token.ParenClose)
                    {
                        break;
                    }
                    AcceptElement(Token.Comma);
                }

                AcceptElement(Token.ParenClose);
            }

            while (AcceptElementIfNext(Token.Asterisk))
            {
                var ptype = new PointerReference();
                ptype.BaseType = decl;
                decl           = ptype;
            }

            return(decl);
        }