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