diff parser/Parser.d @ 36:ce17bea8e9bd new_gen

Switch statements support Can only switch on IntegerLit's but multiple values per case and the default are supported. An error is emitted if a value is used multiple times or if theres is more than one default block
author Anders Halager <halager@gmail.com>
date Sun, 20 Apr 2008 22:39:07 +0200
parents 084c2c147c4f
children 858b9805843d
line wrap: on
line diff
--- a/parser/Parser.d	Sun Apr 20 21:33:50 2008 +0200
+++ b/parser/Parser.d	Sun Apr 20 22:39:07 2008 +0200
@@ -70,7 +70,7 @@
                                 return new VarDecl(type, identifier, exp);
                             default:
                                 char[] c = p.getType;
-                                throw error(__LINE__, UnexpextedTokMulti)
+                                throw error(__LINE__, UnexpectedTokMulti)
                                     .tok(p)
                                     .arg(c)
                                     .arg(Tok.OpenParentheses, Tok.Seperator, Tok.Assign);
@@ -78,7 +78,7 @@
                         break;
                     default:
                         char[] c = t.getType;
-                        throw error(__LINE__, UnexpextedTok).tok(iden).arg(c);
+                        throw error(__LINE__, UnexpectedTok).tok(iden).arg(c);
                 }
                 break;
             case Tok.Struct:
@@ -96,7 +96,7 @@
                 return null;
             default:
                 char[] c = t.getType;
-                throw error(__LINE__, UnexpextedTok).tok(t).arg(c);
+                throw error(__LINE__, UnexpectedTok).tok(t).arg(c);
         }
     }
 
@@ -139,7 +139,7 @@
                                 return new VarDecl(type, identifier, exp);
                             default:
                                 char[] c = p.getType;
-                                throw error(__LINE__, UnexpextedTokMulti)
+                                throw error(__LINE__, UnexpectedTokMulti)
                                     .tok(p)
                                     .arg(c)
                                     .arg(Tok.OpenParentheses, Tok.Seperator, Tok.Assign);
@@ -147,7 +147,7 @@
                         break;
                     default:
                         char[] c = iden.getType;
-                        throw error(__LINE__, UnexpextedTokSingle)
+                        throw error(__LINE__, UnexpectedTokSingle)
                             .tok(iden)
                             .arg(c)
                             .arg(Tok.Identifier);
@@ -157,7 +157,7 @@
                 return null;
             default:
                 char[] c = t.getType;
-                throw error(__LINE__, UnexpextedTok).arg(c);
+                throw error(__LINE__, UnexpectedTok).arg(c);
         }
     }
 
@@ -245,6 +245,57 @@
                 }
                 break;
 
+            case Tok.Switch:
+                lexer.next;
+                require(Tok.OpenParentheses);
+                auto target = parseExpression();
+                auto res = new SwitchStmt(target);
+                require(Tok.CloseParentheses);
+                require(Tok.OpenBrace);
+                while (true)
+                {
+                    Stmt[] statements;
+                    if (skip(Tok.Default))
+                    {
+                        require(Tok.Colon);
+                        statements.length = 0;
+                        while (lexer.peek.type != Tok.Case
+                                && lexer.peek.type != Tok.Default
+                                && lexer.peek.type != Tok.CloseBrace)
+                            statements ~= parseStatement();
+                        res.setDefault(statements);
+                        continue;
+                    }
+
+                    Token _case = require(Tok.Case);
+
+                    IntegerLit[] literals;
+                    do
+                    {
+                        Exp e = parseExpression();
+                        IntegerLit lit = cast(IntegerLit)e;
+                        if (lit is null)
+                            throw error(__LINE__, CaseValueMustBeInt)
+                                .tok(_case);
+
+                        literals ~= lit;
+                    }
+                    while (skip(Tok.Comma));
+                    require(Tok.Colon);
+
+                    while (lexer.peek.type != Tok.Case
+                            && lexer.peek.type != Tok.Default
+                            && lexer.peek.type != Tok.CloseBrace)
+                        statements ~= parseStatement();
+
+                    res.addCase(literals, statements);
+
+                    if (lexer.peek.type == Tok.CloseBrace)
+                        break;
+                }
+                require(Tok.CloseBrace);
+                return res;
+
             default:
                 auto decl = new DeclStmt(parseDecl());
                 //require(Tok.Seperator);
@@ -300,7 +351,7 @@
                 return new Identifier(identifier);
                 break;
             default:
-                throw error(__LINE__, "Unexpexted token in Identifier parsing. Got %0")
+                throw error(__LINE__, "Unexpected token in Identifier parsing. Got %0")
                     .arg(identifier.getType)
                     .tok(identifier);
         }
@@ -323,7 +374,7 @@
                 break;
             default:
                 char[] c = type.getType;
-                error(__LINE__, "Unexpexted token in Type parsing. Got %0").arg(c);
+                error(__LINE__, "Unexpected token in Type parsing. Got %0").arg(c);
         }
     }
 
@@ -472,13 +523,21 @@
 
 private:
 
-    void require(Tok t)
+    Token require(Tok t)
     {
         if (lexer.peek().type != t)
-            error(__LINE__, UnexpextedTokSingle)
+            throw error(__LINE__, UnexpectedTokSingle)
                 .arg(lexer.peek.getType)
                 .arg(t);
+        return lexer.next();
+    }
+
+    bool skip(Tok t)
+    {
+        if (lexer.peek().type != t)
+            return false;
         lexer.next();
+        return true;
     }
 
     Error error(uint line, char[] errMsg, Token* tok = null)
@@ -497,9 +556,12 @@
     }
 
     static char[]
-        UnexpextedTokMulti = "Unexpexted token, got %0 expected one of %1",
-        UnexpextedTokSingle = "Unexpexted token, got %0 expected %1",
-        UnexpextedTok = "Unexpexted token %0";
+        UnexpectedTokMulti = "Unexpected token, got %0 expected one of %1",
+        UnexpectedTokSingle = "Unexpected token, got %0 expected %1",
+        UnexpectedTok = "Unexpected token %0";
+
+    static char[]
+        CaseValueMustBeInt = "Cases can only be integer literals";
 
     Lexer lexer;
 }