Mercurial > projects > dang
changeset 172:01c2c49775ef
- Changed Parser to be more clean on type parsing.
- Parsing int function(int), and the like, types.(Function pointers)
- Fixed a design fault that made Symbol be wrong. Now Symbols are created with a factory with the help of types.
author | Anders Johnsen <skabet@gmail.com> |
---|---|
date | Thu, 24 Jul 2008 20:31:24 +0200 |
parents | f0385c044065 |
children | 50b98a06a200 |
files | ast/Decl.d ast/Exp.d lexer/Token.d parser/Action.d parser/Parser.d sema/AstAction.d sema/ScopeBuilder.d sema/ScopeCheck.d sema/Visitor.d tests/parser/function_pointer.d tools/AstPrinter.d |
diffstat | 11 files changed, 482 insertions(+), 376 deletions(-) [+] |
line wrap: on
line diff
--- a/ast/Decl.d Thu Jul 24 12:27:34 2008 +0200 +++ b/ast/Decl.d Thu Jul 24 20:31:24 2008 +0200 @@ -76,7 +76,7 @@ class VarDecl : Decl { - this(Identifier type, Identifier identifier, + this(IdentifierTypeExp type, Identifier identifier, Exp e = null) { super(DeclType.VarDecl); @@ -121,14 +121,14 @@ class FuncDecl : Decl { - this(Identifier type, Identifier identifier) + this(IdentifierTypeExp type, Identifier identifier) { super(DeclType.FuncDecl); this.returnType = type; this.identifier = identifier; } - void addParam(Identifier type, Identifier name = null) + void addParam(IdentifierTypeExp type, Identifier name = null) { funcArgs ~= new VarDecl(type, name, null); } @@ -246,8 +246,8 @@ this.identifier = identifier; auto name = new Identifier(identifier.loc, "__vptr"); - auto type = new Identifier(identifier.loc, "int"); - auto p_type = new PointerIdentifier(type); + auto type = new IdentifierTypeExp(identifier.loc, "int"); + auto p_type = new PointerTypeExp(type); decls ~= new VarDecl(p_type, name, null); }
--- a/ast/Exp.d Thu Jul 24 12:27:34 2008 +0200 +++ b/ast/Exp.d Thu Jul 24 20:31:24 2008 +0200 @@ -24,14 +24,17 @@ MemberReference, Index, Identifier, - ArrayIdentifier, - StaticArrayIdentifier, - PointerIdentifier, AssignExp, CallExp, CastExp, StringExp, NewExp, + + IdentifierTypeExp, + ArrayTypeExp, + StaticArrayTypeExp, + PointerTypeExp, + FunctionTypeExp, } abstract class Exp @@ -523,63 +526,6 @@ Symbol callSym; } -class PointerIdentifier : Identifier -{ - this(Identifier pointerOf) - { - super(ExpType.PointerIdentifier, pointerOf.loc); - this.pointerOf = pointerOf; - this.name = pointerOf.name; - } - - override DType type() - { - return pointerOf.type.getPointerTo(); - } - - Identifier pointerOf; -} - -class StaticArrayIdentifier : Identifier -{ - this(Identifier arrayOf, IntegerLit size) - { - super(ExpType.StaticArrayIdentifier, arrayOf.loc); - this.arrayOf = arrayOf; - this.size = Integer.parse(size.get); - this.name = arrayOf.name; - } - - override DType type() - { - return arrayOf.type.getAsStaticArray(size); - } - - Identifier arrayOf; - int size; - - private DType myType; -} - -class ArrayIdentifier : Identifier -{ - this(Identifier arrayOf) - { - super(ExpType.ArrayIdentifier, arrayOf.loc); - this.arrayOf = arrayOf; - this.name = arrayOf.name; - } - - override DType type() - { - return arrayOf.type.getAsArray(); - } - - Identifier arrayOf; - - private DType myType; -} - class Identifier : Exp { this(SLoc loc, char[] name) @@ -667,3 +613,101 @@ private DType myType; } +class IdentifierTypeExp : Identifier +{ + this(SLoc loc, char[] name) + { + super(ExpType.IdentifierTypeExp, loc); + this.name = name; + } + + protected this(ExpType t, SLoc loc) + { + super(t, loc); + } +} + +class PointerTypeExp : IdentifierTypeExp +{ + this(IdentifierTypeExp pointerOf) + { + super(ExpType.PointerTypeExp, pointerOf.loc); + this.pointerOf = pointerOf; + this.name = pointerOf.name; + } + + override DType type() + { + return pointerOf.type.getPointerTo(); + } + + Identifier pointerOf; +} + +class StaticArrayTypeExp : IdentifierTypeExp +{ + this(IdentifierTypeExp arrayOf, IntegerLit size) + { + super(ExpType.StaticArrayTypeExp, arrayOf.loc); + this.arrayOf = arrayOf; + this.size = Integer.parse(size.get); + this.name = arrayOf.name; + } + + override DType type() + { + return arrayOf.type.getAsStaticArray(size); + } + + Identifier arrayOf; + int size; + + private DType myType; +} + +class ArrayTypeExp : IdentifierTypeExp +{ + this(IdentifierTypeExp arrayOf) + { + super(ExpType.ArrayTypeExp, arrayOf.loc); + this.arrayOf = arrayOf; + this.name = arrayOf.name; + } + + override DType type() + { + return arrayOf.type.getAsArray(); + } + + Identifier arrayOf; + + private DType myType; +} + +class FunctionTypeExp : IdentifierTypeExp +{ + this(IdentifierTypeExp returnType, VarDecl[] decls) + { + super(ExpType.FunctionTypeExp, returnType.loc); + this.returnType = returnType; + this.decls = decls; + } + + override DType type() + { + if (myType) + return myType; + auto t = new DFunction(returnType); + t.returnType = returnType.type; + foreach (decl ; decls) + t.params ~= decl.identifier.type; + + myType = t.getPointerTo; + return myType; + } + + VarDecl[] decls; + IdentifierTypeExp returnType; + private DType myType; +} +
--- a/lexer/Token.d Thu Jul 24 12:27:34 2008 +0200 +++ b/lexer/Token.d Thu Jul 24 20:31:24 2008 +0200 @@ -255,6 +255,7 @@ Tok.Dchar:"Dchar", Tok.Bool:"Bool", Tok.Void:"Void", + Tok.Function:"Function", Tok.Eq:"Eq", Tok.Ne:"Ne", Tok.Lt:"Lt",
--- a/parser/Action.d Thu Jul 24 12:27:34 2008 +0200 +++ b/parser/Action.d Thu Jul 24 20:31:24 2008 +0200 @@ -40,11 +40,11 @@ Token tok; } -class PointerId : Id +class PointerTypeId : Id { - public static PointerId opCall(Id id) + public static PointerTypeId opCall(Id id) { - auto p = new PointerId(); + auto p = new PointerTypeId(); p.id = id; return p; } @@ -52,11 +52,11 @@ Id id; } -class StaticArrayId : Id +class StaticArrayTypeId : Id { - public static StaticArrayId opCall(Id id, Object number) + public static StaticArrayTypeId opCall(Id id, Object number) { - auto a = new StaticArrayId(); + auto a = new StaticArrayTypeId(); a.id = id; a.number = number; return a; @@ -66,6 +66,20 @@ Object number; } +class FunctionTypeId : Id +{ + public static FunctionTypeId opCall(Id id, DeclT[] decls) + { + auto f = new FunctionTypeId(); + f.id = id; + f.decls = decls; + return f; + } + + Id id; + DeclT[] decls; +} + /** Represents a fully qualified name, with some packages and a final identifier. The identifier should always be set, but packages may have length 0. @@ -85,6 +99,18 @@ } } + /** + A few aliases to indicate what methods should be dealing with the same + types. + Not typesafe, and not using typedef because users would need a lot of + casts (and base type would be void*, so no possibility to synchronize, + print etc.) + */ +alias Object ExprT; +alias Object StmtT; /// ditto +alias Object DeclT; /// ditto +alias Object ModuleT; /// ditto + /** All methods are optional. @@ -93,18 +119,7 @@ */ abstract class Action { - /** - A few aliases to indicate what methods should be dealing with the same - types. - Not typesafe, and not using typedef because users would need a lot of - casts (and base type would be void*, so no possibility to synchronize, - print etc.) - */ - alias Object ExprT; - alias Object StmtT; /// ditto - alias Object DeclT; /// ditto - alias Object ModuleT; /// ditto // -- Modules --
--- a/parser/Parser.d Thu Jul 24 12:27:34 2008 +0200 +++ b/parser/Parser.d Thu Jul 24 20:31:24 2008 +0200 @@ -74,76 +74,61 @@ Decl parseDecl(Attribute att) { - Token t = peek; - - if (t.isBasicType || t.isIdentifier) + switch(peek.type) { - Id type; - Id iden; - int len = peekParseType; - if (peek(len).type == Tok.Identifier && len != 0) - { - type = parseType; -parseDeclAfterInvalidType: - iden = Id(require(Tok.Identifier)); - if ( isa(Tok.Seperator) ) + case Tok.Struct: + Id type = Id(next()); + Id iden = Id(require(Tok.Identifier)); + return parseStruct(type, iden, att); + + case Tok.Class: + Id type = Id(next()); + Id iden = Id(require(Tok.Identifier)); + return parseClass(type, iden, att); + + case Tok.Interface: + Id type = Id(next()); + Id iden = Id(require(Tok.Identifier)); + return parseInterface(type, iden, att); + + case Tok.Identifier: + Id type = parseType; + Id iden = Id(require(Tok.Identifier)); + + switch(peek.type) { - Token sep = next(); - return action.actOnDeclarator(type, iden, null, att); + case Tok.Seperator: + Token sep = next(); + return action.actOnDeclarator(type, iden, null, att); + + case Tok.Assign: + Token assign = next(); + Exp exp = parseExpression(); + require(Tok.Seperator); + return action.actOnDeclarator(type, iden, exp, att); + + case Tok.OpenParentheses: + return parseFunc(type, iden, att); + + default: + auto n1 = next(); + messages.report(UnexpectedTok, n1.location).arg(n1.getType); + return null; } - else if ( isa(Tok.Assign) ) - { - Token assign = next(); - Exp exp = parseExpression(); - require(Tok.Seperator); - return action.actOnDeclarator(type, iden, exp, att); - } - else if ( isa(Tok.OpenParentheses) ) - return parseFunc(type, iden, att); - else - { - auto n1 = next(); - messages.report(UnexpectedTok, n1.location).arg(n1.getType); - } + messages.report(InvalidDeclType, peek.location) + .arg(sm.getText(peek.asRange)); + + default: + if (peek.isBasicType) + goto case Tok.Identifier; + + messages.report(UnexpectedTok, peek.location) + .arg(sm.getText(peek.asRange)); + return null; - } - t = peek(len); - messages.report(InvalidDeclType, t.location) - .arg(sm.getText(t.asRange)); - while(len--) - next(); - while( !isa(Tok.Identifier) && !isa(Tok.EOF)) - next(); - if ( isa(Tok.EOF ) ) - messages.report(UnexpectedTok, t.location) - .fatal(ExitLevel.Parser); - - type = Id(peek); - goto parseDeclAfterInvalidType; } - else if (t.type == Tok.Struct) - { - Id type = Id(next()); - Id iden = Id(require(Tok.Identifier)); - - return parseStruct(type, iden, att); - } - else if (t.type == Tok.Class) - { - Id type = Id(next()); - Id iden = Id(require(Tok.Identifier)); - - return parseClass(type, iden, att); - } - else if (t.type == Tok.Interface) - { - Id type = Id(next()); - Id iden = Id(require(Tok.Identifier)); - - return parseInterface(type, iden, att); - } - messages.report(UnexpectedTok, t.location) - .arg(t.getType) + messages.report(UnexpectedTok, peek.location) + .arg(peek.getType) .arg(Tok.Identifier) .fatal(ExitLevel.Parser); } @@ -536,169 +521,175 @@ */ Stmt parseStatement() { - Token t = peek; - - if (t.isReturn) - { - Token ret = next(); - Exp exp; - if (peek.type != Tok.Seperator) - exp = parseExpression(); - require(Tok.Seperator); - return action.actOnReturnStmt(ret, exp); - } - /* - if (cond) - single statement | compound statement - [else - single statement | compound statement] - */ - else if (t.isIf) - { - Token _if = next(); - - require(Tok.OpenParentheses); - Exp cond = parseExpression(); - require(Tok.CloseParentheses); - - Stmt thenB = parseSingleOrCompoundStatement(); - - // if there is no else part we use the if as token, to have - // something than can be passed along - Token _else = _if; - Stmt elseB; - if (peek.type == Tok.Else) - { - _else = next(); - elseB = parseSingleOrCompoundStatement(); - } - - return action.actOnIfStmt(_if, cond, thenB, _else, elseB); - - } - /* - while (cond) - single statement | compound statement - */ - else if (t.isWhile) - { - Token _while = next(); - require(Tok.OpenParentheses); - Exp cond = parseExpression(); - require(Tok.CloseParentheses); - Stmt bodyStmt = parseSingleOrCompoundStatement(); - return action.actOnWhileStmt(_while, cond, bodyStmt); - - } - else if (t.isFor) + switch (peek.type) { - Token _for = next(); - require(Tok.OpenParentheses); - Stmt init; - if ( isa(Tok.Seperator)) + case Tok.Return: + Token ret = next(); + Exp exp; + if (peek.type != Tok.Seperator) + exp = parseExpression(); require(Tok.Seperator); - else - init = parseStatement(); + return action.actOnReturnStmt(ret, exp); + + case Tok.If: + Token _if = next(); + + require(Tok.OpenParentheses); + Exp cond = parseExpression(); + require(Tok.CloseParentheses); + + Stmt thenB = parseSingleOrCompoundStatement(); - Exp cond; - if ( !isa(Tok.Seperator)) - cond = parseExpression(); - require(Tok.Seperator); + // if there is no else part we use the if as token, to have + // something than can be passed along + Token _else = _if; + Stmt elseB; + if (peek.type == Tok.Else) + { + _else = next(); + elseB = parseSingleOrCompoundStatement(); + } + return action.actOnIfStmt(_if, cond, thenB, _else, elseB); - Exp incre; - if ( !isa(Tok.CloseParentheses)) - incre = parseExpression(); - require(Tok.CloseParentheses); + case Tok.While: + Token _while = next(); + require(Tok.OpenParentheses); + Exp cond = parseExpression(); + require(Tok.CloseParentheses); + Stmt bodyStmt = parseSingleOrCompoundStatement(); + return action.actOnWhileStmt(_while, cond, bodyStmt); + + case Tok.For: + Token _for = next(); + require(Tok.OpenParentheses); + Stmt init; + if ( isa(Tok.Seperator)) + require(Tok.Seperator); + else + init = parseStatement(); - Stmt bodyStmt = parseSingleOrCompoundStatement(); - return action.actOnForStmt(_for, init, cond, incre, bodyStmt); - } - else if (t.isBasicType || t.isIdentifier) - { - Token iden = peek; - Token n = peek(1); - // Must be an decl, if we start with a basic type, or two - // identifiers in a row - if ( n.type == Tok.Star || n.type == Tok.OpenBracket) - { - int len = peekParseType; - if(peek(len).type == Tok.Identifier && len != 0) - return action.actOnDeclStmt(parseVarDecl()); + Exp cond; + if ( !isa(Tok.Seperator)) + cond = parseExpression(); + require(Tok.Seperator); - Exp exp = parseExpression(); - require(Tok.Seperator); - return action.actOnExprStmt(exp); - } + Exp incre; + if ( !isa(Tok.CloseParentheses)) + incre = parseExpression(); + require(Tok.CloseParentheses); + + Stmt bodyStmt = parseSingleOrCompoundStatement(); + return action.actOnForStmt(_for, init, cond, incre, bodyStmt); - if (n.isIdentifier()) - return action.actOnDeclStmt(parseVarDecl()); + case Tok.Switch: + auto t = next(); + require(Tok.OpenParentheses); + auto target = parseExpression(); + auto res = action.actOnStartOfSwitchStmt(t, target); + require(Tok.CloseParentheses); + require(Tok.OpenBrace); + while (true) + { + Stmt[] statements; + if (isa(Tok.Default)) + { + Token _default = next(); + require(Tok.Colon); + statements.length = 0; + while (peek.type != Tok.Case + && peek.type != Tok.Default + && peek.type != Tok.CloseBrace) + statements ~= parseStatement(); + action.actOnDefaultStmt(res, _default, statements); + continue; + } - // Expression: a.b, a = b, a(b) etc. - Exp exp = parseExpression(); - require(Tok.Seperator); - return action.actOnExprStmt(exp); - } - else if (t.isSwitch) - { - next(); - require(Tok.OpenParentheses); - auto target = parseExpression(); - auto res = action.actOnStartOfSwitchStmt(t, target); - require(Tok.CloseParentheses); - require(Tok.OpenBrace); - while (true) - { - Stmt[] statements; - if (isa(Tok.Default)) - { - Token _default = next(); + Token _case = peek; + if (_case.type != Tok.Case) + break; + next(); + + Exp[] literals; + do + { + Exp e = parseExpression(); + literals ~= e; + } + while (skip(Tok.Comma)); require(Tok.Colon); - statements.length = 0; + while (peek.type != Tok.Case && peek.type != Tok.Default && peek.type != Tok.CloseBrace) statements ~= parseStatement(); - action.actOnDefaultStmt(res, _default, statements); - continue; + + action.actOnCaseStmt(res, _case, literals, statements); + + if (peek.type == Tok.CloseBrace) + break; + } + require(Tok.CloseBrace); + return res; + + case Tok.Star: + auto exp = parseExpression(); + require(Tok.Seperator); + return action.actOnExprStmt(exp); + + case Tok.Identifier: + // If it's a '*' it must be a method. Otherwise it won't give + // any sense. + if (isa(Tok.Function, 1) || + isa(Tok.Identifier, 1) || + isa(Tok.Star, 1)) + return action.actOnDeclStmt(parseDecl(Attribute())); + + if (isa(Tok.OpenBracket, 1)) + { + int i = 1; + while (isa(Tok.OpenBracket, i) || + isa(Tok.Star, i) || + isa(Tok.Identifier, i)) + { + if (isa(Tok.Identifier, i)) + return action.actOnDeclStmt(parseDecl(Attribute())); + + i++; + if (isa(Tok.Star,i-1)) + continue; + // Must be OpenBracket here.. + + if (isa(Tok.Integer, i)) + i++; + else + if (isa(Tok.CloseBracket, i)) + return action.actOnDeclStmt(parseDecl(Attribute())); + else + i++; + + if (!isa(Tok.CloseBracket, i)) + break; + i++; + } + if (isa(Tok.Function, i)) + return action.actOnDeclStmt(parseDecl(Attribute())); } - Token _case = peek; - if (_case.type != Tok.Case) - break; - next(); - - Exp[] literals; - do - { - Exp e = parseExpression(); - literals ~= e; - } - while (skip(Tok.Comma)); - require(Tok.Colon); - - while (peek.type != Tok.Case - && peek.type != Tok.Default - && peek.type != Tok.CloseBrace) - statements ~= parseStatement(); + // Expression: a.b, a = b, a(b) etc. + Exp exp = parseExpression(); + require(Tok.Seperator); + return action.actOnExprStmt(exp); + + case Tok.Void: // And all basic types + return action.actOnDeclStmt(parseVarDecl()); - action.actOnCaseStmt(res, _case, literals, statements); + default: + if (peek.isBasicType) + goto case Tok.Void; - if (peek.type == Tok.CloseBrace) - break; - } - require(Tok.CloseBrace); - return res; - } - else if (t.type == Tok.Star) - { - auto exp = parseExpression(); - require(Tok.Seperator); - return action.actOnExprStmt(exp); - } - else - { - messages.report(UnexpectedBeginStmt, t.location).arg(t.getType); - return null; + messages.report(UnexpectedBeginStmt, peek.location).arg(peek.getType); + require(Tok.Seperator); + return null; } } @@ -833,70 +824,56 @@ messages.report(InvalidType, type.location); currentType = Id(type); - type = peek; - while(type.type == Tok.Star || type.type == Tok.OpenBracket) + while(true) { - if(type.type == Tok.Star) - { - currentType = PointerId(currentType); - next(); - } - else + switch(peek.type) { - next(); - if(peek.type == Tok.Integer) - currentType = StaticArrayId( - currentType, - action.actOnNumericConstant( - require(Tok.Integer))); - require(Tok.CloseBracket); + case Tok.Star: + currentType = PointerTypeId(currentType); + next(); + break; + case Tok.OpenBracket: + next(); + if (isa(Tok.Integer)) + currentType = StaticArrayTypeId( + currentType, + action.actOnNumericConstant( + require(Tok.Integer))); + require(Tok.CloseBracket); + break; + case Tok.Function: + next(); - } - type = peek; - } - return currentType; - } - - int peekParseType() - { - int i; - Token type = peek(i); + require(Tok.OpenParentheses); // Remove the "(" token. - Id currentType; + DeclT[] decls; - if ( !(type.isBasicType || type.type == Tok.Identifier) ) - return 0; + while(peek.type != Tok.CloseParentheses) + { + auto t = parseType(); + Id i; + if(peek.type == Tok.Identifier) + i = parseIdentifier(); - currentType = Id(type); - type = peek(++i); + // Act on function type param + decls ~= action.actOnDeclarator(t, i, null, Attribute()); + + if(peek.type == Tok.Comma) + next(); + } - while(type.type == Tok.Star || type.type == Tok.OpenBracket) - { - if(type.type == Tok.Star) - { - i++; + currentType = FunctionTypeId(currentType, decls); + + require(Tok.CloseParentheses); // Remove the ")" + break; + default: + goto end; } - else - { - if(peek(i++).type != Tok.OpenBracket) - return 0; - if(peek(i).type == Tok.Integer) - { - i++; - if(peek(i++).type != Tok.CloseBracket) - return 0; - } - else - if(peek(i++).type != Tok.CloseBracket) - return 0; - - } - type = peek(i); } - - return i; +end: + return currentType; } private: @@ -1143,9 +1120,9 @@ return true; } - bool isa(Tok t) + bool isa(Tok t, int i = 0) { - return peek.type == t; + return peek(i).type == t; } Token next()
--- a/sema/AstAction.d Thu Jul 24 12:27:34 2008 +0200 +++ b/sema/AstAction.d Thu Jul 24 20:31:24 2008 +0200 @@ -27,14 +27,16 @@ } private SourceManager sm; - private Identifier handleType(Id type) + private IdentifierTypeExp handleType(Id type) { - if(auto t = cast(PointerId)type) - return new PointerIdentifier(handleType(t.id)); - if(auto t = cast(StaticArrayId)type) - return new StaticArrayIdentifier(handleType(t.id), cast(IntegerLit)t.number); - else - return identifierFromTok(type.tok); + if(auto t = cast(PointerTypeId)type) + return new PointerTypeExp(handleType(t.id)); + if(auto t = cast(StaticArrayTypeId)type) + return new StaticArrayTypeExp(handleType(t.id), cast(IntegerLit)t.number); + if(auto t = cast(FunctionTypeId)type) + return new FunctionTypeExp(handleType(t.id), cast(VarDecl[])t.decls); + + return new IdentifierTypeExp(type.tok.location, sm.getText(type.tok.asRange)); } private Identifier identifierFromTok(Token t) @@ -139,7 +141,7 @@ DeclT actOnStartOfFunctionDef(ref Id type, ref Id name, Attribute att) { - auto res = new FuncDecl(identifierFromTok(type.tok), identifierFromTok(name.tok)); + auto res = new FuncDecl(handleType(type), identifierFromTok(name.tok)); res.att = att; return res; } @@ -150,7 +152,7 @@ if(name) fd.addParam(handleType(type), identifierFromTok(name.tok)); else - fd.addParam(identifierFromTok(type.tok)); + fd.addParam(handleType(type)); } DeclT actOnEndOfFunction(DeclT func, StmtT stmts)
--- a/sema/ScopeBuilder.d Thu Jul 24 12:27:34 2008 +0200 +++ b/sema/ScopeBuilder.d Thu Jul 24 20:31:24 2008 +0200 @@ -10,11 +10,33 @@ import sema.Visitor, basic.SmallArray; +class SymbolFactory +{ + void put(Symbol symbol, DType type) + { + types[type] = symbol; + } + + Symbol get(Symbol owner, DType type, Identifier i, Decl decl) + { + if (type in types) + return owner.createAlias(i.get, types[type], decl); + else + return owner.createMember(i.get, type, decl); + } + + Symbol[DType] types; +} + class ForwardReference : Visitor!(void) { + this(SymbolFactory sf) + { + this.sf = sf; + } override void visit(Module[] modules) { - (new TypeBuilder).visit(modules); + (new TypeBuilder(sf)).visit(modules); this.modules = modules; inFunctionBodyStack.push(false); foreach (mod; modules) @@ -62,10 +84,7 @@ visitExp(d.init); DType t = typeOf(d.varType, d.env); - d.sym = current.symbol.createAlias( - d.identifier.get, - d.env.find(d.varType.get)[0].sym, - d); + d.sym = sf.get(current.symbol, t, d.identifier, d); d.sym.type = t; } @@ -99,22 +118,40 @@ current.symbol = old; } + override void visitFunctionTypeExp(FunctionTypeExp f) + { + } + DType typeOf(Identifier id, Scope sc) { - if(auto i = cast(PointerIdentifier)id) + if(auto i = cast(PointerTypeExp)id) return (typeOf(i.pointerOf, sc)).getPointerTo(); - else if(auto i = cast(StaticArrayIdentifier)id) + else if(auto i = cast(StaticArrayTypeExp)id) return typeOf(i.arrayOf, sc).getAsStaticArray(i.size); + else if(auto i = cast(FunctionTypeExp)id) + { + auto d = new DFunction(id); + d.returnType = typeOf(i.returnType, sc); + foreach (decl ; i.decls) + d.params ~= typeOf(decl.varType, sc); + return d; + } return sc.findType(id.get); } Module[] modules; Module current; SmallArray!(bool) inFunctionBodyStack; + SymbolFactory sf; } class TypeBuilder : Visitor!(void) { + this(SymbolFactory sf) + { + this.sf = sf; + } + override void visit(Module[] modules) { foreach (mod; modules) @@ -132,6 +169,7 @@ s.identifier.get, st, s.env.find(s.identifier.get)[0]); + sf.put(s.sym, st); foreach (decl; s.decls) { @@ -160,6 +198,8 @@ st, s.env.find(s.identifier.get)[0]); + sf.put(s.sym, st); + foreach (decl; s.decls) { DType type; @@ -186,6 +226,7 @@ s.identifier.get, st, s.env.find(s.identifier.get)[0]); + sf.put(s.sym, st); foreach (decl; s.decls) { @@ -209,14 +250,15 @@ DType typeOf(Identifier id, Scope sc) { - if(auto i = cast(PointerIdentifier)id) + if(auto i = cast(PointerTypeExp)id) return (typeOf(i.pointerOf, sc)).getPointerTo(); - else if(auto i = cast(StaticArrayIdentifier)id) + else if(auto i = cast(StaticArrayTypeExp)id) return typeOf(i.arrayOf, sc).getAsStaticArray(i.size); return sc.findType(id.get); } Module current; + SymbolFactory sf; } @@ -235,6 +277,7 @@ this() { + sf = new SymbolFactory(); } override void visit(Module[] modules) @@ -242,7 +285,7 @@ foreach(m ; modules) visitModule(m); - auto fr = new ForwardReference(); + auto fr = new ForwardReference(sf); fr.visit(modules); } @@ -446,6 +489,7 @@ private: Scope[] table; + SymbolFactory sf; Scope push() {
--- a/sema/ScopeCheck.d Thu Jul 24 12:27:34 2008 +0200 +++ b/sema/ScopeCheck.d Thu Jul 24 20:31:24 2008 +0200 @@ -29,7 +29,7 @@ override void visitVarDecl(VarDecl d) { - if(!d.env.findType(d.varType.get)) + if(d.identifier.get is null) messages.report(UndefinedType, d.varType.loc) .arg(d.varType.get);
--- a/sema/Visitor.d Thu Jul 24 12:27:34 2008 +0200 +++ b/sema/Visitor.d Thu Jul 24 20:31:24 2008 +0200 @@ -99,10 +99,14 @@ return visitCastExp(cast(CastExp)exp); case ExpType.Identifier: return visitIdentifier(cast(Identifier)exp); - case ExpType.PointerIdentifier: - return visitPointerIdentifier(cast(PointerIdentifier)exp); - case ExpType.StaticArrayIdentifier: - return visitStaticArrayIdentifier(cast(StaticArrayIdentifier)exp); + case ExpType.IdentifierTypeExp: + return visitIdentifier(cast(Identifier)exp); + case ExpType.PointerTypeExp: + return visitPointerTypeExp(cast(PointerTypeExp)exp); + case ExpType.StaticArrayTypeExp: + return visitStaticArrayTypeExp(cast(StaticArrayTypeExp)exp); + case ExpType.FunctionTypeExp: + return visitFunctionTypeExp(cast(FunctionTypeExp)exp); case ExpType.StringExp: return visitStringExp(cast(StringExp)exp); case ExpType.Index: @@ -387,7 +391,7 @@ return ExpT.init; } - ExpT visitPointerIdentifier(PointerIdentifier exp) + ExpT visitPointerTypeExp(PointerTypeExp exp) { visitExp(exp.pointerOf); @@ -397,7 +401,7 @@ return ExpT.init; } - ExpT visitStaticArrayIdentifier(StaticArrayIdentifier exp) + ExpT visitStaticArrayTypeExp(StaticArrayTypeExp exp) { visitExp(exp.arrayOf); @@ -407,6 +411,19 @@ return ExpT.init; } + ExpT visitFunctionTypeExp(FunctionTypeExp exp) + { + visitExp(exp.returnType); + + foreach (decl ; exp.decls) + visitDecl(decl); + + static if (is(ExpT == void)) + return; + else + return ExpT.init; + } + ExpT visitIndexExp(IndexExp exp) { visitExp(exp.target);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/parser/function_pointer.d Thu Jul 24 20:31:24 2008 +0200 @@ -0,0 +1,6 @@ + +int main() +{ +} + +int function(int x) f;
--- a/tools/AstPrinter.d Thu Jul 24 12:27:34 2008 +0200 +++ b/tools/AstPrinter.d Thu Jul 24 20:31:24 2008 +0200 @@ -197,8 +197,8 @@ auto iden = cast(Identifier)exp; printIdentifier(iden); break; - case ExpType.PointerIdentifier: - auto iden = cast(PointerIdentifier)exp; + case ExpType.PointerTypeExp: + auto iden = cast(PointerTypeExp)exp; printExp(iden.pointerOf); print("*"); break;