# HG changeset patch # User Anders Johnsen # Date 1216933398 -7200 # Node ID dc9bf56b7ace34a2386e04555a891721c1113499 # Parent c8e26556c24dc36fee7348850ccef62931ab49e4 Can now use & as a unary operator and take an AddressOf diff -r c8e26556c24d -r dc9bf56b7ace ast/Exp.d --- a/ast/Exp.d Thu Jul 24 21:12:12 2008 +0200 +++ b/ast/Exp.d Thu Jul 24 23:03:18 2008 +0200 @@ -20,6 +20,7 @@ Binary, Negate, Deref, + AddressOfExp, IntegerLit, MemberReference, Index, @@ -306,6 +307,33 @@ public Exp exp; } +class AddressOfExp : Exp +{ + this(SLoc op, Exp exp) + { + super(ExpType.AddressOfExp, op); + this.exp = exp; + } + + override AddressOfExp simplify() + { + exp = exp.simplify(); + return this; + } + + override DType type() + { + return exp.type().getPointerTo; + } + + override SourceRange sourceRange() + { + return SourceRange(loc) + exp.sourceRange; + } + + public Exp exp; +} + class IntegerLit : Exp { this(SLoc loc, char[] t) diff -r c8e26556c24d -r dc9bf56b7ace dang/compiler.d --- a/dang/compiler.d Thu Jul 24 21:12:12 2008 +0200 +++ b/dang/compiler.d Thu Jul 24 23:03:18 2008 +0200 @@ -43,7 +43,7 @@ void checkFiles(char[][] *files) { - GC.disable(); +// GC.disable(); bool non_existant_files = false; bool duplicate_files = false; @@ -116,6 +116,9 @@ argParse.addOption(["--ast-dump-code"], "what-to-do", Opt.Action.StoreConst, "code") .help("Output the AST as code"); + argParse.addOption(["--semantic-only"], + "what-to-do", Opt.Action.StoreConst, "exit") + .help("Exit after semantics and before codegen"); argParse.addOption(["--gen-llvm"], "what-to-do", Opt.Action.StoreConst, "gen-llvm") .help("Compile to LLVM code (default)"); @@ -218,6 +221,10 @@ print.print(m); timings ~= Measurement("Converting AST to text", w.stop); }); + else if (what == "exit") + postSema.attach( + (Module[] modules, SourceManager sm) { + }); StopWatch total; total.start; diff -r c8e26556c24d -r dc9bf56b7ace lexer/Lexer.d --- a/lexer/Lexer.d Thu Jul 24 21:12:12 2008 +0200 +++ b/lexer/Lexer.d Thu Jul 24 23:03:18 2008 +0200 @@ -37,7 +37,7 @@ foreach (c; "0123456789") charTable[c] = CharType.Number; - foreach (c; "(){}[];:.,=!<>+-*/%\"`") + foreach (c; "(){}[];:.,=!<>+-*/%&\"`") charTable[c] = CharType.Symbol; foreach (c; " \n") @@ -67,6 +67,7 @@ symbolFunctions['*'] = ☆ symbolFunctions['/'] = &slash; symbolFunctions['%'] = &percent; + symbolFunctions['&'] = ∧ symbolFunctions['"'] = &string; symbolFunctions['`'] = &string; } @@ -282,7 +283,10 @@ return Token(Tok.Slash, Loc(position - 1), 1); } } - + Token and() + { + return Token(Tok.And, Loc(position - 1), 1); + } Token percent() { if(source[position] == '=') diff -r c8e26556c24d -r dc9bf56b7ace lexer/Token.d --- a/lexer/Token.d Thu Jul 24 21:12:12 2008 +0200 +++ b/lexer/Token.d Thu Jul 24 23:03:18 2008 +0200 @@ -162,6 +162,7 @@ Percent, LeftShift, RightShift, UnsignedRightShift, Comma, + And, /* Symbols */ OpenParentheses, @@ -181,6 +182,7 @@ Not, + /* Keywords */ Byte, Ubyte, Short, Ushort, @@ -315,6 +317,7 @@ Tok.Deprecated:"Deprecated", Tok.Auto:"Auto", Tok.Extern:"Extern", - Tok.New:"New" + Tok.New:"New", + Tok.And:"And" ]; } diff -r c8e26556c24d -r dc9bf56b7ace parser/Parser.d --- a/parser/Parser.d Thu Jul 24 21:12:12 2008 +0200 +++ b/parser/Parser.d Thu Jul 24 23:03:18 2008 +0200 @@ -639,10 +639,14 @@ 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())); + { + Attribute a; + return action.actOnDeclStmt(parseDecl(a)); + } if (isa(Tok.OpenBracket, 1)) { @@ -1032,7 +1036,8 @@ static const UnOp[] _unary = [ {Tok.Minus, 4}, - {Tok.Star, 4} + {Tok.Star, 4}, + {Tok.And, 4} ]; UnOp* unary(Tok t) { diff -r c8e26556c24d -r dc9bf56b7ace sema/AstAction.d --- a/sema/AstAction.d Thu Jul 24 21:12:12 2008 +0200 +++ b/sema/AstAction.d Thu Jul 24 23:03:18 2008 +0200 @@ -272,6 +272,8 @@ return new NegateExp(op.location, target); if (op.type == Tok.Star) return new DerefExp(op.location, target); + if (op.type == Tok.And) + return new AddressOfExp(op.location, target); assert(0, "Only valid unary expressions are -x and *x"); } diff -r c8e26556c24d -r dc9bf56b7ace sema/DType.d --- a/sema/DType.d Thu Jul 24 21:12:12 2008 +0200 +++ b/sema/DType.d Thu Jul 24 23:03:18 2008 +0200 @@ -99,12 +99,12 @@ { return cast(hash_t)(cast(void*)this); } - +/* char[] toString() { return id; } - +*/ char[] name() { return id; } SourceLocation getLoc() { return loc; } int byteSize() { return 0; } @@ -167,6 +167,11 @@ } private DArray myArray; + bool isSame(DType d) + { + return d is this; + } + static DInteger Bool, Byte, UByte, Short, UShort, @@ -352,6 +357,19 @@ return "S"~Integer.toString(name.length)~name; } + override bool isSame(DType d) + { + if (d is this) + return true; + + if (!d.isStruct) + return false; + + auto s = d.asStruct; + + return id == s.id; + } + struct DStructMember { DType type; @@ -407,6 +425,19 @@ return "S"~Integer.toString(name.length)~name; } + override bool isSame(DType d) + { + if (d is this) + return true; + + if (!d.isClass) + return false; + + auto c = d.asClass; + + return id == c.id; + } + struct DClassMember { DType type; @@ -454,6 +485,19 @@ return null; } + override bool isSame(DType d) + { + if (d is this) + return true; + + if (!d.isInterface) + return false; + + auto i = d.asInterface; + + return id == i.id; + } + DInterfaceMember[char[]] members; private int bytes_total; @@ -488,6 +532,22 @@ int byteSize() { return arrayOf.byteSize * size; } + override bool isSame(DType d) + { + if (d is this) + return true; + + if (!d.isArray) + return false; + + auto a = d.asStaticArray; + + if (size != a.size) + return false; + + return arrayOf.isSame(a.arrayOf); + } + override char[] mangle() { return "G"~Integer.toString(size)~arrayOf.mangle; @@ -510,6 +570,19 @@ int byteSize() { return 8; } // FIXME: Size is a pointer + on size. (platform depend) + override bool isSame(DType d) + { + if (d is this) + return true; + + if (!d.isArray) + return false; + + auto a = d.asArray; + + return arrayOf.isSame(a.arrayOf); + } + override char[] mangle() { return "G"~arrayOf.mangle; // FIXME: Need correct mangling @@ -531,6 +604,19 @@ int byteSize() { return DType.Int.byteSize; } + override bool isSame(DType d) + { + if (d is this) + return true; + + if (!d.isPointer) + return false; + + auto p = d.asPointer; + + return pointerOf.isSame(p.pointerOf); + } + override char[] mangle() { return "P"~pointerOf.mangle; @@ -569,6 +655,29 @@ return res; } + override bool isSame(DType f) + { + if (f is this) + return true; + + if (!f.isFunction) + return false; + + auto func = f.asFunction; + + if (returnType != func.returnType) + return false; + + if (params.length != func.params.length) + return false; + + foreach (i, p ; params) + if (!p.isSame(func.params[0])) + return false; + + return true; + } + DType[] params; DType returnType; bool firstParamIsReturnValue = false; diff -r c8e26556c24d -r dc9bf56b7ace sema/ScopeBuilder.d --- a/sema/ScopeBuilder.d Thu Jul 24 21:12:12 2008 +0200 +++ b/sema/ScopeBuilder.d Thu Jul 24 23:03:18 2008 +0200 @@ -134,7 +134,7 @@ d.returnType = typeOf(i.returnType, sc); foreach (decl ; i.decls) d.params ~= typeOf(decl.varType, sc); - return d; + return d.getPointerTo; } return sc.findType(id.get); } @@ -247,13 +247,20 @@ } } - DType typeOf(Identifier id, Scope sc) { if(auto i = cast(PointerTypeExp)id) return (typeOf(i.pointerOf, sc)).getPointerTo(); 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.getPointerTo; + } return sc.findType(id.get); } diff -r c8e26556c24d -r dc9bf56b7ace sema/TypeCheck.d --- a/sema/TypeCheck.d Thu Jul 24 21:12:12 2008 +0200 +++ b/sema/TypeCheck.d Thu Jul 24 23:03:18 2008 +0200 @@ -305,7 +305,7 @@ auto identifierType = exp.identifier.type; auto expType = exp.exp.type; - if(identifierType != expType) + if(!identifierType.isSame(expType)) { if(!expType.hasImplicitConversionTo(identifierType)) messages.report(InvalidImplicitCast, exp.loc) diff -r c8e26556c24d -r dc9bf56b7ace sema/Visitor.d --- a/sema/Visitor.d Thu Jul 24 21:12:12 2008 +0200 +++ b/sema/Visitor.d Thu Jul 24 23:03:18 2008 +0200 @@ -91,6 +91,8 @@ return visitNegateExp(cast(NegateExp)exp); case ExpType.Deref: return visitDerefExp(cast(DerefExp)exp); + case ExpType.AddressOfExp: + return visitAddressOfExp(cast(AddressOfExp)exp); case ExpType.AssignExp: return visitAssignExp(cast(AssignExp)exp); case ExpType.CallExp: @@ -367,6 +369,15 @@ return ExpT.init; } + ExpT visitAddressOfExp(AddressOfExp exp) + { + visitExp(exp.exp); + static if (is(ExpT == void)) + return; + else + return ExpT.init; + } + ExpT visitIntegerLit(IntegerLit exp) { static if (is(ExpT == void)) diff -r c8e26556c24d -r dc9bf56b7ace tests/parser/function_pointer.d --- a/tests/parser/function_pointer.d Thu Jul 24 21:12:12 2008 +0200 +++ b/tests/parser/function_pointer.d Thu Jul 24 23:03:18 2008 +0200 @@ -1,6 +1,12 @@ int main() { + f = &foo; +} + +int foo(int x) +{ + return x; } int function(int x) f; diff -r c8e26556c24d -r dc9bf56b7ace tools/AstPrinter.d --- a/tools/AstPrinter.d Thu Jul 24 21:12:12 2008 +0200 +++ b/tools/AstPrinter.d Thu Jul 24 23:03:18 2008 +0200 @@ -197,6 +197,10 @@ auto iden = cast(Identifier)exp; printIdentifier(iden); break; + case ExpType.IdentifierTypeExp: + auto iden = cast(Identifier)exp; + printIdentifier(iden); + break; case ExpType.PointerTypeExp: auto iden = cast(PointerTypeExp)exp; printExp(iden.pointerOf);