changeset 176:dc9bf56b7ace

Can now use & as a unary operator and take an AddressOf
author Anders Johnsen <skabet@gmail.com>
date Thu, 24 Jul 2008 23:03:18 +0200
parents c8e26556c24d
children 491b5fc4782a
files ast/Exp.d dang/compiler.d lexer/Lexer.d lexer/Token.d parser/Parser.d sema/AstAction.d sema/DType.d sema/ScopeBuilder.d sema/TypeCheck.d sema/Visitor.d tests/parser/function_pointer.d tools/AstPrinter.d
diffstat 12 files changed, 197 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- 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)
--- 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;
 
--- 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['*'] = &star;
         symbolFunctions['/'] = &slash;
         symbolFunctions['%'] = &percent;
+        symbolFunctions['&'] = &and;
         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] == '=')
--- 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"
     ];
 }
--- 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)
     {
--- 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");
     }
 
--- 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;
--- 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);
     }
 
--- 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)
--- 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))
--- 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;
--- 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);