changeset 140:927ae00bd9d2

Added support for extern keyword. Being ignored atm though. Also changed ast/Module, so that you can get a list of only vars, functions or structs.
author Anders Johnsen <skabet@gmail.com>
date Sun, 20 Jul 2008 23:23:56 +0200
parents 2be29b296081
children 85d609399fdf
files ast/Module.d basic/Attribute.d basic/Messages.d lexer/Keyword.d lexer/Token.d parser/Parser.d
diffstat 6 files changed, 83 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/ast/Module.d	Fri Jul 11 21:47:57 2008 +0200
+++ b/ast/Module.d	Sun Jul 20 23:23:56 2008 +0200
@@ -14,10 +14,28 @@
 
     void addDecl(Decl decl)
     {
+        switch(decl.declType)
+        {
+            case DeclType.FuncDecl:
+                functions ~= cast(FuncDecl)decl;
+                break;
+            case DeclType.VarDecl:
+                vars ~= cast(VarDecl)decl;
+                break;
+            case DeclType.StructDecl:
+                structs ~= cast(StructDecl)decl;
+                break;
+            default:
+                assert(0, "DeclType not implemented");
+        }
         decls ~= decl;
     }
 
+    VarDecl[] vars;
+    FuncDecl[] functions;
+    StructDecl[] structs;
     Decl[] decls;
+
     char[] moduleName;
     Scope env;
     Symbol symbol;
--- a/basic/Attribute.d	Fri Jul 11 21:47:57 2008 +0200
+++ b/basic/Attribute.d	Sun Jul 20 23:23:56 2008 +0200
@@ -14,6 +14,16 @@
     Export    = 1<<4,
 }
 
+enum Extern : uint
+{
+    C         = 1<<12,
+    CPlusPlus = 1<<13,
+    D         = 1<<14,
+    Windows   = 1<<15,
+    Pascal    = 1<<16,
+    System    = 1<<17,
+}
+
 struct Attribute
 {
 
@@ -49,6 +59,11 @@
         return p;
     }
 
+    void setExtern(Extern e)    
+    { 
+        att &= ~e; 
+    }
+
     void setStatic()    { att &= ~Static; }
     void setFinal()     { att &= ~Final; }
     void setConst()     { att &= ~Const; }
--- a/basic/Messages.d	Fri Jul 11 21:47:57 2008 +0200
+++ b/basic/Messages.d	Sun Jul 20 23:23:56 2008 +0200
@@ -21,6 +21,7 @@
     ExpectedCastType,
     InvalidDeclType,
     InvalidType,
+    UnexpectedLinkType,
     //   - imports/module
     ExpectedIdAfterPackage,
     RenameMustBeSingleIdent,
@@ -93,6 +94,7 @@
         InvalidDeclType     : E(Err, "Invalid declaration type"),
         InvalidType         : E(Err, "Invalid type"),
         ExpectedIdAfterPackage : E(Err, "Identifier expected following package"),
+        UnexpectedLinkType  : E(Err, "Invalid linkage type. Only C, C++, D, Windows, Pascal and System is allowed"),
 
         // sema
         CannotFindModule    : E(Err, "Cannot find module '%0'"),
--- a/lexer/Keyword.d	Fri Jul 11 21:47:57 2008 +0200
+++ b/lexer/Keyword.d	Sun Jul 20 23:23:56 2008 +0200
@@ -74,6 +74,7 @@
         "override"  : Tok.Override,
         "depracted" : Tok.Depracted,
         "auto"      : Tok.Auto,
+        "extern"      : Tok.Extern,
 
         // exceptions
         "assert"    : Tok.Assert,
--- a/lexer/Token.d	Fri Jul 11 21:47:57 2008 +0200
+++ b/lexer/Token.d	Sun Jul 20 23:23:56 2008 +0200
@@ -72,7 +72,7 @@
      */
     bool isAttribute()
     {
-        return type >= Tok.Public && type <= Tok.Auto;
+        return type >= Tok.Public && type <= Tok.Extern;
     }
 
     /**
@@ -207,6 +207,7 @@
     Override,
     Depracted,
     Auto,
+    Extern,
 
     Align,
 
@@ -297,6 +298,7 @@
         Tok.Abstract:"Abstract",
         Tok.Override:"Override",
         Tok.Depracted:"Depracted",
-        Tok.Auto:"Auto"
+        Tok.Auto:"Auto",
+        Tok.Extern:"Extern"
     ];
 }
--- a/parser/Parser.d	Fri Jul 11 21:47:57 2008 +0200
+++ b/parser/Parser.d	Sun Jul 20 23:23:56 2008 +0200
@@ -117,6 +117,10 @@
                 case Tok.Auto:
                     a.setAuto;
                     break;
+                case Tok.Extern:
+                    Extern e = parseLinkageType;
+                    a.setExtern(e);
+                    break;
             }
             if(sco)
             {
@@ -196,6 +200,45 @@
             .fatal(ExitLevel.Parser);
     }
 
+    Extern parseLinkageType()
+    {
+        Extern e = Extern.D;
+        if(lexer.peek(1).type != Tok.OpenParentheses)
+            return e;
+
+        lexer.next; lexer.next;
+
+        Token t = require(Tok.Identifier);
+
+        switch(sm.getText(t.asRange))
+        {
+            case "C":
+                if (lexer.peek(0).type == Tok.Plus && 
+                    lexer.peek(1).type == Tok.Plus)
+                    e = Extern.CPlusPlus;
+                else
+                    e = Extern.C;
+                break;
+            case "D":
+                break;
+            case "Windows":
+                e = Extern.Windows;
+                break;
+            case "Pascal":
+                e = Extern.Pascal;
+                break;
+            case "System":
+                e = Extern.System;
+                break;
+            default:
+                messages.report(UnexpectedLinkType, t.location);
+        }
+
+        require(Tok.CloseParentheses);
+        
+        return e;
+    }
+
     /**
       Parse a series of imports belonging to a single import token.
      */