diff dmd/Parser.d @ 130:60bb0fe4563e

dmdfe 2.037 first main iteration
author Eldar Insafutdinov <e.insafutdinov@gmail.com>
date Thu, 09 Sep 2010 22:51:44 +0100
parents e6e542f37b94
children 206db751bd4c
line wrap: on
line diff
--- a/dmd/Parser.d	Sun Sep 05 15:32:22 2010 +0400
+++ b/dmd/Parser.d	Thu Sep 09 22:51:44 2010 +0100
@@ -138,7 +138,7 @@
 import dmd.CompoundStatement;
 import dmd.ConditionalStatement;
 import dmd.CompoundDeclarationStatement;
-import dmd.Argument;
+import dmd.Parameter;
 import dmd.ParseStatementFlags;
 import dmd.TypeNewArray;
 import dmd.TypeNext;
@@ -235,6 +235,7 @@
 			bool safe = false;
 
 			nextToken();
+static if(false) {
 version (DMDV2) {
 			if (token.value == TOK.TOKlparen)
 			{
@@ -254,6 +255,7 @@
 				check(TOK.TOKrparen);
 			}
 }
+}
 
 			if (token.value != TOK.TOKidentifier)
 			{
@@ -507,6 +509,7 @@
 			case TOK.TOKgshared:      
 				stc = STC.STCgshared;	 goto Lstc;
 			//case TOK.TOKmanifest:	  stc = STC.STCmanifest;	 goto Lstc;
+	        case TOK.TOKat:           stc = parseAttribute(); goto Lstc;
 }
 
 			Lstc:
@@ -545,6 +548,7 @@
 				case TOK.TOKtls:          stc = STC.STCtls;		 goto Lstc;
 				case TOK.TOKgshared:      stc = STC.STCgshared;	 goto Lstc;
 				//case TOK.TOKmanifest:	  stc = STC.STCmanifest;	 goto Lstc;
+		        case TOK.TOKat:           stc = parseAttribute(); goto Lstc;
 				default:
 				break;
 			}
@@ -835,7 +839,7 @@
 		}
 		return a;
 	}
-	
+version(DMDV2) {
     void composeStorageClass(STC stc)
 	{
 		STC u = stc;
@@ -847,8 +851,39 @@
 		u &= STC.STCgshared | STC.STCshared | STC.STCtls;
 		if (u & (u - 1))
 			error("conflicting storage class %s", Token.toChars(token.value));
+        u = stc;
+        u &= STCsafe | STCsystem | STCtrusted;
+        if (u & (u - 1))
+	        error("conflicting attribute @%s", token.toChars());
 	}
-	
+}
+    
+/***********************************************
+ * Parse storage class, lexer is on '@'
+ */
+
+version(DMDV2) {
+    STC parseAttribute()
+    {
+        nextToken();
+        STC stc = STCundefined;
+        if (token.value != TOKidentifier)
+        {
+	        error("identifier expected after @, not %s", token.toChars());
+        }
+        else if (token.ident == Id.property)
+	        stc = STCproperty;
+        else if (token.ident == Id.safe)
+	        stc = STCsafe;
+        else if (token.ident == Id.trusted)
+	        stc = STCtrusted;
+        else if (token.ident == Id.system)
+	        stc = STCsystem;
+        else
+	        error("valid attribute identifiers are @property, @safe, @trusted, @system, not @%s", token.toChars());
+        return stc;
+    }
+}
 	/**************************************
 	 * Parse constraint.
 	 * Constraint is of the form:
@@ -1575,7 +1610,7 @@
 			nextToken();
 			nextToken();
 			check(TOK.TOKrparen);
-			PostBlitDeclaration f = new PostBlitDeclaration(loc, Loc(0));
+			auto f = new PostBlitDeclaration(loc, Loc(0));
 			parseContracts(f);
 			return f;
 		}
@@ -1589,7 +1624,7 @@
 		{	tpl = parseTemplateParameterList();
 
 			int varargs;
-			Arguments arguments = parseParameters(&varargs);
+			auto arguments = parseParameters(&varargs);
 
 			Expression constraint = null;
 			if (tpl)
@@ -1608,7 +1643,7 @@
 		/* Just a regular constructor
 		 */
 		int varargs;
-		Arguments arguments = parseParameters(&varargs);
+		auto arguments = parseParameters(&varargs);
 		CtorDeclaration f = new CtorDeclaration(loc, Loc(0), arguments, varargs);
 		parseContracts(f);
 		return f;
@@ -1725,7 +1760,7 @@
     NewDeclaration parseNew()
 	{
 		NewDeclaration f;
-		scope Arguments arguments = new Arguments();
+		scope arguments = new Parameters();
 		int varargs;
 		Loc loc = this.loc;
 
@@ -1744,7 +1779,7 @@
     DeleteDeclaration parseDelete()
 	{
 		DeleteDeclaration f;
-		scope Arguments arguments;
+		scope Parameters arguments;
 		int varargs;
 		Loc loc = this.loc;
 
@@ -1757,9 +1792,9 @@
 		return f;
 	}
 	
-    Arguments parseParameters(int* pvarargs)
+    Parameters parseParameters(int* pvarargs)
 	{
-		Arguments arguments = new Arguments();
+		auto arguments = new Parameters();
 		int varargs = 0;
 		int hasdefault = 0;
 
@@ -1768,7 +1803,7 @@
 		{   Type *tb;
 		Identifier ai = null;
 		Type at;
-		Argument a;
+		Parameter a;
 		STC storageClass = STC.STCundefined;
 		STC stc;
 		Expression ae;
@@ -1880,13 +1915,13 @@
 				if (storageClass & (STC.STCout | STC.STCref))
 					error("variadic argument cannot be out or ref");
 				varargs = 2;
-				a = new Argument(storageClass, at, ai, ae);
+				a = new Parameter(storageClass, at, ai, ae);
 				arguments.push(a);
 				nextToken();
 				break;
 				}
 			L3:
-				a = new Argument(storageClass, at, ai, ae);
+				a = new Parameter(storageClass, at, ai, ae);
 				arguments.push(a);
 				if (token.value == TOK.TOKcomma)
 				{   nextToken();
@@ -2486,11 +2521,11 @@
 				{
 					//printf("it's type[expression]\n");
 					inBrackets++;
-					Expression e = parseExpression();		// [ expression ]
+					Expression e = parseAssignExp();		// [ expression ]
 					if (token.value == TOK.TOKslice)
 					{
 					nextToken();
-					Expression e2 = parseExpression();	// [ exp .. exp ]
+					Expression e2 = parseAssignExp();	// [ exp .. exp ]
 					t = new TypeSlice(t, e, e2);
 					}
 					else
@@ -2505,27 +2540,52 @@
 				{	// Handle delegate declaration:
 				//	t delegate(parameter list) nothrow pure
 				//	t function(parameter list) nothrow pure
-				Arguments arguments;
+				Parameters arguments;
 				int varargs;
 				bool ispure = false;
 				bool isnothrow = false;
+		        bool isproperty = false;
 				TOK save = token.value;
+		        TRUST trust = TRUSTdefault;
 	
 				nextToken();
 				arguments = parseParameters(&varargs);
 				while (1)
 				{   // Postfixes
 					if (token.value == TOK.TOKpure)
-					ispure = true;
+					    ispure = true;
 					else if (token.value == TOK.TOKnothrow)
-					isnothrow = true;
+					    isnothrow = true;
+		            else if (token.value == TOKat)
+		            {	STC stc = parseAttribute();
+			            switch (cast(uint)(stc >> 32))
+			            {   case STCproperty >> 32:
+				                isproperty = true;
+				                break;
+			                case STCsafe >> 32:
+				                trust = TRUSTsafe;
+				                break;
+			                case STCsystem >> 32:
+				                trust = TRUSTsystem;
+				                break;
+			                case STCtrusted >> 32:
+				                trust = TRUSTtrusted;
+				                break;
+			                case 0:
+				                break;
+			                default:
+    				            assert(0);
+			            }
+		            }
 					else
-					break;
+					    break;
 					nextToken();
 				}
 				TypeFunction tf = new TypeFunction(arguments, t, varargs, linkage);
 				tf.ispure = ispure;
 				tf.isnothrow = isnothrow;
+		        tf.isproperty = isproperty;
+		        tf.trust = trust;
 				if (save == TOK.TOKdelegate)
 					t = new TypeDelegate(tf);
 				else
@@ -2614,7 +2674,7 @@
 			else
 			{
 				//printf("It's a static array\n");
-				Expression e = parseExpression();	// [ expression ]
+				Expression e = parseAssignExp();	// [ expression ]
 				ta = new TypeSArray(t, e);
 				check(TOK.TOKrbracket);
 			}
@@ -2649,7 +2709,7 @@
 			}
 
 			int varargs;
-			Arguments arguments = parseParameters(&varargs);
+			auto arguments = parseParameters(&varargs);
 			Type tf = new TypeFunction(arguments, t, varargs, linkage);
 
 			/* Parse const/invariant/nothrow/pure postfix
@@ -2691,19 +2751,31 @@
 						continue;
 
 					case TOK.TOKat:
-						nextToken();
-						if (token.value != TOK.TOKidentifier)
-						{   error("attribute identifier expected");
-						nextToken();
-						continue;
-						}
-						Identifier id = token.ident;
-						if (id is Id.property)
-						(cast(TypeFunction)tf).isproperty = 1;
-						else
-						error("valid attribute identifiers are @property, not @%s", id.toChars());
-						nextToken();
-						continue;
+    	            {
+                        STC stc = parseAttribute();
+	                    auto tfunc = cast(TypeFunction)tf;
+		                switch (cast(uint)(stc >> 32))
+		                {
+                        case STCproperty >> 32:
+		                    tfunc.isproperty = 1;
+			                break;
+			            case STCsafe >> 32:
+			                tfunc.trust = TRUSTsafe;
+			                break;
+			            case STCsystem >> 32:
+			                tfunc.trust = TRUSTsystem;
+			                break;
+			            case STCtrusted >> 32:
+			                tfunc.trust = TRUSTtrusted;
+			                break;
+			            case 0:
+			                break;
+			            default:
+			                assert(0);
+					    }
+					    nextToken();
+					    continue;
+                    }
 					default:
 						break;	///
 				}
@@ -2817,6 +2889,7 @@
 			case TOK.TOKtls:        stc = STC.STCtls;		 goto L1;
 			case TOK.TOKgshared:    stc = STC.STCgshared;	 goto L1;
 			case TOK.TOKenum:	stc = STC.STCmanifest;	 goto L1;
+	        case TOK.TOKat:         stc = parseAttribute();  goto L1;
 }
 			L1:
 			if (storage_class & stc)
@@ -2947,7 +3020,7 @@
 			auto tf = cast(TypeFunction)t;
 			Expression constraint = null;
 static if (false) {
-			if (Argument.isTPL(tf.parameters))
+			if (Parameter.isTPL(tf.parameters))
 			{
 			if (!tpl)
 				tpl = new TemplateParameters();
@@ -3028,7 +3101,6 @@
 	
     void parseContracts(FuncDeclaration f)
 	{
-		Type tb;
 		LINK linksave = linkage;
 
 		// The following is irrelevant, as it is overridden by sc.linkage in
@@ -3071,7 +3143,7 @@
 			check(TOK.TOKlparen);
 			while (1)
 			{
-			tb = parseBasicType();
+			Type tb = parseBasicType();
 			f.fthrows.push(tb);
 			if (token.value == TOK.TOKcomma)
 			{   nextToken();
@@ -3195,9 +3267,8 @@
 		case TOK.TOKline:
 }
 		Lexp:
-		{   Expression exp;
-
-			exp = parseExpression();
+		{
+			auto exp = parseExpression();
 			check(TOK.TOKsemicolon, "statement");
 			s = new ExpStatement(loc, exp);
 			break;
@@ -3220,6 +3291,16 @@
 				condition = parseStaticIfCondition();
 				goto Lcondition;
 			}
+	        if (t.value == TOK.TOKstruct || t.value == TOK.TOKunion || t.value == TOK.TOKclass)
+	        {
+		        nextToken();
+		        auto a = parseBlock();
+		        Dsymbol d = new StorageClassDeclaration(STCstatic, a);
+		        s = new DeclarationStatement(loc, d);
+		        if (flags & PSscope)
+		            s = new ScopeStatement(loc, s);
+		        break;
+	        }
 			goto Ldeclaration;
 		}
 
@@ -3255,6 +3336,7 @@
 		case TOK.TOKpure:
 		case TOK.TOKtls:
 		case TOK.TOKgshared:
+	    case TOK.TOKat:
 }
 	//	case TOK.TOKtypeof:
 		Ldeclaration:
@@ -3430,24 +3512,17 @@
 		case TOK.TOKforeach_reverse:
 		{
 			TOK op = token.value;
-			Arguments arguments;
-
-			Statement d;
-			Statement body_;
-			Expression aggr;
 
 			nextToken();
 			check(TOK.TOKlparen);
 
-			arguments = new Arguments();
+			auto arguments = new Parameters();
 
 			while (1)
 			{
-			Type tb;
 			Identifier ai = null;
 			Type at;
 			STC storageClass = STC.STCundefined;
-			Argument a;
 
 			if (token.value == TOK.TOKinout || token.value == TOK.TOKref)
 			{   storageClass = STC.STCref;
@@ -3467,7 +3542,7 @@
 			if (!ai)
 				error("no identifier for declarator %s", at.toChars());
 			  Larg:
-			a = new Argument(storageClass, at, ai, null);
+			auto a = new Parameter(storageClass, at, ai, null);
 			arguments.push(a);
 			if (token.value == TOK.TOKcomma)
 			{   nextToken();
@@ -3477,7 +3552,7 @@
 			}
 			check(TOK.TOKsemicolon);
 
-			aggr = parseExpression();
+			Expression aggr = parseExpression();
 			if (token.value == TOK.TOKslice && arguments.dim == 1)
 			{
 			auto a = arguments[0];
@@ -3485,20 +3560,20 @@
 			nextToken();
 			Expression upr = parseExpression();
 			check(TOK.TOKrparen);
-			body_ = parseStatement(cast(ParseStatementFlags)0);
+			auto body_ = parseStatement(cast(ParseStatementFlags)0);
 			s = new ForeachRangeStatement(loc, op, a, aggr, upr, body_);
 			}
 			else
 			{
 			check(TOK.TOKrparen);
-			body_ = parseStatement(cast(ParseStatementFlags)0);
+			auto body_ = parseStatement(cast(ParseStatementFlags)0);
 			s = new ForeachStatement(loc, op, arguments, aggr, body_);
 			}
 			break;
 		}
 
 		case TOK.TOKif:
-		{   Argument arg = null;
+		{   Parameter arg = null;
 			Expression condition2;
 			Statement ifbody2;
 			Statement elsebody2;
@@ -3514,7 +3589,7 @@
 				Token *tt = peek(&token);
 				if (tt.value == TOK.TOKassign)
 				{
-					arg = new Argument(STC.STCundefined, null, token.ident, null);
+					arg = new Parameter(STC.STCundefined, null, token.ident, null);
 					nextToken();
 					nextToken();
 				}
@@ -3535,7 +3610,7 @@
 
 			at = parseType(&ai);
 			check(TOK.TOKassign);
-			arg = new Argument(STC.STCundefined, at, ai, null);
+			arg = new Parameter(STC.STCundefined, at, ai, null);
 			}
 
 			// Check for " ident;"
@@ -3544,7 +3619,7 @@
 			Token *tt = peek(&token);
 			if (tt.value == TOK.TOKcomma || tt.value == TOK.TOKsemicolon)
 			{
-				arg = new Argument(STC.STCundefined, null, token.ident, null);
+				arg = new Parameter(STC.STCundefined, null, token.ident, null);
 				nextToken();
 				nextToken();
 				if (1 || !global.params.useDeprecated)
@@ -5137,13 +5212,20 @@
 		}
 
 		case TOK.TOKtypeid:
-		{   Type tt;
-
+		{
 			nextToken();
 			check(TOK.TOKlparen, "typeid");
-			tt = parseType();		// ( type )
+	        Object o;
+	        if (isDeclaration(&token, 0, TOKreserved, NULL))
+	        {	// argument is a type
+		        o = parseType();
+	        }
+	        else
+	        {	// argument is an expression
+		        o = parseAssignExp();
+	        }
 			check(TOK.TOKrparen);
-			e = new TypeidExp(loc, tt);
+		    e = new TypeidExp(loc, o);
 			break;
 		}
 
@@ -5345,18 +5427,20 @@
 			 * (parameters) { body }
 			 * { body }
 			 */
-			Arguments arguments;
+			Parameters arguments;
 			int varargs;
 			FuncLiteralDeclaration fd;
 			Type tt;
 			bool isnothrow = false;
 			bool ispure = false;
-
+	        bool isproperty = false;
+	        TRUST trust = TRUSTdefault;
+            
 			if (token.value == TOK.TOKlcurly)
 			{
 			tt = null;
 			varargs = 0;
-			arguments = new Arguments();
+			arguments = new Parameters();
 			}
 			else
 			{
@@ -5374,8 +5458,31 @@
 				ispure = true;
 				else if (token.value == TOK.TOKnothrow)
 				isnothrow = true;
+		        else if (token.value == TOKat)
+		        {
+                    STC stc = parseAttribute();
+			        switch (cast(uint)(stc >> 32))
+			        {
+                        case STCproperty >> 32:
+				            isproperty = true;
+				            break;
+			            case STCsafe >> 32:
+				            trust = TRUSTsafe;
+				            break;
+			            case STCsystem >> 32:
+				            trust = TRUSTsystem;
+				            break;
+			            case STCtrusted >> 32:
+				            trust = TRUSTtrusted;
+				            break;
+			            case 0:
+				            break;
+			            default:
+    				        assert(0);
+			        }
+	            }
 				else
-				break;
+	    			break;
 				nextToken();
 			}
 			}
@@ -5383,6 +5490,8 @@
 			TypeFunction tf = new TypeFunction(arguments, tt, varargs, linkage);
 			tf.ispure = ispure;
 			tf.isnothrow = isnothrow;
+	        tf.isproperty = isproperty;
+	        tf.trust = trust;
 			fd = new FuncLiteralDeclaration(loc, Loc(0), tf, save, null);
 			parseContracts(fd);
 			e = new FuncExp(loc, fd);
@@ -5644,14 +5753,15 @@
 				if (token.value == TOK.TOKnot && peekNext() != TOK.TOKis)
 				{   // identifier!(template-argument-list)
 				TemplateInstance tempinst = new TemplateInstance(loc, id);
+			    Objects tiargs;
 				nextToken();
 				if (token.value == TOK.TOKlparen)
 					// ident!(template_arguments)
-					tempinst.tiargs = parseTemplateArgumentList();
+					tiargs = parseTemplateArgumentList();
 				else
 					// ident!template_argument
-					tempinst.tiargs = parseTemplateArgument();
-				e = new DotTemplateInstanceExp(loc, e, tempinst);
+					tiargs = parseTemplateArgument();
+				e = new DotTemplateInstanceExp(loc, e, tiargs);
 				}
 				else
 				e = new DotIdExp(loc, e, id);
@@ -5748,8 +5858,9 @@
 			switch (token.value)
 			{
 				case TOK.TOKmul: nextToken(); e2 = parseUnaryExp(); e = new MulExp(loc,e,e2); continue;
-				case TOK.TOKdiv: nextToken(); e2 = parseUnaryExp(); e = new DivExp(loc,e,e2); continue;
-				case TOK.TOKmod: nextToken(); e2 = parseUnaryExp(); e = new ModExp(loc,e,e2); continue;
+	            case TOK.TOKdiv: nextToken(); e2 = parseUnaryExp(); e = new DivExp(loc,e,e2); continue;
+	            case TOK.TOKmod: nextToken(); e2 = parseUnaryExp(); e = new ModExp(loc,e,e2); continue;
+	            case TOK.TOKpow: nextToken(); e2 = parseUnaryExp(); e = new PowExp(loc,e,e2); continue;
 
 				default:
 				break;
@@ -6016,6 +6127,7 @@
 				case TOK.TOKmulass:  nextToken(); e2 = parseAssignExp(); e = new MulAssignExp(loc,e,e2); continue;
 				case TOK.TOKdivass:  nextToken(); e2 = parseAssignExp(); e = new DivAssignExp(loc,e,e2); continue;
 				case TOK.TOKmodass:  nextToken(); e2 = parseAssignExp(); e = new ModAssignExp(loc,e,e2); continue;
+//				case TOK.TOKpowass:  nextToken(); e2 = parseAssignExp(); e = new PowAssignExp(loc,e,e2); continue;
 				case TOK.TOKandass:  nextToken(); e2 = parseAssignExp(); e = new AndAssignExp(loc,e,e2); continue;
 				case TOK.TOKorass:   nextToken(); e2 = parseAssignExp(); e = new OrAssignExp(loc,e,e2); continue;
 				case TOK.TOKxorass:  nextToken(); e2 = parseAssignExp(); e = new XorAssignExp(loc,e,e2); continue;