Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/CodeGen/CodeGenerator.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -656,4 +656,10 @@
 	}
 
+	void CodeGenerator::visit( StmtExpr * stmtExpr ) {
+		output << "(";
+		stmtExpr->get_statements()->accept( *this );
+		output << ")";
+	}
+
 	//*** Statements
 	void CodeGenerator::visit( CompoundStmt * compoundStmt ) {
Index: src/CodeGen/CodeGenerator.h
===================================================================
--- src/CodeGen/CodeGenerator.h	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/CodeGen/CodeGenerator.h	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -73,4 +73,5 @@
 		virtual void visit( TypeExpr *typeExpr );
 		virtual void visit( AsmExpr * );
+		virtual void visit( StmtExpr * );
 
 		//*** Statements
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/InitTweak/InitTweak.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -388,5 +388,5 @@
 				return memberExpr->get_member()->get_name();
 			} else if ( UntypedMemberExpr * memberExpr = dynamic_cast< UntypedMemberExpr * > ( func ) ) {
-				return memberExpr->get_member();
+				return funcName( memberExpr->get_member() );
 			} else {
 				assertf( false, "Unexpected expression type being called as a function in call expression" );
@@ -451,10 +451,10 @@
 		// virtual void visit( LogicalExpr *logicalExpr );
 		// virtual void visit( ConditionalExpr *conditionalExpr );
-		virtual void visit( TupleExpr *tupleExpr ) { isConstExpr = false; }
-		virtual void visit( SolvedTupleExpr *tupleExpr ) { isConstExpr = false; }
 		virtual void visit( TypeExpr *typeExpr ) { isConstExpr = false; }
 		virtual void visit( AsmExpr *asmExpr ) { isConstExpr = false; }
 		virtual void visit( UntypedValofExpr *valofExpr ) { isConstExpr = false; }
 		virtual void visit( CompoundLiteralExpr *compLitExpr ) { isConstExpr = false; }
+		virtual void visit( TupleExpr *tupleExpr ) { isConstExpr = false; }
+		virtual void visit( TupleAssignExpr *tupleExpr ) { isConstExpr = false; }
 
 		bool isConstExpr;
Index: src/Makefile.in
===================================================================
--- src/Makefile.in	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/Makefile.in	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -189,5 +189,5 @@
 	SynTree/driver_cfa_cpp-Attribute.$(OBJEXT) \
 	Tuples/driver_cfa_cpp-TupleAssignment.$(OBJEXT) \
-	Tuples/driver_cfa_cpp-NameMatcher.$(OBJEXT)
+	Tuples/driver_cfa_cpp-TupleExpansion.$(OBJEXT)
 am_driver_cfa_cpp_OBJECTS = $(am__objects_1)
 driver_cfa_cpp_OBJECTS = $(am_driver_cfa_cpp_OBJECTS)
@@ -402,5 +402,5 @@
 	SynTree/AddStmtVisitor.cc SynTree/TypeSubstitution.cc \
 	SynTree/Attribute.cc Tuples/TupleAssignment.cc \
-	Tuples/NameMatcher.cc
+	Tuples/TupleExpansion.cc
 MAINTAINERCLEANFILES = Parser/parser.output ${libdir}/${notdir \
 	${cfa_cpplib_PROGRAMS}}
@@ -769,6 +769,6 @@
 Tuples/driver_cfa_cpp-TupleAssignment.$(OBJEXT):  \
 	Tuples/$(am__dirstamp) Tuples/$(DEPDIR)/$(am__dirstamp)
-Tuples/driver_cfa_cpp-NameMatcher.$(OBJEXT): Tuples/$(am__dirstamp) \
-	Tuples/$(DEPDIR)/$(am__dirstamp)
+Tuples/driver_cfa_cpp-TupleExpansion.$(OBJEXT):  \
+	Tuples/$(am__dirstamp) Tuples/$(DEPDIR)/$(am__dirstamp)
 driver/$(am__dirstamp):
 	@$(MKDIR_P) driver
@@ -877,6 +877,6 @@
 	-rm -f SynTree/driver_cfa_cpp-Visitor.$(OBJEXT)
 	-rm -f SynTree/driver_cfa_cpp-VoidType.$(OBJEXT)
-	-rm -f Tuples/driver_cfa_cpp-NameMatcher.$(OBJEXT)
 	-rm -f Tuples/driver_cfa_cpp-TupleAssignment.$(OBJEXT)
+	-rm -f Tuples/driver_cfa_cpp-TupleExpansion.$(OBJEXT)
 
 distclean-compile:
@@ -982,6 +982,6 @@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Visitor.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-VoidType.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/driver_cfa_cpp-NameMatcher.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/driver_cfa_cpp-TupleAssignment.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Po@am__quote@
 
 .cc.o:
@@ -2401,17 +2401,17 @@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Tuples/driver_cfa_cpp-TupleAssignment.obj `if test -f 'Tuples/TupleAssignment.cc'; then $(CYGPATH_W) 'Tuples/TupleAssignment.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/TupleAssignment.cc'; fi`
 
-Tuples/driver_cfa_cpp-NameMatcher.o: Tuples/NameMatcher.cc
-@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-NameMatcher.o -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-NameMatcher.Tpo -c -o Tuples/driver_cfa_cpp-NameMatcher.o `test -f 'Tuples/NameMatcher.cc' || echo '$(srcdir)/'`Tuples/NameMatcher.cc
-@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) Tuples/$(DEPDIR)/driver_cfa_cpp-NameMatcher.Tpo Tuples/$(DEPDIR)/driver_cfa_cpp-NameMatcher.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='Tuples/NameMatcher.cc' object='Tuples/driver_cfa_cpp-NameMatcher.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Tuples/driver_cfa_cpp-NameMatcher.o `test -f 'Tuples/NameMatcher.cc' || echo '$(srcdir)/'`Tuples/NameMatcher.cc
-
-Tuples/driver_cfa_cpp-NameMatcher.obj: Tuples/NameMatcher.cc
-@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-NameMatcher.obj -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-NameMatcher.Tpo -c -o Tuples/driver_cfa_cpp-NameMatcher.obj `if test -f 'Tuples/NameMatcher.cc'; then $(CYGPATH_W) 'Tuples/NameMatcher.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/NameMatcher.cc'; fi`
-@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) Tuples/$(DEPDIR)/driver_cfa_cpp-NameMatcher.Tpo Tuples/$(DEPDIR)/driver_cfa_cpp-NameMatcher.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='Tuples/NameMatcher.cc' object='Tuples/driver_cfa_cpp-NameMatcher.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Tuples/driver_cfa_cpp-NameMatcher.obj `if test -f 'Tuples/NameMatcher.cc'; then $(CYGPATH_W) 'Tuples/NameMatcher.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/NameMatcher.cc'; fi`
+Tuples/driver_cfa_cpp-TupleExpansion.o: Tuples/TupleExpansion.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-TupleExpansion.o -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Tpo -c -o Tuples/driver_cfa_cpp-TupleExpansion.o `test -f 'Tuples/TupleExpansion.cc' || echo '$(srcdir)/'`Tuples/TupleExpansion.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Tpo Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='Tuples/TupleExpansion.cc' object='Tuples/driver_cfa_cpp-TupleExpansion.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Tuples/driver_cfa_cpp-TupleExpansion.o `test -f 'Tuples/TupleExpansion.cc' || echo '$(srcdir)/'`Tuples/TupleExpansion.cc
+
+Tuples/driver_cfa_cpp-TupleExpansion.obj: Tuples/TupleExpansion.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-TupleExpansion.obj -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Tpo -c -o Tuples/driver_cfa_cpp-TupleExpansion.obj `if test -f 'Tuples/TupleExpansion.cc'; then $(CYGPATH_W) 'Tuples/TupleExpansion.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/TupleExpansion.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Tpo Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='Tuples/TupleExpansion.cc' object='Tuples/driver_cfa_cpp-TupleExpansion.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Tuples/driver_cfa_cpp-TupleExpansion.obj `if test -f 'Tuples/TupleExpansion.cc'; then $(CYGPATH_W) 'Tuples/TupleExpansion.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/TupleExpansion.cc'; fi`
 
 .ll.cc:
Index: src/Parser/ExpressionNode.cc
===================================================================
--- src/Parser/ExpressionNode.cc	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/Parser/ExpressionNode.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -200,15 +200,13 @@
 }
 
-Expression *build_fieldSel( ExpressionNode *expr_node, NameExpr *member ) {
-	UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), maybeMoveBuild< Expression >(expr_node) );
-	delete member;
-	return ret;
-}
-
-Expression *build_pfieldSel( ExpressionNode *expr_node, NameExpr *member ) {
+Expression *build_fieldSel( ExpressionNode *expr_node, Expression *member ) {
+	UntypedMemberExpr *ret = new UntypedMemberExpr( member, maybeMoveBuild< Expression >(expr_node) );
+	return ret;
+}
+
+Expression *build_pfieldSel( ExpressionNode *expr_node, Expression *member ) {
 	UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
 	deref->get_args().push_back( maybeMoveBuild< Expression >(expr_node) );
-	UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), deref );
-	delete member;
+	UntypedMemberExpr *ret = new UntypedMemberExpr( member, deref );
 	return ret;
 }
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/Parser/ParseNode.h	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -165,6 +165,6 @@
 
 Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
-Expression * build_fieldSel( ExpressionNode * expr_node, NameExpr * member );
-Expression * build_pfieldSel( ExpressionNode * expr_node, NameExpr * member );
+Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );
+Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member );
 Expression * build_addressOf( ExpressionNode * expr_node );
 Expression * build_sizeOfexpr( ExpressionNode * expr_node );
Index: src/Parser/parser.cc
===================================================================
--- src/Parser/parser.cc	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/Parser/parser.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -1023,78 +1023,78 @@
        0,   300,   300,   304,   311,   312,   313,   317,   318,   319,
      323,   324,   328,   329,   333,   334,   338,   342,   343,   354,
-     356,   358,   360,   365,   366,   372,   376,   378,   379,   381,
-     382,   384,   386,   388,   397,   398,   404,   405,   409,   410,
-     414,   418,   420,   422,   424,   429,   432,   434,   436,   441,
-     454,   456,   458,   460,   462,   464,   466,   468,   470,   472,
-     474,   481,   482,   488,   489,   490,   491,   495,   496,   498,
-     503,   504,   506,   508,   513,   514,   516,   521,   522,   524,
-     529,   530,   532,   534,   536,   541,   542,   544,   549,   550,
-     555,   556,   561,   562,   567,   568,   573,   574,   579,   580,
-     583,   585,   590,   595,   596,   598,   604,   605,   609,   610,
-     611,   612,   613,   614,   615,   616,   617,   618,   619,   620,
-     626,   628,   630,   632,   637,   638,   643,   644,   650,   651,
-     657,   658,   659,   660,   661,   662,   663,   664,   665,   675,
-     682,   684,   694,   695,   700,   702,   708,   710,   714,   715,
-     720,   725,   728,   730,   732,   742,   744,   755,   756,   758,
-     762,   764,   768,   769,   774,   775,   779,   784,   785,   789,
-     791,   797,   798,   802,   804,   806,   808,   814,   815,   819,
-     821,   826,   828,   830,   835,   837,   842,   844,   848,   851,
-     855,   858,   862,   864,   866,   868,   873,   875,   877,   882,
-     884,   886,   888,   890,   895,   897,   899,   901,   906,   918,
-     919,   924,   926,   931,   935,   937,   939,   941,   943,   949,
-     950,   956,   957,   961,   962,   967,   969,   975,   976,   978,
-     983,   988,   998,  1000,  1004,  1005,  1010,  1012,  1016,  1017,
-    1021,  1023,  1027,  1028,  1032,  1033,  1037,  1038,  1053,  1054,
-    1055,  1056,  1057,  1061,  1066,  1073,  1083,  1088,  1093,  1101,
-    1106,  1111,  1116,  1121,  1129,  1151,  1156,  1163,  1165,  1172,
-    1177,  1182,  1193,  1198,  1203,  1208,  1213,  1222,  1227,  1235,
-    1236,  1237,  1238,  1244,  1249,  1257,  1258,  1259,  1260,  1264,
-    1265,  1266,  1267,  1272,  1273,  1282,  1283,  1288,  1289,  1294,
-    1296,  1298,  1300,  1302,  1305,  1304,  1316,  1317,  1319,  1329,
-    1330,  1335,  1337,  1339,  1341,  1343,  1346,  1348,  1351,  1356,
-    1358,  1360,  1362,  1364,  1366,  1368,  1370,  1372,  1374,  1376,
-    1378,  1380,  1386,  1387,  1389,  1391,  1393,  1398,  1399,  1405,
-    1406,  1408,  1410,  1415,  1417,  1419,  1421,  1426,  1427,  1429,
-    1431,  1436,  1437,  1439,  1444,  1445,  1447,  1449,  1454,  1456,
-    1458,  1463,  1464,  1468,  1470,  1476,  1475,  1479,  1481,  1486,
-    1488,  1494,  1495,  1500,  1501,  1503,  1504,  1513,  1514,  1516,
-    1518,  1523,  1525,  1531,  1532,  1534,  1537,  1540,  1545,  1546,
-    1551,  1556,  1560,  1562,  1568,  1567,  1574,  1576,  1582,  1583,
-    1591,  1592,  1596,  1597,  1598,  1600,  1602,  1609,  1610,  1612,
-    1614,  1619,  1620,  1626,  1627,  1631,  1632,  1637,  1638,  1639,
-    1641,  1649,  1650,  1652,  1655,  1657,  1661,  1662,  1663,  1665,
-    1667,  1671,  1676,  1684,  1685,  1694,  1696,  1701,  1702,  1703,
-    1707,  1708,  1709,  1713,  1714,  1715,  1719,  1720,  1721,  1726,
-    1727,  1728,  1729,  1735,  1736,  1738,  1743,  1744,  1749,  1750,
-    1751,  1752,  1753,  1768,  1769,  1774,  1775,  1781,  1783,  1786,
-    1788,  1790,  1813,  1814,  1816,  1818,  1823,  1824,  1826,  1831,
-    1836,  1837,  1843,  1842,  1846,  1850,  1852,  1854,  1860,  1861,
-    1866,  1871,  1873,  1878,  1880,  1881,  1883,  1888,  1890,  1892,
-    1897,  1899,  1904,  1909,  1917,  1923,  1922,  1936,  1937,  1942,
-    1943,  1947,  1952,  1957,  1965,  1970,  1981,  1982,  1987,  1988,
-    1994,  1995,  1999,  2000,  2001,  2004,  2003,  2014,  2023,  2029,
-    2035,  2044,  2050,  2056,  2062,  2068,  2076,  2082,  2090,  2096,
-    2105,  2106,  2107,  2111,  2115,  2117,  2122,  2123,  2127,  2128,
-    2133,  2139,  2140,  2143,  2145,  2146,  2150,  2151,  2152,  2153,
-    2187,  2189,  2190,  2192,  2197,  2202,  2207,  2209,  2211,  2216,
-    2218,  2220,  2222,  2227,  2229,  2238,  2240,  2241,  2246,  2248,
-    2250,  2255,  2257,  2259,  2264,  2266,  2268,  2277,  2278,  2279,
-    2283,  2285,  2287,  2292,  2294,  2296,  2301,  2303,  2305,  2320,
-    2322,  2323,  2325,  2330,  2331,  2336,  2338,  2340,  2345,  2347,
-    2349,  2351,  2356,  2358,  2360,  2370,  2372,  2373,  2375,  2380,
-    2382,  2384,  2389,  2391,  2393,  2395,  2400,  2402,  2404,  2435,
-    2437,  2438,  2440,  2445,  2450,  2458,  2460,  2462,  2467,  2469,
-    2474,  2476,  2490,  2491,  2493,  2498,  2500,  2502,  2504,  2506,
-    2511,  2512,  2514,  2516,  2521,  2523,  2525,  2531,  2533,  2535,
-    2539,  2541,  2543,  2545,  2559,  2560,  2562,  2567,  2569,  2571,
-    2573,  2575,  2580,  2581,  2583,  2585,  2590,  2592,  2594,  2600,
-    2601,  2603,  2612,  2615,  2617,  2620,  2622,  2624,  2637,  2638,
-    2640,  2645,  2647,  2649,  2651,  2653,  2658,  2659,  2661,  2663,
-    2668,  2670,  2678,  2679,  2680,  2685,  2686,  2690,  2692,  2694,
-    2696,  2698,  2700,  2707,  2709,  2711,  2713,  2715,  2717,  2719,
-    2721,  2723,  2725,  2730,  2732,  2734,  2739,  2765,  2766,  2768,
-    2772,  2773,  2777,  2779,  2781,  2783,  2785,  2787,  2794,  2796,
-    2798,  2800,  2802,  2804,  2809,  2814,  2816,  2818,  2836,  2838,
-    2843,  2844
+     356,   358,   360,   365,   366,   372,   376,   378,   380,   382,
+     384,   386,   388,   390,   399,   400,   406,   407,   411,   412,
+     416,   420,   422,   424,   426,   431,   434,   436,   438,   443,
+     456,   458,   460,   462,   464,   466,   468,   470,   472,   474,
+     476,   483,   484,   490,   491,   492,   493,   497,   498,   500,
+     505,   506,   508,   510,   515,   516,   518,   523,   524,   526,
+     531,   532,   534,   536,   538,   543,   544,   546,   551,   552,
+     557,   558,   563,   564,   569,   570,   575,   576,   581,   582,
+     585,   587,   592,   597,   598,   600,   606,   607,   611,   612,
+     613,   614,   615,   616,   617,   618,   619,   620,   621,   622,
+     628,   630,   632,   634,   639,   640,   645,   646,   652,   653,
+     659,   660,   661,   662,   663,   664,   665,   666,   667,   677,
+     684,   686,   696,   697,   702,   704,   710,   712,   716,   717,
+     722,   727,   730,   732,   734,   744,   746,   757,   758,   760,
+     764,   766,   770,   771,   776,   777,   781,   786,   787,   791,
+     793,   799,   800,   804,   806,   808,   810,   816,   817,   821,
+     823,   828,   830,   832,   837,   839,   844,   846,   850,   853,
+     857,   860,   864,   866,   868,   870,   875,   877,   879,   884,
+     886,   888,   890,   892,   897,   899,   901,   903,   908,   920,
+     921,   926,   928,   933,   937,   939,   941,   943,   945,   951,
+     952,   958,   959,   963,   964,   969,   971,   977,   978,   980,
+     985,   990,  1000,  1002,  1006,  1007,  1012,  1014,  1018,  1019,
+    1023,  1025,  1029,  1030,  1034,  1035,  1039,  1040,  1055,  1056,
+    1057,  1058,  1059,  1063,  1068,  1075,  1085,  1090,  1095,  1103,
+    1108,  1113,  1118,  1123,  1131,  1153,  1158,  1165,  1167,  1174,
+    1179,  1184,  1195,  1200,  1205,  1210,  1215,  1224,  1229,  1237,
+    1238,  1239,  1240,  1246,  1251,  1259,  1260,  1261,  1262,  1266,
+    1267,  1268,  1269,  1274,  1275,  1284,  1285,  1290,  1291,  1296,
+    1298,  1300,  1302,  1304,  1307,  1306,  1318,  1319,  1321,  1331,
+    1332,  1337,  1339,  1341,  1343,  1345,  1348,  1350,  1353,  1358,
+    1360,  1362,  1364,  1366,  1368,  1370,  1372,  1374,  1376,  1378,
+    1380,  1382,  1388,  1389,  1391,  1393,  1395,  1400,  1401,  1407,
+    1408,  1410,  1412,  1417,  1419,  1421,  1423,  1428,  1429,  1431,
+    1433,  1438,  1439,  1441,  1446,  1447,  1449,  1451,  1456,  1458,
+    1460,  1465,  1466,  1470,  1472,  1478,  1477,  1481,  1483,  1488,
+    1490,  1496,  1497,  1502,  1503,  1505,  1506,  1515,  1516,  1518,
+    1520,  1525,  1527,  1533,  1534,  1536,  1539,  1542,  1547,  1548,
+    1553,  1558,  1562,  1564,  1570,  1569,  1576,  1578,  1584,  1585,
+    1593,  1594,  1598,  1599,  1600,  1602,  1604,  1611,  1612,  1614,
+    1616,  1621,  1622,  1628,  1629,  1633,  1634,  1639,  1640,  1641,
+    1643,  1651,  1652,  1654,  1657,  1659,  1663,  1664,  1665,  1667,
+    1669,  1673,  1678,  1686,  1687,  1696,  1698,  1703,  1704,  1705,
+    1709,  1710,  1711,  1715,  1716,  1717,  1721,  1722,  1723,  1728,
+    1729,  1730,  1731,  1737,  1738,  1740,  1745,  1746,  1751,  1752,
+    1753,  1754,  1755,  1770,  1771,  1776,  1777,  1783,  1785,  1788,
+    1790,  1792,  1815,  1816,  1818,  1820,  1825,  1826,  1828,  1833,
+    1838,  1839,  1845,  1844,  1848,  1852,  1854,  1856,  1862,  1863,
+    1868,  1873,  1875,  1880,  1882,  1883,  1885,  1890,  1892,  1894,
+    1899,  1901,  1906,  1911,  1919,  1925,  1924,  1938,  1939,  1944,
+    1945,  1949,  1954,  1959,  1967,  1972,  1983,  1984,  1989,  1990,
+    1996,  1997,  2001,  2002,  2003,  2006,  2005,  2016,  2025,  2031,
+    2037,  2046,  2052,  2058,  2064,  2070,  2078,  2084,  2092,  2098,
+    2107,  2108,  2109,  2113,  2117,  2119,  2124,  2125,  2129,  2130,
+    2135,  2141,  2142,  2145,  2147,  2148,  2152,  2153,  2154,  2155,
+    2189,  2191,  2192,  2194,  2199,  2204,  2209,  2211,  2213,  2218,
+    2220,  2222,  2224,  2229,  2231,  2240,  2242,  2243,  2248,  2250,
+    2252,  2257,  2259,  2261,  2266,  2268,  2270,  2279,  2280,  2281,
+    2285,  2287,  2289,  2294,  2296,  2298,  2303,  2305,  2307,  2322,
+    2324,  2325,  2327,  2332,  2333,  2338,  2340,  2342,  2347,  2349,
+    2351,  2353,  2358,  2360,  2362,  2372,  2374,  2375,  2377,  2382,
+    2384,  2386,  2391,  2393,  2395,  2397,  2402,  2404,  2406,  2437,
+    2439,  2440,  2442,  2447,  2452,  2460,  2462,  2464,  2469,  2471,
+    2476,  2478,  2492,  2493,  2495,  2500,  2502,  2504,  2506,  2508,
+    2513,  2514,  2516,  2518,  2523,  2525,  2527,  2533,  2535,  2537,
+    2541,  2543,  2545,  2547,  2561,  2562,  2564,  2569,  2571,  2573,
+    2575,  2577,  2582,  2583,  2585,  2587,  2592,  2594,  2596,  2602,
+    2603,  2605,  2614,  2617,  2619,  2622,  2624,  2626,  2639,  2640,
+    2642,  2647,  2649,  2651,  2653,  2655,  2660,  2661,  2663,  2665,
+    2670,  2672,  2680,  2681,  2682,  2687,  2688,  2692,  2694,  2696,
+    2698,  2700,  2702,  2709,  2711,  2713,  2715,  2717,  2719,  2721,
+    2723,  2725,  2727,  2732,  2734,  2736,  2741,  2767,  2768,  2770,
+    2774,  2775,  2779,  2781,  2783,  2785,  2787,  2789,  2796,  2798,
+    2800,  2802,  2804,  2806,  2811,  2816,  2818,  2820,  2838,  2840,
+    2845,  2846
 };
 #endif
@@ -5077,15 +5077,29 @@
     break;
 
+  case 27:
+
+/* Line 1806 of yacc.c  */
+#line 379 "parser.yy"
+    { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(1) - (7)].en), build_tuple( (yyvsp[(5) - (7)].en) ) ) ); }
+    break;
+
   case 28:
 
 /* Line 1806 of yacc.c  */
-#line 380 "parser.yy"
+#line 381 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(1) - (3)].en), build_varref( (yyvsp[(3) - (3)].tok) ) ) ); }
     break;
 
+  case 29:
+
+/* Line 1806 of yacc.c  */
+#line 383 "parser.yy"
+    { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(1) - (7)].en), build_tuple( (yyvsp[(5) - (7)].en) ) ) ); }
+    break;
+
   case 30:
 
 /* Line 1806 of yacc.c  */
-#line 383 "parser.yy"
+#line 385 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds::IncrPost, (yyvsp[(1) - (2)].en) ) ); }
     break;
@@ -5094,5 +5108,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 385 "parser.yy"
+#line 387 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds::DecrPost, (yyvsp[(1) - (2)].en) ) ); }
     break;
@@ -5101,5 +5115,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 387 "parser.yy"
+#line 389 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_compoundLiteral( (yyvsp[(2) - (7)].decl), new InitializerNode( (yyvsp[(5) - (7)].in), true ) ) ); }
     break;
@@ -5108,5 +5122,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 389 "parser.yy"
+#line 391 "parser.yy"
     {
 			Token fn;
@@ -5119,5 +5133,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 399 "parser.yy"
+#line 401 "parser.yy"
     { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) )); }
     break;
@@ -5126,5 +5140,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 404 "parser.yy"
+#line 406 "parser.yy"
     { (yyval.en) = 0; }
     break;
@@ -5133,5 +5147,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 410 "parser.yy"
+#line 412 "parser.yy"
     { (yyval.en) = (ExpressionNode *)(yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) ); }
     break;
@@ -5140,5 +5154,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 415 "parser.yy"
+#line 417 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_varref( (yyvsp[(1) - (1)].tok) ) ); }
     break;
@@ -5147,5 +5161,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 419 "parser.yy"
+#line 421 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(3) - (3)].en), build_varref( (yyvsp[(1) - (3)].tok) ) ) ); }
     break;
@@ -5154,5 +5168,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 421 "parser.yy"
+#line 423 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_fieldSel( (yyvsp[(5) - (7)].en), build_varref( (yyvsp[(1) - (7)].tok) ) ) ); }
     break;
@@ -5161,5 +5175,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 423 "parser.yy"
+#line 425 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(3) - (3)].en), build_varref( (yyvsp[(1) - (3)].tok) ) ) ); }
     break;
@@ -5168,5 +5182,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 425 "parser.yy"
+#line 427 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_pfieldSel( (yyvsp[(5) - (7)].en), build_varref( (yyvsp[(1) - (7)].tok) ) ) ); }
     break;
@@ -5175,5 +5189,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 433 "parser.yy"
+#line 435 "parser.yy"
     { (yyval.en) = (yyvsp[(1) - (1)].en); }
     break;
@@ -5182,5 +5196,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 435 "parser.yy"
+#line 437 "parser.yy"
     { (yyval.en) = new ExpressionNode( (yyvsp[(1) - (1)].constant) ); }
     break;
@@ -5189,5 +5203,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 437 "parser.yy"
+#line 439 "parser.yy"
     { (yyval.en) = (yyvsp[(2) - (2)].en)->set_extension( true ); }
     break;
@@ -5196,5 +5210,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 442 "parser.yy"
+#line 444 "parser.yy"
     {
 			switch ( (yyvsp[(1) - (2)].op) ) {
@@ -5214,5 +5228,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 455 "parser.yy"
+#line 457 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_unary_val( (yyvsp[(1) - (2)].op), (yyvsp[(2) - (2)].en) ) ); }
     break;
@@ -5221,5 +5235,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 457 "parser.yy"
+#line 459 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds::Incr, (yyvsp[(2) - (2)].en) ) ); }
     break;
@@ -5228,5 +5242,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 459 "parser.yy"
+#line 461 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_unary_ptr( OperKinds::Decr, (yyvsp[(2) - (2)].en) ) ); }
     break;
@@ -5235,5 +5249,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 461 "parser.yy"
+#line 463 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_sizeOfexpr( (yyvsp[(2) - (2)].en) ) ); }
     break;
@@ -5242,5 +5256,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 463 "parser.yy"
+#line 465 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_sizeOftype( (yyvsp[(3) - (4)].decl) ) ); }
     break;
@@ -5249,5 +5263,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 465 "parser.yy"
+#line 467 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_alignOfexpr( (yyvsp[(2) - (2)].en) ) ); }
     break;
@@ -5256,5 +5270,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 467 "parser.yy"
+#line 469 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_alignOftype( (yyvsp[(3) - (4)].decl) ) ); }
     break;
@@ -5263,5 +5277,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 469 "parser.yy"
+#line 471 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_offsetOf( (yyvsp[(3) - (6)].decl), build_varref( (yyvsp[(5) - (6)].tok) ) ) ); }
     break;
@@ -5270,5 +5284,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 471 "parser.yy"
+#line 473 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_attrexpr( build_varref( (yyvsp[(1) - (1)].tok) ), nullptr ) ); }
     break;
@@ -5277,5 +5291,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 473 "parser.yy"
+#line 475 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_attrexpr( build_varref( (yyvsp[(1) - (4)].tok) ), (yyvsp[(3) - (4)].en) ) ); }
     break;
@@ -5284,5 +5298,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 475 "parser.yy"
+#line 477 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_attrtype( build_varref( (yyvsp[(1) - (4)].tok) ), (yyvsp[(3) - (4)].decl) ) ); }
     break;
@@ -5291,5 +5305,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 481 "parser.yy"
+#line 483 "parser.yy"
     { (yyval.op) = OperKinds::PointTo; }
     break;
@@ -5298,5 +5312,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 482 "parser.yy"
+#line 484 "parser.yy"
     { (yyval.op) = OperKinds::AddressOf; }
     break;
@@ -5305,5 +5319,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 488 "parser.yy"
+#line 490 "parser.yy"
     { (yyval.op) = OperKinds::UnPlus; }
     break;
@@ -5312,5 +5326,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 489 "parser.yy"
+#line 491 "parser.yy"
     { (yyval.op) = OperKinds::UnMinus; }
     break;
@@ -5319,5 +5333,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 490 "parser.yy"
+#line 492 "parser.yy"
     { (yyval.op) = OperKinds::Neg; }
     break;
@@ -5326,16 +5340,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 491 "parser.yy"
+#line 493 "parser.yy"
     { (yyval.op) = OperKinds::BitNeg; }
     break;
 
   case 68:
-
-/* Line 1806 of yacc.c  */
-#line 497 "parser.yy"
-    { (yyval.en) = new ExpressionNode( build_cast( (yyvsp[(2) - (4)].decl), (yyvsp[(4) - (4)].en) ) ); }
-    break;
-
-  case 69:
 
 /* Line 1806 of yacc.c  */
@@ -5344,8 +5351,15 @@
     break;
 
+  case 69:
+
+/* Line 1806 of yacc.c  */
+#line 501 "parser.yy"
+    { (yyval.en) = new ExpressionNode( build_cast( (yyvsp[(2) - (4)].decl), (yyvsp[(4) - (4)].en) ) ); }
+    break;
+
   case 71:
 
 /* Line 1806 of yacc.c  */
-#line 505 "parser.yy"
+#line 507 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Mul, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5354,5 +5368,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 507 "parser.yy"
+#line 509 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Div, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5361,5 +5375,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 509 "parser.yy"
+#line 511 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Mod, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5368,5 +5382,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 515 "parser.yy"
+#line 517 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Plus, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5375,5 +5389,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 517 "parser.yy"
+#line 519 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Minus, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5382,5 +5396,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 523 "parser.yy"
+#line 525 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::LShift, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5389,5 +5403,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 525 "parser.yy"
+#line 527 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::RShift, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5396,5 +5410,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 531 "parser.yy"
+#line 533 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::LThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5403,5 +5417,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 533 "parser.yy"
+#line 535 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::GThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5410,5 +5424,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 535 "parser.yy"
+#line 537 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::LEThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5417,5 +5431,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 537 "parser.yy"
+#line 539 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::GEThan, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5424,5 +5438,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 543 "parser.yy"
+#line 545 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Eq, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5431,5 +5445,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 545 "parser.yy"
+#line 547 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Neq, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5438,5 +5452,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 551 "parser.yy"
+#line 553 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::BitAnd, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5445,5 +5459,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 557 "parser.yy"
+#line 559 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::Xor, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5452,5 +5466,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 563 "parser.yy"
+#line 565 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_val( OperKinds::BitOr, (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5459,5 +5473,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 569 "parser.yy"
+#line 571 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_and_or( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en), true ) ); }
     break;
@@ -5466,5 +5480,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 575 "parser.yy"
+#line 577 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_and_or( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en), false ) ); }
     break;
@@ -5473,5 +5487,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 581 "parser.yy"
+#line 583 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_cond( (yyvsp[(1) - (5)].en), (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].en) ) ); }
     break;
@@ -5480,5 +5494,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 584 "parser.yy"
+#line 586 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_cond( (yyvsp[(1) - (4)].en), (yyvsp[(1) - (4)].en), (yyvsp[(4) - (4)].en) ) ); }
     break;
@@ -5487,5 +5501,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 586 "parser.yy"
+#line 588 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_cond( (yyvsp[(1) - (5)].en), (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].en) ) ); }
     break;
@@ -5494,5 +5508,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 597 "parser.yy"
+#line 599 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_binary_ptr( (yyvsp[(2) - (3)].op), (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5501,5 +5515,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 599 "parser.yy"
+#line 601 "parser.yy"
     { (yyval.en) = ( (yyvsp[(2) - (2)].en) == 0 ) ? (yyvsp[(1) - (2)].en) : new ExpressionNode( build_binary_ptr( OperKinds::Assign, (yyvsp[(1) - (2)].en), (yyvsp[(2) - (2)].en) ) ); }
     break;
@@ -5508,5 +5522,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 604 "parser.yy"
+#line 606 "parser.yy"
     { (yyval.en) = nullptr; }
     break;
@@ -5515,5 +5529,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 609 "parser.yy"
+#line 611 "parser.yy"
     { (yyval.op) = OperKinds::Assign; }
     break;
@@ -5522,5 +5536,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 610 "parser.yy"
+#line 612 "parser.yy"
     { (yyval.op) = OperKinds::AtAssn; }
     break;
@@ -5529,5 +5543,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 611 "parser.yy"
+#line 613 "parser.yy"
     { (yyval.op) = OperKinds::MulAssn; }
     break;
@@ -5536,5 +5550,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 612 "parser.yy"
+#line 614 "parser.yy"
     { (yyval.op) = OperKinds::DivAssn; }
     break;
@@ -5543,5 +5557,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 613 "parser.yy"
+#line 615 "parser.yy"
     { (yyval.op) = OperKinds::ModAssn; }
     break;
@@ -5550,5 +5564,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 614 "parser.yy"
+#line 616 "parser.yy"
     { (yyval.op) = OperKinds::PlusAssn; }
     break;
@@ -5557,5 +5571,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 615 "parser.yy"
+#line 617 "parser.yy"
     { (yyval.op) = OperKinds::MinusAssn; }
     break;
@@ -5564,5 +5578,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 616 "parser.yy"
+#line 618 "parser.yy"
     { (yyval.op) = OperKinds::LSAssn; }
     break;
@@ -5571,5 +5585,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 617 "parser.yy"
+#line 619 "parser.yy"
     { (yyval.op) = OperKinds::RSAssn; }
     break;
@@ -5578,5 +5592,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 618 "parser.yy"
+#line 620 "parser.yy"
     { (yyval.op) = OperKinds::AndAssn; }
     break;
@@ -5585,5 +5599,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 619 "parser.yy"
+#line 621 "parser.yy"
     { (yyval.op) = OperKinds::ERAssn; }
     break;
@@ -5592,5 +5606,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 620 "parser.yy"
+#line 622 "parser.yy"
     { (yyval.op) = OperKinds::OrAssn; }
     break;
@@ -5599,5 +5613,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 627 "parser.yy"
+#line 629 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_tuple() ); }
     break;
@@ -5606,5 +5620,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 629 "parser.yy"
+#line 631 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_tuple( (yyvsp[(3) - (5)].en) ) ); }
     break;
@@ -5613,5 +5627,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 631 "parser.yy"
+#line 633 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( (yyvsp[(4) - (6)].en) ) ) ); }
     break;
@@ -5620,5 +5634,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 633 "parser.yy"
+#line 635 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_tuple( (ExpressionNode *)(yyvsp[(3) - (7)].en)->set_last( (yyvsp[(5) - (7)].en) ) ) ); }
     break;
@@ -5627,5 +5641,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 639 "parser.yy"
+#line 641 "parser.yy"
     { (yyval.en) = (ExpressionNode *)(yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) ); }
     break;
@@ -5634,5 +5648,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 645 "parser.yy"
+#line 647 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_comma( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5641,5 +5655,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 650 "parser.yy"
+#line 652 "parser.yy"
     { (yyval.en) = 0; }
     break;
@@ -5648,5 +5662,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 659 "parser.yy"
+#line 661 "parser.yy"
     { (yyval.sn) = (yyvsp[(1) - (1)].sn); }
     break;
@@ -5655,5 +5669,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 666 "parser.yy"
+#line 668 "parser.yy"
     {
 			Token fn;
@@ -5666,5 +5680,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 676 "parser.yy"
+#line 678 "parser.yy"
     {
 			(yyval.sn) = (yyvsp[(4) - (4)].sn)->add_label( (yyvsp[(1) - (4)].tok) );
@@ -5675,5 +5689,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 683 "parser.yy"
+#line 685 "parser.yy"
     { (yyval.sn) = new StatementNode( build_compound( (StatementNode *)0 ) ); }
     break;
@@ -5682,5 +5696,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 690 "parser.yy"
+#line 692 "parser.yy"
     { (yyval.sn) = new StatementNode( build_compound( (yyvsp[(5) - (7)].sn) ) ); }
     break;
@@ -5689,5 +5703,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 696 "parser.yy"
+#line 698 "parser.yy"
     { if ( (yyvsp[(1) - (3)].sn) != 0 ) { (yyvsp[(1) - (3)].sn)->set_last( (yyvsp[(3) - (3)].sn) ); (yyval.sn) = (yyvsp[(1) - (3)].sn); } }
     break;
@@ -5696,5 +5710,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 701 "parser.yy"
+#line 703 "parser.yy"
     { (yyval.sn) = new StatementNode( (yyvsp[(1) - (1)].decl) ); }
     break;
@@ -5703,5 +5717,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 703 "parser.yy"
+#line 705 "parser.yy"
     {	// mark all fields in list
 			for ( DeclarationNode *iter = (yyvsp[(2) - (2)].decl); iter != nullptr; iter = (DeclarationNode *)iter->get_next() )
@@ -5714,5 +5728,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 709 "parser.yy"
+#line 711 "parser.yy"
     { (yyval.sn) = new StatementNode( (yyvsp[(1) - (1)].decl) ); }
     break;
@@ -5721,5 +5735,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 716 "parser.yy"
+#line 718 "parser.yy"
     { if ( (yyvsp[(1) - (2)].sn) != 0 ) { (yyvsp[(1) - (2)].sn)->set_last( (yyvsp[(2) - (2)].sn) ); (yyval.sn) = (yyvsp[(1) - (2)].sn); } }
     break;
@@ -5728,5 +5742,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 721 "parser.yy"
+#line 723 "parser.yy"
     { (yyval.sn) = new StatementNode( build_expr( (yyvsp[(1) - (2)].en) ) ); }
     break;
@@ -5735,5 +5749,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 727 "parser.yy"
+#line 729 "parser.yy"
     { (yyval.sn) = new StatementNode( build_if( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn), nullptr ) ); }
     break;
@@ -5742,5 +5756,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 729 "parser.yy"
+#line 731 "parser.yy"
     { (yyval.sn) = new StatementNode( build_if( (yyvsp[(3) - (7)].en), (yyvsp[(5) - (7)].sn), (yyvsp[(7) - (7)].sn) ) ); }
     break;
@@ -5749,5 +5763,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 731 "parser.yy"
+#line 733 "parser.yy"
     { (yyval.sn) = new StatementNode( build_switch( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); }
     break;
@@ -5756,5 +5770,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 733 "parser.yy"
+#line 735 "parser.yy"
     {
 			StatementNode *sw = new StatementNode( build_switch( (yyvsp[(3) - (9)].en), (yyvsp[(8) - (9)].sn) ) );
@@ -5771,5 +5785,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 743 "parser.yy"
+#line 745 "parser.yy"
     { (yyval.sn) = new StatementNode( build_switch( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); }
     break;
@@ -5778,5 +5792,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 745 "parser.yy"
+#line 747 "parser.yy"
     {
 			StatementNode *sw = new StatementNode( build_switch( (yyvsp[(3) - (9)].en), (yyvsp[(8) - (9)].sn) ) );
@@ -5788,5 +5802,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 755 "parser.yy"
+#line 757 "parser.yy"
     { (yyval.en) = (yyvsp[(1) - (1)].en); }
     break;
@@ -5795,5 +5809,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 757 "parser.yy"
+#line 759 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_range( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -5802,5 +5816,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 762 "parser.yy"
+#line 764 "parser.yy"
     { (yyval.sn) = new StatementNode( build_case( (yyvsp[(1) - (1)].en) ) ); }
     break;
@@ -5809,5 +5823,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 764 "parser.yy"
+#line 766 "parser.yy"
     { (yyval.sn) = (StatementNode *)((yyvsp[(1) - (3)].sn)->set_last( new StatementNode( build_case( (yyvsp[(3) - (3)].en) ) ) ) ); }
     break;
@@ -5816,5 +5830,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 768 "parser.yy"
+#line 770 "parser.yy"
     { (yyval.sn) = (yyvsp[(2) - (3)].sn); }
     break;
@@ -5823,5 +5837,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 769 "parser.yy"
+#line 771 "parser.yy"
     { (yyval.sn) = new StatementNode( build_default() ); }
     break;
@@ -5830,5 +5844,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 775 "parser.yy"
+#line 777 "parser.yy"
     { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (2)].sn)->set_last( (yyvsp[(2) - (2)].sn) )); }
     break;
@@ -5837,5 +5851,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 779 "parser.yy"
+#line 781 "parser.yy"
     { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( new StatementNode( build_compound( (yyvsp[(2) - (2)].sn) ) ) ); }
     break;
@@ -5844,5 +5858,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 784 "parser.yy"
+#line 786 "parser.yy"
     { (yyval.sn) = 0; }
     break;
@@ -5851,5 +5865,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 790 "parser.yy"
+#line 792 "parser.yy"
     { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( new StatementNode( build_compound( (yyvsp[(2) - (2)].sn) ) ) ); }
     break;
@@ -5858,5 +5872,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 792 "parser.yy"
+#line 794 "parser.yy"
     { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (3)].sn)->set_last( (yyvsp[(2) - (3)].sn)->append_last_case( new StatementNode( build_compound( (yyvsp[(3) - (3)].sn) ) ) ) ) ); }
     break;
@@ -5865,5 +5879,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 797 "parser.yy"
+#line 799 "parser.yy"
     { (yyval.sn) = 0; }
     break;
@@ -5872,5 +5886,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 803 "parser.yy"
+#line 805 "parser.yy"
     { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( (yyvsp[(2) - (2)].sn) ); }
     break;
@@ -5879,5 +5893,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 805 "parser.yy"
+#line 807 "parser.yy"
     { (yyval.sn) = (yyvsp[(1) - (3)].sn)->append_last_case( new StatementNode( build_compound( (StatementNode *)(yyvsp[(2) - (3)].sn)->set_last( (yyvsp[(3) - (3)].sn) ) ) ) ); }
     break;
@@ -5886,5 +5900,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 807 "parser.yy"
+#line 809 "parser.yy"
     { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (3)].sn)->set_last( (yyvsp[(2) - (3)].sn)->append_last_case( (yyvsp[(3) - (3)].sn) ))); }
     break;
@@ -5893,5 +5907,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 809 "parser.yy"
+#line 811 "parser.yy"
     { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (4)].sn)->set_last( (yyvsp[(2) - (4)].sn)->append_last_case( new StatementNode( build_compound( (StatementNode *)(yyvsp[(3) - (4)].sn)->set_last( (yyvsp[(4) - (4)].sn) ) ) ) ) ) ); }
     break;
@@ -5900,16 +5914,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 814 "parser.yy"
+#line 816 "parser.yy"
     { (yyval.sn) = new StatementNode( build_branch( BranchStmt::Break ) ); }
     break;
 
   case 179:
-
-/* Line 1806 of yacc.c  */
-#line 820 "parser.yy"
-    { (yyval.sn) = 0; }
-    break;
-
-  case 180:
 
 /* Line 1806 of yacc.c  */
@@ -5918,8 +5925,15 @@
     break;
 
+  case 180:
+
+/* Line 1806 of yacc.c  */
+#line 824 "parser.yy"
+    { (yyval.sn) = 0; }
+    break;
+
   case 181:
 
 /* Line 1806 of yacc.c  */
-#line 827 "parser.yy"
+#line 829 "parser.yy"
     { (yyval.sn) = new StatementNode( build_while( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); }
     break;
@@ -5928,6 +5942,6 @@
 
 /* Line 1806 of yacc.c  */
-#line 829 "parser.yy"
-    { (yyval.sn) = new StatementNode( build_while( (yyvsp[(5) - (7)].en), (yyvsp[(2) - (7)].sn) ) ); }
+#line 831 "parser.yy"
+    { (yyval.sn) = new StatementNode( build_while( (yyvsp[(5) - (7)].en), (yyvsp[(2) - (7)].sn), true ) ); }
     break;
 
@@ -5935,5 +5949,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 831 "parser.yy"
+#line 833 "parser.yy"
     { (yyval.sn) = new StatementNode( build_for( (yyvsp[(4) - (6)].fctl), (yyvsp[(6) - (6)].sn) ) ); }
     break;
@@ -5942,5 +5956,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 836 "parser.yy"
+#line 838 "parser.yy"
     { (yyval.fctl) = new ForCtl( (yyvsp[(1) - (6)].en), (yyvsp[(4) - (6)].en), (yyvsp[(6) - (6)].en) ); }
     break;
@@ -5949,5 +5963,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 838 "parser.yy"
+#line 840 "parser.yy"
     { (yyval.fctl) = new ForCtl( (yyvsp[(1) - (4)].decl), (yyvsp[(2) - (4)].en), (yyvsp[(4) - (4)].en) ); }
     break;
@@ -5956,5 +5970,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 843 "parser.yy"
+#line 845 "parser.yy"
     { (yyval.sn) = new StatementNode( build_branch( (yyvsp[(2) - (3)].tok), BranchStmt::Goto ) ); }
     break;
@@ -5963,5 +5977,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 847 "parser.yy"
+#line 849 "parser.yy"
     { (yyval.sn) = new StatementNode( build_computedgoto( (yyvsp[(3) - (4)].en) ) ); }
     break;
@@ -5970,5 +5984,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 850 "parser.yy"
+#line 852 "parser.yy"
     { (yyval.sn) = new StatementNode( build_branch( BranchStmt::Continue ) ); }
     break;
@@ -5977,5 +5991,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 854 "parser.yy"
+#line 856 "parser.yy"
     { (yyval.sn) = new StatementNode( build_branch( (yyvsp[(2) - (3)].tok), BranchStmt::Continue ) ); }
     break;
@@ -5984,5 +5998,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 857 "parser.yy"
+#line 859 "parser.yy"
     { (yyval.sn) = new StatementNode( build_branch( BranchStmt::Break ) ); }
     break;
@@ -5991,5 +6005,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 861 "parser.yy"
+#line 863 "parser.yy"
     { (yyval.sn) = new StatementNode( build_branch( (yyvsp[(2) - (3)].tok), BranchStmt::Break ) ); }
     break;
@@ -5998,16 +6012,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 863 "parser.yy"
+#line 865 "parser.yy"
     { (yyval.sn) = new StatementNode( build_return( (yyvsp[(2) - (3)].en) ) ); }
     break;
 
   case 193:
-
-/* Line 1806 of yacc.c  */
-#line 865 "parser.yy"
-    { (yyval.sn) = new StatementNode( build_throw( (yyvsp[(2) - (3)].en) ) ); }
-    break;
-
-  case 194:
 
 /* Line 1806 of yacc.c  */
@@ -6016,8 +6023,15 @@
     break;
 
+  case 194:
+
+/* Line 1806 of yacc.c  */
+#line 869 "parser.yy"
+    { (yyval.sn) = new StatementNode( build_throw( (yyvsp[(2) - (3)].en) ) ); }
+    break;
+
   case 195:
 
 /* Line 1806 of yacc.c  */
-#line 869 "parser.yy"
+#line 871 "parser.yy"
     { (yyval.sn) = new StatementNode( build_throw( (yyvsp[(2) - (5)].en) ) ); }
     break;
@@ -6026,5 +6040,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 874 "parser.yy"
+#line 876 "parser.yy"
     { (yyval.sn) = new StatementNode( build_try( (yyvsp[(2) - (3)].sn), (yyvsp[(3) - (3)].sn), 0 ) ); }
     break;
@@ -6033,5 +6047,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 876 "parser.yy"
+#line 878 "parser.yy"
     { (yyval.sn) = new StatementNode( build_try( (yyvsp[(2) - (3)].sn), 0, (yyvsp[(3) - (3)].sn) ) ); }
     break;
@@ -6040,5 +6054,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 878 "parser.yy"
+#line 880 "parser.yy"
     { (yyval.sn) = new StatementNode( build_try( (yyvsp[(2) - (4)].sn), (yyvsp[(3) - (4)].sn), (yyvsp[(4) - (4)].sn) ) ); }
     break;
@@ -6047,5 +6061,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 885 "parser.yy"
+#line 887 "parser.yy"
     { (yyval.sn) = new StatementNode( build_catch( 0, (yyvsp[(5) - (5)].sn), true ) ); }
     break;
@@ -6054,5 +6068,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 887 "parser.yy"
+#line 889 "parser.yy"
     { (yyval.sn) = (StatementNode *)(yyvsp[(1) - (6)].sn)->set_last( new StatementNode( build_catch( 0, (yyvsp[(6) - (6)].sn), true ) ) ); }
     break;
@@ -6061,5 +6075,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 889 "parser.yy"
+#line 891 "parser.yy"
     { (yyval.sn) = new StatementNode( build_catch( 0, (yyvsp[(5) - (5)].sn), true ) ); }
     break;
@@ -6068,5 +6082,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 891 "parser.yy"
+#line 893 "parser.yy"
     { (yyval.sn) = (StatementNode *)(yyvsp[(1) - (6)].sn)->set_last( new StatementNode( build_catch( 0, (yyvsp[(6) - (6)].sn), true ) ) ); }
     break;
@@ -6075,5 +6089,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 896 "parser.yy"
+#line 898 "parser.yy"
     { (yyval.sn) = new StatementNode( build_catch( (yyvsp[(5) - (9)].decl), (yyvsp[(8) - (9)].sn) ) ); }
     break;
@@ -6082,5 +6096,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 898 "parser.yy"
+#line 900 "parser.yy"
     { (yyval.sn) = (StatementNode *)(yyvsp[(1) - (10)].sn)->set_last( new StatementNode( build_catch( (yyvsp[(6) - (10)].decl), (yyvsp[(9) - (10)].sn) ) ) ); }
     break;
@@ -6089,5 +6103,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 900 "parser.yy"
+#line 902 "parser.yy"
     { (yyval.sn) = new StatementNode( build_catch( (yyvsp[(5) - (9)].decl), (yyvsp[(8) - (9)].sn) ) ); }
     break;
@@ -6096,5 +6110,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 902 "parser.yy"
+#line 904 "parser.yy"
     { (yyval.sn) = (StatementNode *)(yyvsp[(1) - (10)].sn)->set_last( new StatementNode( build_catch( (yyvsp[(6) - (10)].decl), (yyvsp[(9) - (10)].sn) ) ) ); }
     break;
@@ -6103,5 +6117,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 907 "parser.yy"
+#line 909 "parser.yy"
     {
 			(yyval.sn) = new StatementNode( build_finally( (yyvsp[(2) - (2)].sn) ) );
@@ -6112,5 +6126,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 920 "parser.yy"
+#line 922 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6122,5 +6136,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 925 "parser.yy"
+#line 927 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -6129,5 +6143,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 927 "parser.yy"
+#line 929 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6139,5 +6153,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 936 "parser.yy"
+#line 938 "parser.yy"
     { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (6)].flag), (yyvsp[(4) - (6)].constant), 0 ) ); }
     break;
@@ -6146,5 +6160,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 938 "parser.yy"
+#line 940 "parser.yy"
     { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (8)].flag), (yyvsp[(4) - (8)].constant), (yyvsp[(6) - (8)].en) ) ); }
     break;
@@ -6153,5 +6167,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 940 "parser.yy"
+#line 942 "parser.yy"
     { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (10)].flag), (yyvsp[(4) - (10)].constant), (yyvsp[(6) - (10)].en), (yyvsp[(8) - (10)].en) ) ); }
     break;
@@ -6160,5 +6174,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 942 "parser.yy"
+#line 944 "parser.yy"
     { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (12)].flag), (yyvsp[(4) - (12)].constant), (yyvsp[(6) - (12)].en), (yyvsp[(8) - (12)].en), (yyvsp[(10) - (12)].en) ) ); }
     break;
@@ -6167,5 +6181,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 944 "parser.yy"
+#line 946 "parser.yy"
     { (yyval.sn) = new StatementNode( build_asmstmt( (yyvsp[(2) - (14)].flag), (yyvsp[(5) - (14)].constant), 0, (yyvsp[(8) - (14)].en), (yyvsp[(10) - (14)].en), (yyvsp[(12) - (14)].label) ) ); }
     break;
@@ -6174,5 +6188,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 949 "parser.yy"
+#line 951 "parser.yy"
     { (yyval.flag) = false; }
     break;
@@ -6181,5 +6195,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 951 "parser.yy"
+#line 953 "parser.yy"
     { (yyval.flag) = true; }
     break;
@@ -6188,5 +6202,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 956 "parser.yy"
+#line 958 "parser.yy"
     { (yyval.en) = 0; }
     break;
@@ -6195,5 +6209,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 963 "parser.yy"
+#line 965 "parser.yy"
     { (yyval.en) = (ExpressionNode *)(yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) ); }
     break;
@@ -6202,5 +6216,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 968 "parser.yy"
+#line 970 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_asmexpr( 0, (yyvsp[(1) - (4)].constant), (yyvsp[(3) - (4)].en) ) ); }
     break;
@@ -6209,5 +6223,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 970 "parser.yy"
+#line 972 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_asmexpr( (yyvsp[(2) - (7)].en), (yyvsp[(4) - (7)].constant), (yyvsp[(6) - (7)].en) ) ); }
     break;
@@ -6216,5 +6230,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 975 "parser.yy"
+#line 977 "parser.yy"
     { (yyval.en) = 0; }
     break;
@@ -6223,5 +6237,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 977 "parser.yy"
+#line 979 "parser.yy"
     { (yyval.en) = new ExpressionNode( (yyvsp[(1) - (1)].constant) ); }
     break;
@@ -6230,5 +6244,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 979 "parser.yy"
+#line 981 "parser.yy"
     { (yyval.en) = (ExpressionNode *)(yyvsp[(1) - (3)].en)->set_last( new ExpressionNode( (yyvsp[(3) - (3)].constant) ) ); }
     break;
@@ -6237,5 +6251,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 984 "parser.yy"
+#line 986 "parser.yy"
     {
 			(yyval.label) = new LabelNode(); (yyval.label)->labels.push_back( *(yyvsp[(1) - (1)].tok) );
@@ -6247,5 +6261,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 989 "parser.yy"
+#line 991 "parser.yy"
     {
 			(yyval.label) = (yyvsp[(1) - (3)].label); (yyvsp[(1) - (3)].label)->labels.push_back( *(yyvsp[(3) - (3)].tok) );
@@ -6257,5 +6271,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 999 "parser.yy"
+#line 1001 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -6264,5 +6278,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1006 "parser.yy"
+#line 1008 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -6271,5 +6285,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1011 "parser.yy"
+#line 1013 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -6278,5 +6292,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1018 "parser.yy"
+#line 1020 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -6285,5 +6299,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1032 "parser.yy"
+#line 1034 "parser.yy"
     {}
     break;
@@ -6292,5 +6306,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1033 "parser.yy"
+#line 1035 "parser.yy"
     {}
     break;
@@ -6299,5 +6313,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1062 "parser.yy"
+#line 1064 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6309,5 +6323,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1069 "parser.yy"
+#line 1071 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6319,5 +6333,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1074 "parser.yy"
+#line 1076 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( *(yyvsp[(5) - (6)].tok), TypedefTable::ID );
@@ -6329,5 +6343,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1084 "parser.yy"
+#line 1086 "parser.yy"
     {
 			typedefTable.setNextIdentifier( *(yyvsp[(2) - (3)].tok) );
@@ -6339,5 +6353,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1089 "parser.yy"
+#line 1091 "parser.yy"
     {
 			typedefTable.setNextIdentifier( *(yyvsp[(2) - (3)].tok) );
@@ -6349,5 +6363,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1094 "parser.yy"
+#line 1096 "parser.yy"
     {
 			typedefTable.setNextIdentifier( *(yyvsp[(3) - (4)].tok) );
@@ -6359,5 +6373,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1102 "parser.yy"
+#line 1104 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6369,5 +6383,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1107 "parser.yy"
+#line 1109 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6379,5 +6393,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1112 "parser.yy"
+#line 1114 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6389,5 +6403,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1117 "parser.yy"
+#line 1119 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6399,5 +6413,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1122 "parser.yy"
+#line 1124 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( *(yyvsp[(5) - (5)].tok), TypedefTable::ID );
@@ -6409,5 +6423,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1130 "parser.yy"
+#line 1132 "parser.yy"
     {
 			(yyval.decl) = DeclarationNode::newFunction( (yyvsp[(3) - (8)].tok), DeclarationNode::newTuple( 0 ), (yyvsp[(6) - (8)].decl), 0, true );
@@ -6418,5 +6432,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1153 "parser.yy"
+#line 1155 "parser.yy"
     {
 			(yyval.decl) = DeclarationNode::newFunction( (yyvsp[(2) - (7)].tok), (yyvsp[(1) - (7)].decl), (yyvsp[(5) - (7)].decl), 0, true );
@@ -6427,5 +6441,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1157 "parser.yy"
+#line 1159 "parser.yy"
     {
 			(yyval.decl) = DeclarationNode::newFunction( (yyvsp[(2) - (7)].tok), (yyvsp[(1) - (7)].decl), (yyvsp[(5) - (7)].decl), 0, true );
@@ -6436,5 +6450,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1164 "parser.yy"
+#line 1166 "parser.yy"
     { (yyval.decl) = DeclarationNode::newTuple( (yyvsp[(3) - (5)].decl) ); }
     break;
@@ -6443,5 +6457,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1168 "parser.yy"
+#line 1170 "parser.yy"
     { (yyval.decl) = DeclarationNode::newTuple( (yyvsp[(3) - (9)].decl)->appendList( (yyvsp[(7) - (9)].decl) ) ); }
     break;
@@ -6450,5 +6464,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1173 "parser.yy"
+#line 1175 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::TD );
@@ -6460,5 +6474,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1178 "parser.yy"
+#line 1180 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::TD );
@@ -6470,5 +6484,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1183 "parser.yy"
+#line 1185 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( *(yyvsp[(5) - (5)].tok), TypedefTable::TD );
@@ -6480,5 +6494,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1194 "parser.yy"
+#line 1196 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::TD );
@@ -6490,5 +6504,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1199 "parser.yy"
+#line 1201 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::TD );
@@ -6500,5 +6514,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1204 "parser.yy"
+#line 1206 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::TD );
@@ -6510,5 +6524,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1209 "parser.yy"
+#line 1211 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::TD );
@@ -6520,5 +6534,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1214 "parser.yy"
+#line 1216 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::TD );
@@ -6530,5 +6544,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1223 "parser.yy"
+#line 1225 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( *(yyvsp[(2) - (4)].tok), TypedefTable::TD );
@@ -6540,5 +6554,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1228 "parser.yy"
+#line 1230 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( *(yyvsp[(5) - (7)].tok), TypedefTable::TD );
@@ -6550,5 +6564,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1245 "parser.yy"
+#line 1247 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6560,5 +6574,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1250 "parser.yy"
+#line 1252 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -6570,5 +6584,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1272 "parser.yy"
+#line 1274 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -6577,5 +6591,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1284 "parser.yy"
+#line 1286 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -6584,5 +6598,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1295 "parser.yy"
+#line 1297 "parser.yy"
     { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Const ); }
     break;
@@ -6591,5 +6605,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1297 "parser.yy"
+#line 1299 "parser.yy"
     { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Restrict ); }
     break;
@@ -6598,5 +6612,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1299 "parser.yy"
+#line 1301 "parser.yy"
     { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Volatile ); }
     break;
@@ -6605,5 +6619,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1301 "parser.yy"
+#line 1303 "parser.yy"
     { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Lvalue ); }
     break;
@@ -6612,5 +6626,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1303 "parser.yy"
+#line 1305 "parser.yy"
     { (yyval.decl) = DeclarationNode::newQualifier( DeclarationNode::Atomic ); }
     break;
@@ -6619,5 +6633,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1305 "parser.yy"
+#line 1307 "parser.yy"
     {
 			typedefTable.enterScope();
@@ -6628,5 +6642,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1309 "parser.yy"
+#line 1311 "parser.yy"
     {
 			typedefTable.leaveScope();
@@ -6638,5 +6652,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1318 "parser.yy"
+#line 1320 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -6645,5 +6659,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1320 "parser.yy"
+#line 1322 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -6652,5 +6666,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1331 "parser.yy"
+#line 1333 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -6659,5 +6673,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1336 "parser.yy"
+#line 1338 "parser.yy"
     { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Extern ); }
     break;
@@ -6666,5 +6680,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1338 "parser.yy"
+#line 1340 "parser.yy"
     { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Static ); }
     break;
@@ -6673,5 +6687,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1340 "parser.yy"
+#line 1342 "parser.yy"
     { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Auto ); }
     break;
@@ -6680,5 +6694,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1342 "parser.yy"
+#line 1344 "parser.yy"
     { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Register ); }
     break;
@@ -6687,5 +6701,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1345 "parser.yy"
+#line 1347 "parser.yy"
     { (yyval.decl) = new DeclarationNode; (yyval.decl)->isInline = true; }
     break;
@@ -6694,5 +6708,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1347 "parser.yy"
+#line 1349 "parser.yy"
     { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Fortran ); }
     break;
@@ -6701,5 +6715,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1350 "parser.yy"
+#line 1352 "parser.yy"
     { (yyval.decl) = new DeclarationNode; (yyval.decl)->isNoreturn = true; }
     break;
@@ -6708,5 +6722,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1352 "parser.yy"
+#line 1354 "parser.yy"
     { (yyval.decl) = DeclarationNode::newStorageClass( DeclarationNode::Threadlocal ); }
     break;
@@ -6715,5 +6729,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1357 "parser.yy"
+#line 1359 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Char ); }
     break;
@@ -6722,5 +6736,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1359 "parser.yy"
+#line 1361 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Double ); }
     break;
@@ -6729,5 +6743,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1361 "parser.yy"
+#line 1363 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Float ); }
     break;
@@ -6736,5 +6750,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1363 "parser.yy"
+#line 1365 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Int ); }
     break;
@@ -6743,5 +6757,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1365 "parser.yy"
+#line 1367 "parser.yy"
     { (yyval.decl) = DeclarationNode::newModifier( DeclarationNode::Long ); }
     break;
@@ -6750,5 +6764,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1367 "parser.yy"
+#line 1369 "parser.yy"
     { (yyval.decl) = DeclarationNode::newModifier( DeclarationNode::Short ); }
     break;
@@ -6757,5 +6771,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1369 "parser.yy"
+#line 1371 "parser.yy"
     { (yyval.decl) = DeclarationNode::newModifier( DeclarationNode::Signed ); }
     break;
@@ -6764,5 +6778,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1371 "parser.yy"
+#line 1373 "parser.yy"
     { (yyval.decl) = DeclarationNode::newModifier( DeclarationNode::Unsigned ); }
     break;
@@ -6771,5 +6785,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1373 "parser.yy"
+#line 1375 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Void ); }
     break;
@@ -6778,5 +6792,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1375 "parser.yy"
+#line 1377 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Bool ); }
     break;
@@ -6785,5 +6799,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1377 "parser.yy"
+#line 1379 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Complex ); }
     break;
@@ -6792,5 +6806,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1379 "parser.yy"
+#line 1381 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBasicType( DeclarationNode::Imaginary ); }
     break;
@@ -6799,5 +6813,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1381 "parser.yy"
+#line 1383 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBuiltinType( DeclarationNode::Valist ); }
     break;
@@ -6806,5 +6820,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1388 "parser.yy"
+#line 1390 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -6813,5 +6827,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1390 "parser.yy"
+#line 1392 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -6820,5 +6834,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1392 "parser.yy"
+#line 1394 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -6827,5 +6841,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1394 "parser.yy"
+#line 1396 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addType( (yyvsp[(1) - (3)].decl) ); }
     break;
@@ -6834,5 +6848,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1400 "parser.yy"
+#line 1402 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl)->addQualifiers( (yyvsp[(1) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -6841,5 +6855,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1407 "parser.yy"
+#line 1409 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -6848,5 +6862,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1409 "parser.yy"
+#line 1411 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -6855,5 +6869,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1411 "parser.yy"
+#line 1413 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addType( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -6862,5 +6876,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1416 "parser.yy"
+#line 1418 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (4)].decl); }
     break;
@@ -6869,5 +6883,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1418 "parser.yy"
+#line 1420 "parser.yy"
     { (yyval.decl) = DeclarationNode::newTypeof( (yyvsp[(3) - (4)].en) ); }
     break;
@@ -6876,5 +6890,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1420 "parser.yy"
+#line 1422 "parser.yy"
     { (yyval.decl) = DeclarationNode::newAttr( (yyvsp[(1) - (4)].tok), (yyvsp[(3) - (4)].decl) ); }
     break;
@@ -6883,5 +6897,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1422 "parser.yy"
+#line 1424 "parser.yy"
     { (yyval.decl) = DeclarationNode::newAttr( (yyvsp[(1) - (4)].tok), (yyvsp[(3) - (4)].en) ); }
     break;
@@ -6890,5 +6904,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1428 "parser.yy"
+#line 1430 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -6897,5 +6911,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1430 "parser.yy"
+#line 1432 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -6904,5 +6918,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1432 "parser.yy"
+#line 1434 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -6911,5 +6925,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1438 "parser.yy"
+#line 1440 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -6918,5 +6932,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1440 "parser.yy"
+#line 1442 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -6925,5 +6939,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1446 "parser.yy"
+#line 1448 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -6932,5 +6946,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1448 "parser.yy"
+#line 1450 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -6939,5 +6953,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1450 "parser.yy"
+#line 1452 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -6946,5 +6960,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1455 "parser.yy"
+#line 1457 "parser.yy"
     { (yyval.decl) = DeclarationNode::newFromTypedef( (yyvsp[(1) - (1)].tok) ); }
     break;
@@ -6953,5 +6967,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1457 "parser.yy"
+#line 1459 "parser.yy"
     { (yyval.decl) = DeclarationNode::newFromTypedef( (yyvsp[(2) - (2)].tok) )->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -6960,5 +6974,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1459 "parser.yy"
+#line 1461 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -6967,5 +6981,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1469 "parser.yy"
+#line 1471 "parser.yy"
     { (yyval.decl) = DeclarationNode::newAggregate( (yyvsp[(1) - (4)].aggKey), 0, 0, (yyvsp[(3) - (4)].decl), true ); }
     break;
@@ -6974,5 +6988,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1471 "parser.yy"
+#line 1473 "parser.yy"
     {
 			typedefTable.makeTypedef( *(yyvsp[(2) - (2)].tok) );
@@ -6984,5 +6998,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1476 "parser.yy"
+#line 1478 "parser.yy"
     { typedefTable.makeTypedef( *(yyvsp[(2) - (2)].tok) ); }
     break;
@@ -6991,5 +7005,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1478 "parser.yy"
+#line 1480 "parser.yy"
     { (yyval.decl) = DeclarationNode::newAggregate( (yyvsp[(1) - (6)].aggKey), (yyvsp[(2) - (6)].tok), 0, (yyvsp[(5) - (6)].decl), true ); }
     break;
@@ -6998,5 +7012,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1480 "parser.yy"
+#line 1482 "parser.yy"
     { (yyval.decl) = DeclarationNode::newAggregate( (yyvsp[(1) - (7)].aggKey), 0, (yyvsp[(3) - (7)].en), (yyvsp[(6) - (7)].decl), false ); }
     break;
@@ -7005,5 +7019,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1482 "parser.yy"
+#line 1484 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl); }
     break;
@@ -7012,5 +7026,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1487 "parser.yy"
+#line 1489 "parser.yy"
     { (yyval.aggKey) = DeclarationNode::Struct; }
     break;
@@ -7019,5 +7033,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1489 "parser.yy"
+#line 1491 "parser.yy"
     { (yyval.aggKey) = DeclarationNode::Union; }
     break;
@@ -7026,5 +7040,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1494 "parser.yy"
+#line 1496 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -7033,5 +7047,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1496 "parser.yy"
+#line 1498 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl) != 0 ? (yyvsp[(1) - (2)].decl)->appendList( (yyvsp[(2) - (2)].decl) ) : (yyvsp[(2) - (2)].decl); }
     break;
@@ -7040,5 +7054,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1502 "parser.yy"
+#line 1504 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl)->set_extension( true ); }
     break;
@@ -7047,5 +7061,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1505 "parser.yy"
+#line 1507 "parser.yy"
     {	// mark all fields in list
 			for ( DeclarationNode *iter = (yyvsp[(2) - (3)].decl); iter != nullptr; iter = (DeclarationNode *)iter->get_next() )
@@ -7058,5 +7072,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1515 "parser.yy"
+#line 1517 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addName( (yyvsp[(2) - (2)].tok) ); }
     break;
@@ -7065,5 +7079,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1517 "parser.yy"
+#line 1519 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(1) - (3)].decl)->cloneType( (yyvsp[(3) - (3)].tok) ) ); }
     break;
@@ -7072,5 +7086,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1519 "parser.yy"
+#line 1521 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->appendList( (yyvsp[(1) - (2)].decl)->cloneType( 0 ) ); }
     break;
@@ -7079,5 +7093,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1524 "parser.yy"
+#line 1526 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7086,5 +7100,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1526 "parser.yy"
+#line 1528 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (4)].decl)->appendList( (yyvsp[(1) - (4)].decl)->cloneBaseType( (yyvsp[(4) - (4)].decl) ) ); }
     break;
@@ -7093,5 +7107,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1531 "parser.yy"
+#line 1533 "parser.yy"
     { (yyval.decl) = DeclarationNode::newName( 0 ); /* XXX */ }
     break;
@@ -7100,5 +7114,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1533 "parser.yy"
+#line 1535 "parser.yy"
     { (yyval.decl) = DeclarationNode::newBitfield( (yyvsp[(1) - (1)].en) ); }
     break;
@@ -7107,5 +7121,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1536 "parser.yy"
+#line 1538 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addBitfield( (yyvsp[(2) - (2)].en) ); }
     break;
@@ -7114,5 +7128,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1539 "parser.yy"
+#line 1541 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addBitfield( (yyvsp[(2) - (2)].en) ); }
     break;
@@ -7121,5 +7135,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1545 "parser.yy"
+#line 1547 "parser.yy"
     { (yyval.en) = 0; }
     break;
@@ -7128,5 +7142,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1547 "parser.yy"
+#line 1549 "parser.yy"
     { (yyval.en) = (yyvsp[(1) - (1)].en); }
     break;
@@ -7135,5 +7149,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1552 "parser.yy"
+#line 1554 "parser.yy"
     { (yyval.en) = (yyvsp[(2) - (2)].en); }
     break;
@@ -7142,5 +7156,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1561 "parser.yy"
+#line 1563 "parser.yy"
     { (yyval.decl) = DeclarationNode::newEnum( 0, (yyvsp[(3) - (5)].decl) ); }
     break;
@@ -7149,5 +7163,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1563 "parser.yy"
+#line 1565 "parser.yy"
     {
 			typedefTable.makeTypedef( *(yyvsp[(2) - (2)].tok) );
@@ -7159,5 +7173,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1568 "parser.yy"
+#line 1570 "parser.yy"
     { typedefTable.makeTypedef( *(yyvsp[(2) - (2)].tok) ); }
     break;
@@ -7166,5 +7180,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1570 "parser.yy"
+#line 1572 "parser.yy"
     { (yyval.decl) = DeclarationNode::newEnum( (yyvsp[(2) - (7)].tok), (yyvsp[(5) - (7)].decl) ); }
     break;
@@ -7173,5 +7187,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1575 "parser.yy"
+#line 1577 "parser.yy"
     { (yyval.decl) = DeclarationNode::newEnumConstant( (yyvsp[(1) - (2)].tok), (yyvsp[(2) - (2)].en) ); }
     break;
@@ -7180,5 +7194,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1577 "parser.yy"
+#line 1579 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (4)].decl)->appendList( DeclarationNode::newEnumConstant( (yyvsp[(3) - (4)].tok), (yyvsp[(4) - (4)].en) ) ); }
     break;
@@ -7187,5 +7201,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1582 "parser.yy"
+#line 1584 "parser.yy"
     { (yyval.en) = 0; }
     break;
@@ -7194,5 +7208,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1584 "parser.yy"
+#line 1586 "parser.yy"
     { (yyval.en) = (yyvsp[(2) - (2)].en); }
     break;
@@ -7201,5 +7215,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1591 "parser.yy"
+#line 1593 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -7208,16 +7222,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 1599 "parser.yy"
+#line 1601 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); }
     break;
 
   case 405:
-
-/* Line 1806 of yacc.c  */
-#line 1601 "parser.yy"
-    { (yyval.decl) = (yyvsp[(1) - (5)].decl)->addVarArgs(); }
-    break;
-
-  case 406:
 
 /* Line 1806 of yacc.c  */
@@ -7226,12 +7233,12 @@
     break;
 
+  case 406:
+
+/* Line 1806 of yacc.c  */
+#line 1605 "parser.yy"
+    { (yyval.decl) = (yyvsp[(1) - (5)].decl)->addVarArgs(); }
+    break;
+
   case 408:
-
-/* Line 1806 of yacc.c  */
-#line 1611 "parser.yy"
-    { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); }
-    break;
-
-  case 409:
 
 /* Line 1806 of yacc.c  */
@@ -7240,8 +7247,15 @@
     break;
 
+  case 409:
+
+/* Line 1806 of yacc.c  */
+#line 1615 "parser.yy"
+    { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); }
+    break;
+
   case 410:
 
 /* Line 1806 of yacc.c  */
-#line 1615 "parser.yy"
+#line 1617 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (9)].decl)->appendList( (yyvsp[(5) - (9)].decl) )->appendList( (yyvsp[(9) - (9)].decl) ); }
     break;
@@ -7250,5 +7264,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1621 "parser.yy"
+#line 1623 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); }
     break;
@@ -7257,5 +7271,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1626 "parser.yy"
+#line 1628 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -7264,16 +7278,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 1633 "parser.yy"
+#line 1635 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (5)].decl)->addVarArgs(); }
     break;
 
   case 419:
-
-/* Line 1806 of yacc.c  */
-#line 1640 "parser.yy"
-    { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); }
-    break;
-
-  case 420:
 
 /* Line 1806 of yacc.c  */
@@ -7282,8 +7289,15 @@
     break;
 
+  case 420:
+
+/* Line 1806 of yacc.c  */
+#line 1644 "parser.yy"
+    { (yyval.decl) = (yyvsp[(1) - (5)].decl)->appendList( (yyvsp[(5) - (5)].decl) ); }
+    break;
+
   case 422:
 
 /* Line 1806 of yacc.c  */
-#line 1651 "parser.yy"
+#line 1653 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addName( (yyvsp[(2) - (3)].tok) ); }
     break;
@@ -7292,5 +7306,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1654 "parser.yy"
+#line 1656 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addName( (yyvsp[(2) - (3)].tok) ); }
     break;
@@ -7299,5 +7313,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1656 "parser.yy"
+#line 1658 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addName( (yyvsp[(3) - (4)].tok) )->addQualifiers( (yyvsp[(1) - (4)].decl) ); }
     break;
@@ -7306,5 +7320,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1666 "parser.yy"
+#line 1668 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7313,5 +7327,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1672 "parser.yy"
+#line 1674 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7323,5 +7337,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1677 "parser.yy"
+#line 1679 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7333,5 +7347,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1686 "parser.yy"
+#line 1688 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7340,5 +7354,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1695 "parser.yy"
+#line 1697 "parser.yy"
     { (yyval.decl) = DeclarationNode::newName( (yyvsp[(1) - (1)].tok) ); }
     break;
@@ -7347,5 +7361,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1697 "parser.yy"
+#line 1699 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( DeclarationNode::newName( (yyvsp[(3) - (3)].tok) ) ); }
     break;
@@ -7354,5 +7368,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1722 "parser.yy"
+#line 1724 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7361,5 +7375,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1730 "parser.yy"
+#line 1732 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addType( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7368,5 +7382,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1735 "parser.yy"
+#line 1737 "parser.yy"
     { (yyval.in) = 0; }
     break;
@@ -7375,5 +7389,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1737 "parser.yy"
+#line 1739 "parser.yy"
     { (yyval.in) = (yyvsp[(2) - (2)].in); }
     break;
@@ -7382,5 +7396,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1739 "parser.yy"
+#line 1741 "parser.yy"
     { (yyval.in) = (yyvsp[(2) - (2)].in)->set_maybeConstructed( false ); }
     break;
@@ -7389,5 +7403,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1743 "parser.yy"
+#line 1745 "parser.yy"
     { (yyval.in) = new InitializerNode( (yyvsp[(1) - (1)].en) ); }
     break;
@@ -7396,5 +7410,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1744 "parser.yy"
+#line 1746 "parser.yy"
     { (yyval.in) = new InitializerNode( (yyvsp[(2) - (4)].in), true ); }
     break;
@@ -7403,5 +7417,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1749 "parser.yy"
+#line 1751 "parser.yy"
     { (yyval.in) = 0; }
     break;
@@ -7410,5 +7424,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1751 "parser.yy"
+#line 1753 "parser.yy"
     { (yyval.in) = (yyvsp[(2) - (2)].in)->set_designators( (yyvsp[(1) - (2)].en) ); }
     break;
@@ -7417,5 +7431,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1752 "parser.yy"
+#line 1754 "parser.yy"
     { (yyval.in) = (InitializerNode *)( (yyvsp[(1) - (3)].in)->set_last( (yyvsp[(3) - (3)].in) ) ); }
     break;
@@ -7424,5 +7438,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1754 "parser.yy"
+#line 1756 "parser.yy"
     { (yyval.in) = (InitializerNode *)( (yyvsp[(1) - (4)].in)->set_last( (yyvsp[(4) - (4)].in)->set_designators( (yyvsp[(3) - (4)].en) ) ) ); }
     break;
@@ -7431,5 +7445,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1770 "parser.yy"
+#line 1772 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_varref( (yyvsp[(1) - (2)].tok) ) ); }
     break;
@@ -7438,5 +7452,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1776 "parser.yy"
+#line 1778 "parser.yy"
     { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (2)].en)->set_last( (yyvsp[(2) - (2)].en) ) ); }
     break;
@@ -7445,16 +7459,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 1782 "parser.yy"
+#line 1784 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_varref( (yyvsp[(2) - (2)].tok) ) ); }
     break;
 
   case 468:
-
-/* Line 1806 of yacc.c  */
-#line 1785 "parser.yy"
-    { (yyval.en) = (yyvsp[(3) - (5)].en); }
-    break;
-
-  case 469:
 
 /* Line 1806 of yacc.c  */
@@ -7463,8 +7470,15 @@
     break;
 
+  case 469:
+
+/* Line 1806 of yacc.c  */
+#line 1789 "parser.yy"
+    { (yyval.en) = (yyvsp[(3) - (5)].en); }
+    break;
+
   case 470:
 
 /* Line 1806 of yacc.c  */
-#line 1789 "parser.yy"
+#line 1791 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_range( (yyvsp[(3) - (7)].en), (yyvsp[(5) - (7)].en) ) ); }
     break;
@@ -7473,5 +7487,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1791 "parser.yy"
+#line 1793 "parser.yy"
     { (yyval.en) = (yyvsp[(4) - (6)].en); }
     break;
@@ -7480,5 +7494,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1815 "parser.yy"
+#line 1817 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7487,5 +7501,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1817 "parser.yy"
+#line 1819 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -7494,5 +7508,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1819 "parser.yy"
+#line 1821 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->addQualifiers( (yyvsp[(2) - (3)].decl) )->addQualifiers( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -7501,5 +7515,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1825 "parser.yy"
+#line 1827 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7508,5 +7522,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1827 "parser.yy"
+#line 1829 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -7515,5 +7529,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1832 "parser.yy"
+#line 1834 "parser.yy"
     { (yyval.decl) = DeclarationNode::newFromTypeGen( (yyvsp[(1) - (4)].tok), (yyvsp[(3) - (4)].en) ); }
     break;
@@ -7522,5 +7536,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1838 "parser.yy"
+#line 1840 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (4)].decl)->appendList( (yyvsp[(3) - (4)].decl) ); }
     break;
@@ -7529,5 +7543,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1843 "parser.yy"
+#line 1845 "parser.yy"
     { typedefTable.addToEnclosingScope( *(yyvsp[(2) - (2)].tok), TypedefTable::TD ); }
     break;
@@ -7536,5 +7550,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1845 "parser.yy"
+#line 1847 "parser.yy"
     { (yyval.decl) = DeclarationNode::newTypeParam( (yyvsp[(1) - (4)].tclass), (yyvsp[(2) - (4)].tok) )->addAssertions( (yyvsp[(4) - (4)].decl) ); }
     break;
@@ -7543,5 +7557,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1851 "parser.yy"
+#line 1853 "parser.yy"
     { (yyval.tclass) = DeclarationNode::Type; }
     break;
@@ -7550,5 +7564,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1853 "parser.yy"
+#line 1855 "parser.yy"
     { (yyval.tclass) = DeclarationNode::Ftype; }
     break;
@@ -7557,5 +7571,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1855 "parser.yy"
+#line 1857 "parser.yy"
     { (yyval.tclass) = DeclarationNode::Dtype; }
     break;
@@ -7564,5 +7578,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1860 "parser.yy"
+#line 1862 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -7571,5 +7585,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1862 "parser.yy"
+#line 1864 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl) != 0 ? (yyvsp[(1) - (2)].decl)->appendList( (yyvsp[(2) - (2)].decl) ) : (yyvsp[(2) - (2)].decl); }
     break;
@@ -7578,5 +7592,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1867 "parser.yy"
+#line 1869 "parser.yy"
     {
 			typedefTable.openTrait( *(yyvsp[(2) - (5)].tok) );
@@ -7588,5 +7602,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1872 "parser.yy"
+#line 1874 "parser.yy"
     { (yyval.decl) = (yyvsp[(4) - (5)].decl); }
     break;
@@ -7595,5 +7609,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1874 "parser.yy"
+#line 1876 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -7602,5 +7616,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1879 "parser.yy"
+#line 1881 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_typevalue( (yyvsp[(1) - (1)].decl) ) ); }
     break;
@@ -7609,5 +7623,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1882 "parser.yy"
+#line 1884 "parser.yy"
     { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (3)].en)->set_last( new ExpressionNode( build_typevalue( (yyvsp[(3) - (3)].decl) ) ) ) ); }
     break;
@@ -7616,5 +7630,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1884 "parser.yy"
+#line 1886 "parser.yy"
     { (yyval.en) = (ExpressionNode *)( (yyvsp[(1) - (3)].en)->set_last( (yyvsp[(3) - (3)].en) )); }
     break;
@@ -7623,5 +7637,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1889 "parser.yy"
+#line 1891 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl); }
     break;
@@ -7630,5 +7644,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1891 "parser.yy"
+#line 1893 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addQualifiers( (yyvsp[(1) - (3)].decl) ); }
     break;
@@ -7637,5 +7651,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1893 "parser.yy"
+#line 1895 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl)->copyStorageClasses( (yyvsp[(1) - (3)].decl) ) ); }
     break;
@@ -7644,5 +7658,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1898 "parser.yy"
+#line 1900 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addAssertions( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -7651,5 +7665,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1900 "parser.yy"
+#line 1902 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (4)].decl)->addAssertions( (yyvsp[(2) - (4)].decl) )->addType( (yyvsp[(4) - (4)].decl) ); }
     break;
@@ -7658,5 +7672,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1905 "parser.yy"
+#line 1907 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( *(yyvsp[(1) - (1)].tok), TypedefTable::TD );
@@ -7668,5 +7682,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1910 "parser.yy"
+#line 1912 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( *(yyvsp[(1) - (6)].tok), TypedefTable::TG );
@@ -7678,5 +7692,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1918 "parser.yy"
+#line 1920 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( *(yyvsp[(2) - (9)].tok), TypedefTable::ID );
@@ -7688,5 +7702,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1923 "parser.yy"
+#line 1925 "parser.yy"
     {
 			typedefTable.enterTrait( *(yyvsp[(2) - (8)].tok) );
@@ -7698,5 +7712,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1928 "parser.yy"
+#line 1930 "parser.yy"
     {
 			typedefTable.leaveTrait();
@@ -7709,5 +7723,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1938 "parser.yy"
+#line 1940 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -7716,5 +7730,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1948 "parser.yy"
+#line 1950 "parser.yy"
     {
 			typedefTable.addToEnclosingScope2( TypedefTable::ID );
@@ -7726,5 +7740,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1953 "parser.yy"
+#line 1955 "parser.yy"
     {
 			typedefTable.addToEnclosingScope2( TypedefTable::ID );
@@ -7736,5 +7750,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1958 "parser.yy"
+#line 1960 "parser.yy"
     {
 			typedefTable.addToEnclosingScope2( *(yyvsp[(5) - (5)].tok), TypedefTable::ID );
@@ -7746,5 +7760,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1966 "parser.yy"
+#line 1968 "parser.yy"
     {
 			typedefTable.addToEnclosingScope2( TypedefTable::ID );
@@ -7756,5 +7770,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1971 "parser.yy"
+#line 1973 "parser.yy"
     {
 			typedefTable.addToEnclosingScope2( TypedefTable::ID );
@@ -7766,5 +7780,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1981 "parser.yy"
+#line 1983 "parser.yy"
     {}
     break;
@@ -7773,5 +7787,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1983 "parser.yy"
+#line 1985 "parser.yy"
     { parseTree = parseTree != nullptr ? parseTree->appendList( (yyvsp[(1) - (1)].decl) ) : (yyvsp[(1) - (1)].decl);	}
     break;
@@ -7780,5 +7794,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1989 "parser.yy"
+#line 1991 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (3)].decl) != nullptr ? (yyvsp[(1) - (3)].decl)->appendList( (yyvsp[(3) - (3)].decl) ) : (yyvsp[(3) - (3)].decl); }
     break;
@@ -7787,5 +7801,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 1994 "parser.yy"
+#line 1996 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -7794,5 +7808,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2002 "parser.yy"
+#line 2004 "parser.yy"
     {}
     break;
@@ -7801,5 +7815,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2004 "parser.yy"
+#line 2006 "parser.yy"
     {
 			linkageStack.push( linkage );				// handle nested extern "C"/"Cforall"
@@ -7811,5 +7825,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2009 "parser.yy"
+#line 2011 "parser.yy"
     {
 			linkage = linkageStack.top();
@@ -7822,5 +7836,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2015 "parser.yy"
+#line 2017 "parser.yy"
     {	// mark all fields in list
 			for ( DeclarationNode *iter = (yyvsp[(2) - (2)].decl); iter != nullptr; iter = (DeclarationNode *)iter->get_next() )
@@ -7833,5 +7847,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2030 "parser.yy"
+#line 2032 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7844,5 +7858,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2036 "parser.yy"
+#line 2038 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7855,5 +7869,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2045 "parser.yy"
+#line 2047 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7866,5 +7880,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2051 "parser.yy"
+#line 2053 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7877,5 +7891,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2057 "parser.yy"
+#line 2059 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7888,5 +7902,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2063 "parser.yy"
+#line 2065 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7899,5 +7913,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2069 "parser.yy"
+#line 2071 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7910,5 +7924,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2077 "parser.yy"
+#line 2079 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7921,5 +7935,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2083 "parser.yy"
+#line 2085 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7932,5 +7946,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2091 "parser.yy"
+#line 2093 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7943,5 +7957,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2097 "parser.yy"
+#line 2099 "parser.yy"
     {
 			typedefTable.addToEnclosingScope( TypedefTable::ID );
@@ -7954,5 +7968,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2112 "parser.yy"
+#line 2114 "parser.yy"
     { (yyval.en) = new ExpressionNode( build_range( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     break;
@@ -7961,5 +7975,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2117 "parser.yy"
+#line 2119 "parser.yy"
     { delete (yyvsp[(3) - (5)].str); }
     break;
@@ -7968,5 +7982,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2122 "parser.yy"
+#line 2124 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -7975,5 +7989,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2129 "parser.yy"
+#line 2131 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -7982,5 +7996,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2135 "parser.yy"
+#line 2137 "parser.yy"
     { (yyval.decl) = 0; }
     break;
@@ -7989,5 +8003,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2146 "parser.yy"
+#line 2148 "parser.yy"
     { delete (yyvsp[(3) - (4)].en); }
     break;
@@ -7996,23 +8010,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2150 "parser.yy"
+#line 2152 "parser.yy"
     { delete (yyvsp[(1) - (1)].tok); }
     break;
 
   case 557:
-
-/* Line 1806 of yacc.c  */
-#line 2151 "parser.yy"
-    { delete (yyvsp[(1) - (1)].decl); }
-    break;
-
-  case 558:
-
-/* Line 1806 of yacc.c  */
-#line 2152 "parser.yy"
-    { delete (yyvsp[(1) - (1)].decl); }
-    break;
-
-  case 559:
 
 /* Line 1806 of yacc.c  */
@@ -8021,19 +8021,26 @@
     break;
 
+  case 558:
+
+/* Line 1806 of yacc.c  */
+#line 2154 "parser.yy"
+    { delete (yyvsp[(1) - (1)].decl); }
+    break;
+
+  case 559:
+
+/* Line 1806 of yacc.c  */
+#line 2155 "parser.yy"
+    { delete (yyvsp[(1) - (1)].decl); }
+    break;
+
   case 560:
 
 /* Line 1806 of yacc.c  */
-#line 2188 "parser.yy"
+#line 2190 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
 
   case 562:
-
-/* Line 1806 of yacc.c  */
-#line 2191 "parser.yy"
-    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
-    break;
-
-  case 563:
 
 /* Line 1806 of yacc.c  */
@@ -8042,8 +8049,15 @@
     break;
 
+  case 563:
+
+/* Line 1806 of yacc.c  */
+#line 2195 "parser.yy"
+    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
+    break;
+
   case 564:
 
 /* Line 1806 of yacc.c  */
-#line 2198 "parser.yy"
+#line 2200 "parser.yy"
     {
 			typedefTable.setNextIdentifier( *(yyvsp[(1) - (1)].tok) );
@@ -8055,5 +8069,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2203 "parser.yy"
+#line 2205 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8062,5 +8076,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2208 "parser.yy"
+#line 2210 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8069,5 +8083,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2210 "parser.yy"
+#line 2212 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -8076,5 +8090,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2212 "parser.yy"
+#line 2214 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8083,16 +8097,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2217 "parser.yy"
+#line 2219 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); }
     break;
 
   case 570:
-
-/* Line 1806 of yacc.c  */
-#line 2219 "parser.yy"
-    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
-    break;
-
-  case 571:
 
 /* Line 1806 of yacc.c  */
@@ -8101,8 +8108,15 @@
     break;
 
+  case 571:
+
+/* Line 1806 of yacc.c  */
+#line 2223 "parser.yy"
+    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
+    break;
+
   case 572:
 
 /* Line 1806 of yacc.c  */
-#line 2223 "parser.yy"
+#line 2225 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8111,5 +8125,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2228 "parser.yy"
+#line 2230 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     break;
@@ -8118,5 +8132,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2230 "parser.yy"
+#line 2232 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8125,5 +8139,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2239 "parser.yy"
+#line 2241 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8132,5 +8146,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2242 "parser.yy"
+#line 2244 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8139,5 +8153,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2247 "parser.yy"
+#line 2249 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); }
     break;
@@ -8146,5 +8160,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2249 "parser.yy"
+#line 2251 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     break;
@@ -8153,5 +8167,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2251 "parser.yy"
+#line 2253 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8160,5 +8174,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2256 "parser.yy"
+#line 2258 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8167,5 +8181,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2258 "parser.yy"
+#line 2260 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -8174,16 +8188,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2260 "parser.yy"
+#line 2262 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
 
   case 584:
-
-/* Line 1806 of yacc.c  */
-#line 2265 "parser.yy"
-    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
-    break;
-
-  case 585:
 
 /* Line 1806 of yacc.c  */
@@ -8192,8 +8199,15 @@
     break;
 
+  case 585:
+
+/* Line 1806 of yacc.c  */
+#line 2269 "parser.yy"
+    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
+    break;
+
   case 586:
 
 /* Line 1806 of yacc.c  */
-#line 2269 "parser.yy"
+#line 2271 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8202,5 +8216,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2284 "parser.yy"
+#line 2286 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (4)].decl)->addIdList( (yyvsp[(3) - (4)].decl) ); }
     break;
@@ -8209,5 +8223,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2286 "parser.yy"
+#line 2288 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (6)].decl)->addIdList( (yyvsp[(5) - (6)].decl) ); }
     break;
@@ -8216,5 +8230,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2288 "parser.yy"
+#line 2290 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8223,5 +8237,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2293 "parser.yy"
+#line 2295 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8230,5 +8244,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2295 "parser.yy"
+#line 2297 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -8237,16 +8251,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2297 "parser.yy"
+#line 2299 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
 
   case 596:
-
-/* Line 1806 of yacc.c  */
-#line 2302 "parser.yy"
-    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
-    break;
-
-  case 597:
 
 /* Line 1806 of yacc.c  */
@@ -8255,8 +8262,15 @@
     break;
 
+  case 597:
+
+/* Line 1806 of yacc.c  */
+#line 2306 "parser.yy"
+    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
+    break;
+
   case 598:
 
 /* Line 1806 of yacc.c  */
-#line 2306 "parser.yy"
+#line 2308 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8265,16 +8279,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2321 "parser.yy"
+#line 2323 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
 
   case 601:
-
-/* Line 1806 of yacc.c  */
-#line 2324 "parser.yy"
-    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
-    break;
-
-  case 602:
 
 /* Line 1806 of yacc.c  */
@@ -8283,8 +8290,15 @@
     break;
 
+  case 602:
+
+/* Line 1806 of yacc.c  */
+#line 2328 "parser.yy"
+    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
+    break;
+
   case 604:
 
 /* Line 1806 of yacc.c  */
-#line 2332 "parser.yy"
+#line 2334 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8293,5 +8307,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2337 "parser.yy"
+#line 2339 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8300,5 +8314,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2339 "parser.yy"
+#line 2341 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -8307,5 +8321,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2341 "parser.yy"
+#line 2343 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8314,16 +8328,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2346 "parser.yy"
+#line 2348 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); }
     break;
 
   case 609:
-
-/* Line 1806 of yacc.c  */
-#line 2348 "parser.yy"
-    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
-    break;
-
-  case 610:
 
 /* Line 1806 of yacc.c  */
@@ -8332,8 +8339,15 @@
     break;
 
+  case 610:
+
+/* Line 1806 of yacc.c  */
+#line 2352 "parser.yy"
+    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
+    break;
+
   case 611:
 
 /* Line 1806 of yacc.c  */
-#line 2352 "parser.yy"
+#line 2354 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8342,5 +8356,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2357 "parser.yy"
+#line 2359 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); }
     break;
@@ -8349,5 +8363,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2359 "parser.yy"
+#line 2361 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     break;
@@ -8356,5 +8370,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2361 "parser.yy"
+#line 2363 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8363,16 +8377,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2371 "parser.yy"
+#line 2373 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
 
   case 617:
-
-/* Line 1806 of yacc.c  */
-#line 2374 "parser.yy"
-    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
-    break;
-
-  case 618:
 
 /* Line 1806 of yacc.c  */
@@ -8381,8 +8388,15 @@
     break;
 
+  case 618:
+
+/* Line 1806 of yacc.c  */
+#line 2378 "parser.yy"
+    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
+    break;
+
   case 619:
 
 /* Line 1806 of yacc.c  */
-#line 2381 "parser.yy"
+#line 2383 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8391,5 +8405,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2383 "parser.yy"
+#line 2385 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -8398,5 +8412,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2385 "parser.yy"
+#line 2387 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8405,16 +8419,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2390 "parser.yy"
+#line 2392 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); }
     break;
 
   case 623:
-
-/* Line 1806 of yacc.c  */
-#line 2392 "parser.yy"
-    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
-    break;
-
-  case 624:
 
 /* Line 1806 of yacc.c  */
@@ -8423,8 +8430,15 @@
     break;
 
+  case 624:
+
+/* Line 1806 of yacc.c  */
+#line 2396 "parser.yy"
+    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
+    break;
+
   case 625:
 
 /* Line 1806 of yacc.c  */
-#line 2396 "parser.yy"
+#line 2398 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8433,5 +8447,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2401 "parser.yy"
+#line 2403 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); }
     break;
@@ -8440,5 +8454,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2403 "parser.yy"
+#line 2405 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     break;
@@ -8447,5 +8461,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2405 "parser.yy"
+#line 2407 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8454,16 +8468,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2436 "parser.yy"
+#line 2438 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
     break;
 
   case 631:
-
-/* Line 1806 of yacc.c  */
-#line 2439 "parser.yy"
-    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
-    break;
-
-  case 632:
 
 /* Line 1806 of yacc.c  */
@@ -8472,8 +8479,15 @@
     break;
 
+  case 632:
+
+/* Line 1806 of yacc.c  */
+#line 2443 "parser.yy"
+    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
+    break;
+
   case 633:
 
 /* Line 1806 of yacc.c  */
-#line 2446 "parser.yy"
+#line 2448 "parser.yy"
     {
 			typedefTable.setNextIdentifier( *(yyvsp[(1) - (1)].tok) );
@@ -8485,5 +8499,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2451 "parser.yy"
+#line 2453 "parser.yy"
     {
 			typedefTable.setNextIdentifier( *(yyvsp[(1) - (1)].tok) );
@@ -8495,5 +8509,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2459 "parser.yy"
+#line 2461 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8502,5 +8516,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2461 "parser.yy"
+#line 2463 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -8509,5 +8523,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2463 "parser.yy"
+#line 2465 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8516,5 +8530,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2468 "parser.yy"
+#line 2470 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8523,5 +8537,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2470 "parser.yy"
+#line 2472 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
     break;
@@ -8530,5 +8544,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2475 "parser.yy"
+#line 2477 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addParamList( (yyvsp[(4) - (6)].decl) ); }
     break;
@@ -8537,16 +8551,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2477 "parser.yy"
+#line 2479 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     break;
 
   case 643:
-
-/* Line 1806 of yacc.c  */
-#line 2492 "parser.yy"
-    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
-    break;
-
-  case 644:
 
 /* Line 1806 of yacc.c  */
@@ -8555,8 +8562,15 @@
     break;
 
+  case 644:
+
+/* Line 1806 of yacc.c  */
+#line 2496 "parser.yy"
+    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
+    break;
+
   case 645:
 
 /* Line 1806 of yacc.c  */
-#line 2499 "parser.yy"
+#line 2501 "parser.yy"
     { (yyval.decl) = DeclarationNode::newPointer( 0 ); }
     break;
@@ -8565,5 +8579,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2501 "parser.yy"
+#line 2503 "parser.yy"
     { (yyval.decl) = DeclarationNode::newPointer( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8572,5 +8586,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2503 "parser.yy"
+#line 2505 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8579,5 +8593,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2505 "parser.yy"
+#line 2507 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -8586,16 +8600,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2507 "parser.yy"
+#line 2509 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
 
   case 651:
-
-/* Line 1806 of yacc.c  */
-#line 2513 "parser.yy"
-    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
-    break;
-
-  case 652:
 
 /* Line 1806 of yacc.c  */
@@ -8604,8 +8611,15 @@
     break;
 
+  case 652:
+
+/* Line 1806 of yacc.c  */
+#line 2517 "parser.yy"
+    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
+    break;
+
   case 653:
 
 /* Line 1806 of yacc.c  */
-#line 2517 "parser.yy"
+#line 2519 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8614,5 +8628,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2522 "parser.yy"
+#line 2524 "parser.yy"
     { (yyval.decl) = DeclarationNode::newFunction( 0, 0, (yyvsp[(3) - (5)].decl), 0 ); }
     break;
@@ -8621,5 +8635,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2524 "parser.yy"
+#line 2526 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     break;
@@ -8628,5 +8642,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2526 "parser.yy"
+#line 2528 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8635,5 +8649,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2532 "parser.yy"
+#line 2534 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( 0, 0, false ); }
     break;
@@ -8642,5 +8656,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2534 "parser.yy"
+#line 2536 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( 0, 0, false )->addArray( (yyvsp[(3) - (3)].decl) ); }
     break;
@@ -8649,5 +8663,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2540 "parser.yy"
+#line 2542 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(3) - (5)].en), 0, false ); }
     break;
@@ -8656,5 +8670,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2542 "parser.yy"
+#line 2544 "parser.yy"
     { (yyval.decl) = DeclarationNode::newVarArray( 0 ); }
     break;
@@ -8663,5 +8677,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2544 "parser.yy"
+#line 2546 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addArray( DeclarationNode::newArray( (yyvsp[(4) - (6)].en), 0, false ) ); }
     break;
@@ -8670,16 +8684,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2546 "parser.yy"
+#line 2548 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (6)].decl)->addArray( DeclarationNode::newVarArray( 0 ) ); }
     break;
 
   case 665:
-
-/* Line 1806 of yacc.c  */
-#line 2561 "parser.yy"
-    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
-    break;
-
-  case 666:
 
 /* Line 1806 of yacc.c  */
@@ -8688,8 +8695,15 @@
     break;
 
+  case 666:
+
+/* Line 1806 of yacc.c  */
+#line 2565 "parser.yy"
+    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
+    break;
+
   case 667:
 
 /* Line 1806 of yacc.c  */
-#line 2568 "parser.yy"
+#line 2570 "parser.yy"
     { (yyval.decl) = DeclarationNode::newPointer( 0 ); }
     break;
@@ -8698,5 +8712,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2570 "parser.yy"
+#line 2572 "parser.yy"
     { (yyval.decl) = DeclarationNode::newPointer( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8705,5 +8719,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2572 "parser.yy"
+#line 2574 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8712,5 +8726,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2574 "parser.yy"
+#line 2576 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -8719,16 +8733,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2576 "parser.yy"
+#line 2578 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
 
   case 673:
-
-/* Line 1806 of yacc.c  */
-#line 2582 "parser.yy"
-    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
-    break;
-
-  case 674:
 
 /* Line 1806 of yacc.c  */
@@ -8737,8 +8744,15 @@
     break;
 
+  case 674:
+
+/* Line 1806 of yacc.c  */
+#line 2586 "parser.yy"
+    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
+    break;
+
   case 675:
 
 /* Line 1806 of yacc.c  */
-#line 2586 "parser.yy"
+#line 2588 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8747,5 +8761,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2591 "parser.yy"
+#line 2593 "parser.yy"
     { (yyval.decl) = DeclarationNode::newFunction( 0, 0, (yyvsp[(3) - (5)].decl), 0 ); }
     break;
@@ -8754,5 +8768,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2593 "parser.yy"
+#line 2595 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     break;
@@ -8761,5 +8775,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2595 "parser.yy"
+#line 2597 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8768,5 +8782,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2602 "parser.yy"
+#line 2604 "parser.yy"
     { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addArray( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8775,5 +8789,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2613 "parser.yy"
+#line 2615 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( 0, 0, false ); }
     break;
@@ -8782,5 +8796,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2616 "parser.yy"
+#line 2618 "parser.yy"
     { (yyval.decl) = DeclarationNode::newVarArray( (yyvsp[(3) - (6)].decl) ); }
     break;
@@ -8789,5 +8803,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2618 "parser.yy"
+#line 2620 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( 0, (yyvsp[(3) - (5)].decl), false ); }
     break;
@@ -8796,5 +8810,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2621 "parser.yy"
+#line 2623 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(4) - (6)].en), (yyvsp[(3) - (6)].decl), false ); }
     break;
@@ -8803,5 +8817,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2623 "parser.yy"
+#line 2625 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(5) - (7)].en), (yyvsp[(4) - (7)].decl), true ); }
     break;
@@ -8810,16 +8824,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2625 "parser.yy"
+#line 2627 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(5) - (7)].en), (yyvsp[(3) - (7)].decl), true ); }
     break;
 
   case 689:
-
-/* Line 1806 of yacc.c  */
-#line 2639 "parser.yy"
-    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
-    break;
-
-  case 690:
 
 /* Line 1806 of yacc.c  */
@@ -8828,8 +8835,15 @@
     break;
 
+  case 690:
+
+/* Line 1806 of yacc.c  */
+#line 2643 "parser.yy"
+    { (yyval.decl) = (yyvsp[(1) - (2)].decl)->addQualifiers( (yyvsp[(2) - (2)].decl) ); }
+    break;
+
   case 691:
 
 /* Line 1806 of yacc.c  */
-#line 2646 "parser.yy"
+#line 2648 "parser.yy"
     { (yyval.decl) = DeclarationNode::newPointer( 0 ); }
     break;
@@ -8838,5 +8852,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2648 "parser.yy"
+#line 2650 "parser.yy"
     { (yyval.decl) = DeclarationNode::newPointer( (yyvsp[(2) - (2)].decl) ); }
     break;
@@ -8845,5 +8859,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2650 "parser.yy"
+#line 2652 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8852,5 +8866,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2652 "parser.yy"
+#line 2654 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addPointer( DeclarationNode::newPointer( (yyvsp[(2) - (3)].decl) ) ); }
     break;
@@ -8859,16 +8873,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2654 "parser.yy"
+#line 2656 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
 
   case 697:
-
-/* Line 1806 of yacc.c  */
-#line 2660 "parser.yy"
-    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
-    break;
-
-  case 698:
 
 /* Line 1806 of yacc.c  */
@@ -8877,8 +8884,15 @@
     break;
 
+  case 698:
+
+/* Line 1806 of yacc.c  */
+#line 2664 "parser.yy"
+    { (yyval.decl) = (yyvsp[(2) - (4)].decl)->addArray( (yyvsp[(4) - (4)].decl) ); }
+    break;
+
   case 699:
 
 /* Line 1806 of yacc.c  */
-#line 2664 "parser.yy"
+#line 2666 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8887,5 +8901,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2669 "parser.yy"
+#line 2671 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (8)].decl)->addParamList( (yyvsp[(6) - (8)].decl) ); }
     break;
@@ -8894,5 +8908,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2671 "parser.yy"
+#line 2673 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (3)].decl); }
     break;
@@ -8901,5 +8915,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2681 "parser.yy"
+#line 2683 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -8908,5 +8922,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2691 "parser.yy"
+#line 2693 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8915,5 +8929,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2693 "parser.yy"
+#line 2695 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
     break;
@@ -8922,5 +8936,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2695 "parser.yy"
+#line 2697 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8929,5 +8943,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2697 "parser.yy"
+#line 2699 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
     break;
@@ -8936,5 +8950,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2699 "parser.yy"
+#line 2701 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -8943,5 +8957,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2701 "parser.yy"
+#line 2703 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
     break;
@@ -8950,5 +8964,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2708 "parser.yy"
+#line 2710 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     break;
@@ -8957,5 +8971,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2710 "parser.yy"
+#line 2712 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -8964,5 +8978,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2712 "parser.yy"
+#line 2714 "parser.yy"
     { (yyval.decl) = (yyvsp[(4) - (4)].decl)->addNewArray( (yyvsp[(3) - (4)].decl) )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     break;
@@ -8971,5 +8985,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2714 "parser.yy"
+#line 2716 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( (yyvsp[(2) - (3)].decl) )->addNewArray( (yyvsp[(1) - (3)].decl) ); }
     break;
@@ -8978,5 +8992,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2716 "parser.yy"
+#line 2718 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -8985,5 +8999,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2718 "parser.yy"
+#line 2720 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     break;
@@ -8992,5 +9006,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2720 "parser.yy"
+#line 2722 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -8999,5 +9013,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2722 "parser.yy"
+#line 2724 "parser.yy"
     { (yyval.decl) = (yyvsp[(4) - (4)].decl)->addNewArray( (yyvsp[(3) - (4)].decl) )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     break;
@@ -9006,5 +9020,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2724 "parser.yy"
+#line 2726 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( (yyvsp[(2) - (3)].decl) )->addNewArray( (yyvsp[(1) - (3)].decl) ); }
     break;
@@ -9013,5 +9027,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2726 "parser.yy"
+#line 2728 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -9020,5 +9034,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2731 "parser.yy"
+#line 2733 "parser.yy"
     { (yyval.decl) = DeclarationNode::newVarArray( (yyvsp[(3) - (6)].decl) ); }
     break;
@@ -9027,5 +9041,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2733 "parser.yy"
+#line 2735 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(4) - (6)].en), (yyvsp[(3) - (6)].decl), false ); }
     break;
@@ -9034,5 +9048,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2738 "parser.yy"
+#line 2740 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(4) - (6)].en), (yyvsp[(3) - (6)].decl), true ); }
     break;
@@ -9041,5 +9055,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2740 "parser.yy"
+#line 2742 "parser.yy"
     { (yyval.decl) = DeclarationNode::newArray( (yyvsp[(5) - (7)].en), (yyvsp[(4) - (7)].decl)->addQualifiers( (yyvsp[(3) - (7)].decl) ), true ); }
     break;
@@ -9048,5 +9062,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2767 "parser.yy"
+#line 2769 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addQualifiers( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -9055,5 +9069,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2778 "parser.yy"
+#line 2780 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -9062,5 +9076,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2780 "parser.yy"
+#line 2782 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
     break;
@@ -9069,5 +9083,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2782 "parser.yy"
+#line 2784 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -9076,5 +9090,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2784 "parser.yy"
+#line 2786 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
     break;
@@ -9083,5 +9097,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2786 "parser.yy"
+#line 2788 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewPointer( DeclarationNode::newPointer( 0 ) ); }
     break;
@@ -9090,5 +9104,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2788 "parser.yy"
+#line 2790 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewPointer( DeclarationNode::newPointer( (yyvsp[(1) - (3)].decl) ) ); }
     break;
@@ -9097,5 +9111,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2795 "parser.yy"
+#line 2797 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     break;
@@ -9104,5 +9118,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2797 "parser.yy"
+#line 2799 "parser.yy"
     { (yyval.decl) = (yyvsp[(4) - (4)].decl)->addNewArray( (yyvsp[(3) - (4)].decl) )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     break;
@@ -9111,5 +9125,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2799 "parser.yy"
+#line 2801 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -9118,5 +9132,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2801 "parser.yy"
+#line 2803 "parser.yy"
     { (yyval.decl) = (yyvsp[(3) - (3)].decl)->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     break;
@@ -9125,5 +9139,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2803 "parser.yy"
+#line 2805 "parser.yy"
     { (yyval.decl) = (yyvsp[(4) - (4)].decl)->addNewArray( (yyvsp[(3) - (4)].decl) )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     break;
@@ -9132,5 +9146,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2805 "parser.yy"
+#line 2807 "parser.yy"
     { (yyval.decl) = (yyvsp[(2) - (2)].decl)->addNewArray( (yyvsp[(1) - (2)].decl) ); }
     break;
@@ -9139,5 +9153,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2810 "parser.yy"
+#line 2812 "parser.yy"
     { (yyval.decl) = DeclarationNode::newTuple( (yyvsp[(3) - (5)].decl) ); }
     break;
@@ -9146,16 +9160,9 @@
 
 /* Line 1806 of yacc.c  */
-#line 2815 "parser.yy"
+#line 2817 "parser.yy"
     { (yyval.decl) = DeclarationNode::newFunction( 0, DeclarationNode::newTuple( 0 ), (yyvsp[(4) - (5)].decl), 0 ); }
     break;
 
   case 746:
-
-/* Line 1806 of yacc.c  */
-#line 2817 "parser.yy"
-    { (yyval.decl) = DeclarationNode::newFunction( 0, (yyvsp[(1) - (6)].decl), (yyvsp[(4) - (6)].decl), 0 ); }
-    break;
-
-  case 747:
 
 /* Line 1806 of yacc.c  */
@@ -9164,8 +9171,15 @@
     break;
 
+  case 747:
+
+/* Line 1806 of yacc.c  */
+#line 2821 "parser.yy"
+    { (yyval.decl) = DeclarationNode::newFunction( 0, (yyvsp[(1) - (6)].decl), (yyvsp[(4) - (6)].decl), 0 ); }
+    break;
+
   case 750:
 
 /* Line 1806 of yacc.c  */
-#line 2843 "parser.yy"
+#line 2845 "parser.yy"
     { (yyval.en) = 0; }
     break;
@@ -9174,5 +9188,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 2845 "parser.yy"
+#line 2847 "parser.yy"
     { (yyval.en) = (yyvsp[(2) - (2)].en); }
     break;
@@ -9181,5 +9195,5 @@
 
 /* Line 1806 of yacc.c  */
-#line 9184 "Parser/parser.cc"
+#line 9198 "Parser/parser.cc"
       default: break;
     }
@@ -9412,5 +9426,5 @@
 
 /* Line 2067 of yacc.c  */
-#line 2848 "parser.yy"
+#line 2850 "parser.yy"
 
 // ----end of grammar----
Index: src/Parser/parser.h
===================================================================
--- src/Parser/parser.h	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/Parser/parser.h	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -1,18 +1,18 @@
-/* A Bison parser, made by GNU Bison 3.0.2.  */
+/* A Bison parser, made by GNU Bison 2.5.  */
 
 /* Bison interface for Yacc-like parsers in C
-
-   Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
-
+   
+      Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
+   
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
-
+   
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-
+   
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
@@ -27,130 +27,122 @@
    Bison output files to be licensed under the GNU General Public
    License without this special exception.
-
+   
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
-#ifndef YY_YY_PARSER_PARSER_H_INCLUDED
-# define YY_YY_PARSER_PARSER_H_INCLUDED
-/* Debug traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 1
-#endif
-#if YYDEBUG
-extern int yydebug;
-#endif
-
-/* Token type.  */
+
+/* Tokens.  */
 #ifndef YYTOKENTYPE
 # define YYTOKENTYPE
-  enum yytokentype
-  {
-    TYPEDEF = 258,
-    AUTO = 259,
-    EXTERN = 260,
-    REGISTER = 261,
-    STATIC = 262,
-    INLINE = 263,
-    FORTRAN = 264,
-    CONST = 265,
-    VOLATILE = 266,
-    RESTRICT = 267,
-    FORALL = 268,
-    LVALUE = 269,
-    VOID = 270,
-    CHAR = 271,
-    SHORT = 272,
-    INT = 273,
-    LONG = 274,
-    FLOAT = 275,
-    DOUBLE = 276,
-    SIGNED = 277,
-    UNSIGNED = 278,
-    VALIST = 279,
-    BOOL = 280,
-    COMPLEX = 281,
-    IMAGINARY = 282,
-    TYPEOF = 283,
-    LABEL = 284,
-    ENUM = 285,
-    STRUCT = 286,
-    UNION = 287,
-    OTYPE = 288,
-    FTYPE = 289,
-    DTYPE = 290,
-    TRAIT = 291,
-    SIZEOF = 292,
-    OFFSETOF = 293,
-    ATTRIBUTE = 294,
-    EXTENSION = 295,
-    IF = 296,
-    ELSE = 297,
-    SWITCH = 298,
-    CASE = 299,
-    DEFAULT = 300,
-    DO = 301,
-    WHILE = 302,
-    FOR = 303,
-    BREAK = 304,
-    CONTINUE = 305,
-    GOTO = 306,
-    RETURN = 307,
-    CHOOSE = 308,
-    DISABLE = 309,
-    ENABLE = 310,
-    FALLTHRU = 311,
-    TRY = 312,
-    CATCH = 313,
-    CATCHRESUME = 314,
-    FINALLY = 315,
-    THROW = 316,
-    THROWRESUME = 317,
-    AT = 318,
-    ASM = 319,
-    ALIGNAS = 320,
-    ALIGNOF = 321,
-    ATOMIC = 322,
-    GENERIC = 323,
-    NORETURN = 324,
-    STATICASSERT = 325,
-    THREADLOCAL = 326,
-    IDENTIFIER = 327,
-    QUOTED_IDENTIFIER = 328,
-    TYPEDEFname = 329,
-    TYPEGENname = 330,
-    ATTR_IDENTIFIER = 331,
-    ATTR_TYPEDEFname = 332,
-    ATTR_TYPEGENname = 333,
-    INTEGERconstant = 334,
-    FLOATINGconstant = 335,
-    CHARACTERconstant = 336,
-    STRINGliteral = 337,
-    ZERO = 338,
-    ONE = 339,
-    ARROW = 340,
-    ICR = 341,
-    DECR = 342,
-    LS = 343,
-    RS = 344,
-    LE = 345,
-    GE = 346,
-    EQ = 347,
-    NE = 348,
-    ANDAND = 349,
-    OROR = 350,
-    ELLIPSIS = 351,
-    MULTassign = 352,
-    DIVassign = 353,
-    MODassign = 354,
-    PLUSassign = 355,
-    MINUSassign = 356,
-    LSassign = 357,
-    RSassign = 358,
-    ANDassign = 359,
-    ERassign = 360,
-    ORassign = 361,
-    ATassign = 362,
-    THEN = 363
-  };
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     TYPEDEF = 258,
+     AUTO = 259,
+     EXTERN = 260,
+     REGISTER = 261,
+     STATIC = 262,
+     INLINE = 263,
+     FORTRAN = 264,
+     CONST = 265,
+     VOLATILE = 266,
+     RESTRICT = 267,
+     FORALL = 268,
+     LVALUE = 269,
+     VOID = 270,
+     CHAR = 271,
+     SHORT = 272,
+     INT = 273,
+     LONG = 274,
+     FLOAT = 275,
+     DOUBLE = 276,
+     SIGNED = 277,
+     UNSIGNED = 278,
+     VALIST = 279,
+     BOOL = 280,
+     COMPLEX = 281,
+     IMAGINARY = 282,
+     TYPEOF = 283,
+     LABEL = 284,
+     ENUM = 285,
+     STRUCT = 286,
+     UNION = 287,
+     OTYPE = 288,
+     FTYPE = 289,
+     DTYPE = 290,
+     TRAIT = 291,
+     SIZEOF = 292,
+     OFFSETOF = 293,
+     ATTRIBUTE = 294,
+     EXTENSION = 295,
+     IF = 296,
+     ELSE = 297,
+     SWITCH = 298,
+     CASE = 299,
+     DEFAULT = 300,
+     DO = 301,
+     WHILE = 302,
+     FOR = 303,
+     BREAK = 304,
+     CONTINUE = 305,
+     GOTO = 306,
+     RETURN = 307,
+     CHOOSE = 308,
+     DISABLE = 309,
+     ENABLE = 310,
+     FALLTHRU = 311,
+     TRY = 312,
+     CATCH = 313,
+     CATCHRESUME = 314,
+     FINALLY = 315,
+     THROW = 316,
+     THROWRESUME = 317,
+     AT = 318,
+     ASM = 319,
+     ALIGNAS = 320,
+     ALIGNOF = 321,
+     ATOMIC = 322,
+     GENERIC = 323,
+     NORETURN = 324,
+     STATICASSERT = 325,
+     THREADLOCAL = 326,
+     IDENTIFIER = 327,
+     QUOTED_IDENTIFIER = 328,
+     TYPEDEFname = 329,
+     TYPEGENname = 330,
+     ATTR_IDENTIFIER = 331,
+     ATTR_TYPEDEFname = 332,
+     ATTR_TYPEGENname = 333,
+     INTEGERconstant = 334,
+     FLOATINGconstant = 335,
+     CHARACTERconstant = 336,
+     STRINGliteral = 337,
+     ZERO = 338,
+     ONE = 339,
+     ARROW = 340,
+     ICR = 341,
+     DECR = 342,
+     LS = 343,
+     RS = 344,
+     LE = 345,
+     GE = 346,
+     EQ = 347,
+     NE = 348,
+     ANDAND = 349,
+     OROR = 350,
+     ELLIPSIS = 351,
+     MULTassign = 352,
+     DIVassign = 353,
+     MODassign = 354,
+     PLUSassign = 355,
+     MINUSassign = 356,
+     LSassign = 357,
+     RSassign = 358,
+     ANDassign = 359,
+     ERassign = 360,
+     ORassign = 361,
+     ATassign = 362,
+     THEN = 363
+   };
 #endif
 /* Tokens.  */
@@ -262,10 +254,13 @@
 #define THEN 363
 
-/* Value type.  */
+
+
+
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE YYSTYPE;
-union YYSTYPE
+typedef union YYSTYPE
 {
-#line 115 "parser.yy" /* yacc.c:1909  */
+
+/* Line 2068 of yacc.c  */
+#line 115 "parser.yy"
 
 	Token tok;
@@ -284,14 +279,15 @@
 	bool flag;
 
-#line 287 "Parser/parser.h" /* yacc.c:1909  */
-};
+
+
+/* Line 2068 of yacc.c  */
+#line 285 "Parser/parser.h"
+} YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 #endif
 
-
 extern YYSTYPE yylval;
 
-int yyparse (void);
-
-#endif /* !YY_YY_PARSER_PARSER_H_INCLUDED  */
+
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/Parser/parser.yy	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -377,7 +377,9 @@
 		{ $$ = new ExpressionNode( build_fieldSel( $1, build_varref( $3 ) ) ); }
 	| postfix_expression '.' '[' push field_list pop ']' // CFA, tuple field selector
+		{ $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $5 ) ) ); }
 	| postfix_expression ARROW no_attr_identifier
 		{ $$ = new ExpressionNode( build_pfieldSel( $1, build_varref( $3 ) ) ); }
 	| postfix_expression ARROW '[' push field_list pop ']' // CFA, tuple field selector
+			{ $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $5 ) ) ); }
 	| postfix_expression ICR
 	  	{ $$ = new ExpressionNode( build_unary_ptr( OperKinds::IncrPost, $1 ) ); }
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -38,6 +38,5 @@
 #include "SynTree/TypeSubstitution.h"
 #include "SymTab/Validate.h"
-#include "Tuples/TupleAssignment.h"
-#include "Tuples/NameMatcher.h"
+#include "Tuples/Tuples.h"
 #include "Common/utility.h"
 #include "InitTweak/InitTweak.h"
@@ -64,4 +63,12 @@
 	}
 
+	Cost sumCost( const AltList &in ) {
+		Cost total;
+		for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {
+			total += i->cost;
+		}
+		return total;
+	}
+
 	namespace {
 		void printAlts( const AltList &list, std::ostream &os, int indent = 0 ) {
@@ -76,12 +83,4 @@
 				out.push_back( i->expr->clone() );
 			}
-		}
-
-		Cost sumCost( const AltList &in ) {
-			Cost total;
-			for ( AltList::const_iterator i = in.begin(); i != in.end(); ++i ) {
-				total += i->cost;
-			}
-			return total;
 		}
 
@@ -142,24 +141,4 @@
 		}
 
-		template< typename InputIterator, typename OutputIterator >
-		void findMinCost( InputIterator begin, InputIterator end, OutputIterator out ) {
-			AltList alternatives;
-
-			// select the alternatives that have the minimum parameter cost
-			Cost minCost = Cost::infinity;
-			for ( AltList::iterator i = begin; i != end; ++i ) {
-				if ( i->cost < minCost ) {
-					minCost = i->cost;
-					i->cost = i->cvtCost;
-					alternatives.clear();
-					alternatives.push_back( *i );
-				} else if ( i->cost == minCost ) {
-					i->cost = i->cvtCost;
-					alternatives.push_back( *i );
-				}
-			}
-			std::copy( alternatives.begin(), alternatives.end(), out );
-		}
-
 		template< typename InputIterator >
 		void simpleCombineEnvironments( InputIterator begin, InputIterator end, TypeEnvironment &result ) {
@@ -172,4 +151,16 @@
 			for ( std::list< Type* >::iterator i = expr->get_results().begin(); i != expr->get_results().end(); ++i ) {
 				(*i)->accept( global_renamer );
+			}
+		}
+
+		// flatten tuple type into list of types
+		template< typename OutputIterator >
+		void flatten( Type * type, OutputIterator out ) {
+			if ( TupleType * tupleType = dynamic_cast< TupleType * >( type ) ) {
+				for ( Type * t : *tupleType ) {
+					flatten( t, out );
+				}
+			} else {
+				*out++ = type;
 			}
 		}
@@ -241,5 +232,19 @@
 
 	template< typename StructOrUnionType >
-	void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string &name ) {
+	void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {
+
+		// // member must be either a tuple expression or a name expr
+		// if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( memberExpr->get_member() ) ) {
+		//  addAggMembers( structInst, agg->expr, agg->cost, nameExpr->get_name() );
+		// } else {
+		//  TupleExpr * tupleExpr = safe_dynamic_cast< TupleExpr * >( memberExpr->get_member() );
+		//  // xxx - ...
+		//  assert( false );
+		// }
+		// if ( TupleExpr * tupleExpr = dynamic_cast< TupleExpr * >( memberExpr->get_member() ) ) {
+
+		// }
+		NameExpr * nameExpr = safe_dynamic_cast< NameExpr * >( member );
+		const std::string & name = nameExpr->get_name();
 		std::list< Declaration* > members;
 		aggInst->lookup( name, members );
@@ -259,10 +264,7 @@
 
 	Cost computeConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) {
-		ApplicationExpr *appExpr = dynamic_cast< ApplicationExpr* >( alt.expr );
-		assert( appExpr );
-		PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
-		assert( pointer );
-		FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
-		assert( function );
+		ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( alt.expr );
+		PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
+		FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() );
 
 		Cost convCost( 0, 0, 0 );
@@ -270,5 +272,10 @@
 		std::list< DeclarationWithType* >::iterator formal = formals.begin();
 		std::list< Expression* >& actuals = appExpr->get_args();
+
+		std::list< Type * > formalTypes;
+		std::list< Type * >::iterator formalType = formalTypes.end();
+
 		for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
+
 			PRINT(
 				std::cerr << "actual expression:" << std::endl;
@@ -279,20 +286,33 @@
 			std::list< DeclarationWithType* >::iterator startFormal = formal;
 			Cost actualCost;
-			for ( std::list< Type* >::iterator actual = (*actualExpr)->get_results().begin(); actual != (*actualExpr)->get_results().end(); ++actual ) {
-				if ( formal == formals.end() ) {
-					if ( function->get_isVarArgs() ) {
-						convCost += Cost( 1, 0, 0 );
-						break;
-					} else {
-						return Cost::infinity;
+			for ( std::list< Type* >::iterator actualType = (*actualExpr)->get_results().begin(); actualType != (*actualExpr)->get_results().end(); ++actualType ) {
+
+				// tuple handling code
+				if ( formalType == formalTypes.end() ) {
+					// the type of the formal parameter may be a tuple type. To make this easier to work with,
+					// flatten the tuple type and traverse the resulting list of types, incrementing the formal
+					// iterator once its types have been extracted. Once a particular formal parameter's type has
+					// been exhausted load the next formal parameter's type.
+					if ( formal == formals.end() ) {
+						if ( function->get_isVarArgs() ) {
+							convCost += Cost( 1, 0, 0 );
+							break;
+						} else {
+							return Cost::infinity;
+						}
 					}
+					formalTypes.clear();
+					flatten( (*formal)->get_type(), back_inserter( formalTypes ) );
+					formalType = formalTypes.begin();
+					++formal;
 				}
+
 				PRINT(
 					std::cerr << std::endl << "converting ";
-					(*actual)->print( std::cerr, 8 );
+					(*actualType)->print( std::cerr, 8 );
 					std::cerr << std::endl << " to ";
 					(*formal)->get_type()->print( std::cerr, 8 );
 				)
-				Cost newCost = conversionCost( *actual, (*formal)->get_type(), indexer, alt.env );
+				Cost newCost = conversionCost( *actualType, *formalType, indexer, alt.env );
 				PRINT(
 					std::cerr << std::endl << "cost is" << newCost << std::endl;
@@ -305,7 +325,7 @@
 				actualCost += newCost;
 
-				convCost += Cost( 0, polyCost( (*formal)->get_type(), alt.env, indexer ) + polyCost( *actual, alt.env, indexer ), 0 );
-
-				formal++;
+				convCost += Cost( 0, polyCost( *formalType, alt.env, indexer ) + polyCost( *actualType, alt.env, indexer ), 0 );
+
+				formalType++;
 			}
 			if ( actualCost != Cost( 0, 0, 0 ) ) {
@@ -373,17 +393,24 @@
 		resultEnv.extractOpenVars( openVars );
 
-		/*
-		  Tuples::NameMatcher matcher( formals );
-		  try {
-		  matcher.match( actuals );
-		  } catch ( Tuples::NoMatch &e ) {
-		  std::cerr << "Alternative doesn't match: " << e.message << std::endl;
-		  }
-		*/
 		std::list< DeclarationWithType* >::iterator formal = formals.begin();
+
+		std::list< Type * > formalTypes;
+		std::list< Type * >::iterator formalType = formalTypes.end();
+
 		for ( AltList::const_iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
-			for ( std::list< Type* >::iterator actual = actualExpr->expr->get_results().begin(); actual != actualExpr->expr->get_results().end(); ++actual ) {
-				if ( formal == formals.end() ) {
-					return isVarArgs;
+			std::list< Type* > & actualTypes = actualExpr->expr->get_results();
+			for ( std::list< Type* >::iterator actualType = actualTypes.begin(); actualType != actualTypes.end(); ++actualType ) {
+				if ( formalType == formalTypes.end() ) {
+					// the type of the formal parameter may be a tuple type. To make this easier to work with,
+					// flatten the tuple type and traverse the resulting list of types, incrementing the formal
+					// iterator once its types have been extracted. Once a particular formal parameter's type has
+					// been exhausted load the next formal parameter's type.
+					if ( formal == formals.end() ) {
+						return isVarArgs;
+					}
+					formalTypes.clear();
+					flatten( (*formal)->get_type(), back_inserter( formalTypes ) );
+					formalType = formalTypes.begin();
+					++formal;
 				}
 				PRINT(
@@ -391,13 +418,18 @@
 					(*formal)->get_type()->print( std::cerr );
 					std::cerr << std::endl << "actual type is ";
-					(*actual)->print( std::cerr );
+					(*actualType)->print( std::cerr );
 					std::cerr << std::endl;
 				)
-				if ( ! unify( (*formal)->get_type(), *actual, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
+				if ( ! unify( *formalType, *actualType, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {
 					return false;
 				}
-				formal++;
-			}
-		}
+				++formalType;
+			}
+		}
+
+		// xxx - a tuple type was not completely matched
+		// partially handle the tuple with default arguments??
+		if ( formalType != formalTypes.end() ) return false;
+
 		// Handling of default values
 		while ( formal != formals.end() ) {
@@ -587,9 +619,7 @@
 		combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) );
 
-		Tuples::TupleAssignSpotter tassign( this );
-		if ( tassign.isTupleAssignment( untypedExpr, possibilities ) ) {
-			// take care of possible tuple assignments, or discard expression
-			return;
-		} // else ...
+		// take care of possible tuple assignments
+		// if not tuple assignment, assignment is taken care of as a normal function call
+		Tuples::handleTupleAssignment( *this, untypedExpr, possibilities );
 
 		AltList candidates;
@@ -665,10 +695,7 @@
 
 			PRINT(
-				ApplicationExpr *appExpr = dynamic_cast< ApplicationExpr* >( withFunc->expr );
-				assert( appExpr );
-				PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
-				assert( pointer );
-				FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() );
-				assert( function );
+				ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( withFunc->expr );
+				PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
+				FunctionType *function = safe_dynamic_cast< FunctionType* >( pointer->get_base() );
 				std::cerr << "Case +++++++++++++" << std::endl;
 				std::cerr << "formals are:" << std::endl;
@@ -791,7 +818,9 @@
 			renameTypes( alternatives.back().expr );
 			if ( StructInstType *structInst = dynamic_cast< StructInstType* >( (*i)->get_type() ) ) {
-				addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, "" );
+				NameExpr nameExpr( "" );
+				addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr );
 			} else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( (*i)->get_type() ) ) {
-				addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, "" );
+				NameExpr nameExpr( "" );
+				addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr );
 			} // if
 		} // for
@@ -1024,4 +1053,8 @@
 		}
 	}
+
+	void AlternativeFinder::visit( TupleIndexExpr *tupleExpr ) {
+		alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) );
+	}
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/AlternativeFinder.h
===================================================================
--- src/ResolvExpr/AlternativeFinder.h	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/ResolvExpr/AlternativeFinder.h	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -67,11 +67,12 @@
 		virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr );
 		virtual void visit( ConstructorExpr * ctorExpr );
-	  public:  // xxx - temporary hack - should make Tuples::TupleAssignment a friend
+		virtual void visit( TupleIndexExpr *tupleExpr );
+		/// Runs a new alternative finder on each element in [begin, end)
+		/// and writes each alternative finder to out.
 		template< typename InputIterator, typename OutputIterator >
 		void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out );
 
-	  private:
 		/// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member
-		template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string &name );
+		template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member );
 		/// Adds alternatives for offsetof expressions, given the base type and name of the member
 		template< typename StructOrUnionType > void addOffsetof( StructOrUnionType *aggInst, const std::string &name );
@@ -89,4 +90,26 @@
 
 	Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env );
+
+	template< typename InputIterator, typename OutputIterator >
+	void findMinCost( InputIterator begin, InputIterator end, OutputIterator out ) {
+		AltList alternatives;
+
+		// select the alternatives that have the minimum parameter cost
+		Cost minCost = Cost::infinity;
+		for ( InputIterator i = begin; i != end; ++i ) {
+			if ( i->cost < minCost ) {
+				minCost = i->cost;
+				i->cost = i->cvtCost;
+				alternatives.clear();
+				alternatives.push_back( *i );
+			} else if ( i->cost == minCost ) {
+				i->cost = i->cvtCost;
+				alternatives.push_back( *i );
+			}
+		}
+		std::copy( alternatives.begin(), alternatives.end(), out );
+	}
+
+	Cost sumCost( const AltList &in );
 } // namespace ResolvExpr
 
Index: src/SymTab/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/SymTab/Indexer.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -452,7 +452,10 @@
 	}
 
-	void Indexer::visit( SolvedTupleExpr *tupleExpr ) {
+	void Indexer::visit( TupleAssignExpr *tupleExpr ) {
 		acceptAllNewScope( tupleExpr->get_results(), *this );
-		acceptAll( tupleExpr->get_exprs(), *this );
+		enterScope();
+		acceptAll( tupleExpr->get_tempDecls(), *this );
+		acceptAll( tupleExpr->get_assigns(), *this );
+		leaveScope();
 	}
 
Index: src/SymTab/Indexer.h
===================================================================
--- src/SymTab/Indexer.h	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/SymTab/Indexer.h	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -64,9 +64,9 @@
 		virtual void visit( ConditionalExpr *conditionalExpr );
 		virtual void visit( CommaExpr *commaExpr );
-		virtual void visit( TupleExpr *tupleExpr );
-		virtual void visit( SolvedTupleExpr *tupleExpr );
 		virtual void visit( TypeExpr *typeExpr );
 		virtual void visit( AsmExpr *asmExpr );
 		virtual void visit( UntypedValofExpr *valofExpr );
+		virtual void visit( TupleExpr *tupleExpr );
+		virtual void visit( TupleAssignExpr *tupleExpr );
 
 		virtual void visit( TraitInstType *contextInst );
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/SynTree/Expression.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -311,23 +311,26 @@
 }
 
-UntypedMemberExpr::UntypedMemberExpr( std::string _member, Expression *_aggregate, Expression *_aname ) :
+UntypedMemberExpr::UntypedMemberExpr( Expression * _member, Expression *_aggregate, Expression *_aname ) :
 		Expression( _aname ), member(_member), aggregate(_aggregate) {}
 
 UntypedMemberExpr::UntypedMemberExpr( const UntypedMemberExpr &other ) :
-		Expression( other ), member( other.member ), aggregate( maybeClone( other.aggregate ) ) {
+		Expression( other ), member( maybeClone( other.member ) ), aggregate( maybeClone( other.aggregate ) ) {
 }
 
 UntypedMemberExpr::~UntypedMemberExpr() {
 	delete aggregate;
+	delete member;
 }
 
 void UntypedMemberExpr::print( std::ostream &os, int indent ) const {
-	os << "Untyped Member Expression, with field: " << get_member();
+	os << "Untyped Member Expression, with field: " << std::endl;
+	get_member()->print(os, indent+4);
+	os << std::string( indent+2, ' ' );
 
 	Expression *agg = get_aggregate();
-	os << ", from aggregate: ";
+	os << "from aggregate: " << std::endl;
 	if (agg != 0) {
-		os << std::string( indent + 2, ' ' );
-		agg->print(os, indent + 2);
+		os << std::string( indent + 4, ' ' );
+		agg->print(os, indent + 4);
 	}
 	os << std::string( indent+2, ' ' );
@@ -372,6 +375,6 @@
 }
 
-
-UntypedExpr::UntypedExpr( Expression *_function, Expression *_aname ) : Expression( _aname ), function( _function ) {}
+UntypedExpr::UntypedExpr( Expression *_function, const std::list<Expression *> &_args, Expression *_aname ) :
+		Expression( _aname ), function(_function), args(_args) {}
 
 UntypedExpr::UntypedExpr( const UntypedExpr &other ) :
@@ -379,7 +382,4 @@
 	cloneAll( other.args, args );
 }
-
-UntypedExpr::UntypedExpr( Expression *_function, std::list<Expression *> &_args, Expression *_aname ) :
-		Expression( _aname ), function(_function), args(_args) {}
 
 UntypedExpr::~UntypedExpr() {
@@ -565,4 +565,22 @@
 }
 
+StmtExpr::StmtExpr( CompoundStmt *statements ) : statements( statements ) {
+	assert( statements );
+	std::list< Statement * > & body = statements->get_kids();
+	if ( ! body.empty() ) {
+		if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( body.back() ) ) {
+			cloneAll( exprStmt->get_expr()->get_results(), get_results() );
+		}
+	}
+}
+StmtExpr::StmtExpr( const StmtExpr &other ) : statements( other.statements->clone() ) {}
+StmtExpr::~StmtExpr() {
+	delete statements;
+}
+void StmtExpr::print( std::ostream &os, int indent ) const {
+	os << std::string( indent, ' ' ) << "Statement Expression: " << std::endl;
+	statements->print( os, indent+2 );
+}
+
 std::ostream & operator<<( std::ostream & out, const Expression * expr ) {
 	expr->print( out );
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/SynTree/Expression.h	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -98,7 +98,6 @@
 class UntypedExpr : public Expression {
   public:
-	UntypedExpr( Expression *function, Expression *_aname = nullptr );
+	UntypedExpr( Expression *function, const std::list<Expression *> &args = std::list< Expression * >(), Expression *_aname = nullptr );
 	UntypedExpr( const UntypedExpr &other );
-	UntypedExpr( Expression *function, std::list<Expression *> &args, Expression *_aname = nullptr );
 	virtual ~UntypedExpr();
 
@@ -200,10 +199,10 @@
 class UntypedMemberExpr : public Expression {
   public:
-	UntypedMemberExpr( std::string member, Expression *aggregate, Expression *_aname = nullptr );
+	UntypedMemberExpr( Expression *member, Expression *aggregate, Expression *_aname = nullptr );
 	UntypedMemberExpr( const UntypedMemberExpr &other );
 	virtual ~UntypedMemberExpr();
 
-	std::string get_member() const { return member; }
-	void set_member( const std::string &newValue ) { member = newValue; }
+	Expression * get_member() const { return member; }
+	void set_member( Expression * newValue ) { member = newValue; }
 	Expression *get_aggregate() const { return aggregate; }
 	void set_aggregate( Expression *newValue ) { aggregate = newValue; }
@@ -214,5 +213,5 @@
 	virtual void print( std::ostream &os, int indent = 0 ) const;
   private:
-	std::string member;
+	Expression *member;
 	Expression *aggregate;
 };
@@ -483,40 +482,4 @@
 };
 
-/// TupleExpr represents a tuple expression ( [a, b, c] )
-class TupleExpr : public Expression {
-  public:
-	TupleExpr( Expression *_aname = nullptr );
-	TupleExpr( const TupleExpr &other );
-	virtual ~TupleExpr();
-
-	void set_exprs( std::list<Expression*> newValue ) { exprs = newValue; }
-	std::list<Expression*>& get_exprs() { return exprs; }
-
-	virtual TupleExpr *clone() const { return new TupleExpr( *this ); }
-	virtual void accept( Visitor &v ) { v.visit( this ); }
-	virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
-	virtual void print( std::ostream &os, int indent = 0 ) const;
-  private:
-	std::list<Expression*> exprs;
-};
-
-/// SolvedTupleExpr represents a TupleExpr whose components have been type-resolved. It is effectively a shell for the code generator to work on
-class SolvedTupleExpr : public Expression {
-  public:
-	SolvedTupleExpr( Expression *_aname = nullptr ) : Expression( _aname ) {}
-	SolvedTupleExpr( std::list<Expression *> &, Expression *_aname = nullptr );
-	SolvedTupleExpr( const SolvedTupleExpr &other );
-	virtual ~SolvedTupleExpr() {}
-
-	std::list<Expression*> &get_exprs() { return exprs; }
-
-	virtual SolvedTupleExpr *clone() const { return new SolvedTupleExpr( *this ); }
-	virtual void accept( Visitor &v ) { v.visit( this ); }
-	virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
-	virtual void print( std::ostream &os, int indent = 0 ) const;
-  private:
-	std::list<Expression*> exprs;
-};
-
 /// TypeExpr represents a type used in an expression (e.g. as a type generator parameter)
 class TypeExpr : public Expression {
@@ -618,5 +581,5 @@
 	CompoundLiteralExpr( Type * type, Initializer * initializer );
 	CompoundLiteralExpr( const CompoundLiteralExpr &other );
-	~CompoundLiteralExpr();
+	virtual ~CompoundLiteralExpr();
 
 	Type * get_type() const { return type; }
@@ -670,4 +633,101 @@
   private:
 	Expression *low, *high;
+};
+
+/// TupleExpr represents a tuple expression ( [a, b, c] )
+class TupleExpr : public Expression {
+  public:
+	TupleExpr( Expression *_aname = nullptr );
+	TupleExpr( const TupleExpr &other );
+	virtual ~TupleExpr();
+
+	void set_exprs( std::list<Expression*> newValue ) { exprs = newValue; }
+	std::list<Expression*>& get_exprs() { return exprs; }
+
+	virtual TupleExpr *clone() const { return new TupleExpr( *this ); }
+	virtual void accept( Visitor &v ) { v.visit( this ); }
+	virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const;
+  private:
+	std::list<Expression*> exprs;
+};
+
+/// TupleIndexExpr represents an element selection operation on a tuple value, e.g. t.3 after processing by the expression analyzer
+class TupleIndexExpr : public Expression {
+  public:
+	TupleIndexExpr( Expression * tuple, unsigned int index );
+	TupleIndexExpr( const TupleIndexExpr &other );
+	virtual ~TupleIndexExpr();
+
+	Expression * get_tuple() const { return tuple; }
+	int get_index() const { return index; }
+	TupleIndexExpr * set_tuple( Expression *newValue ) { tuple = newValue; return this; }
+	TupleIndexExpr * set_index( unsigned int newValue ) { index = newValue; return this; }
+
+	virtual TupleIndexExpr *clone() const { return new TupleIndexExpr( *this ); }
+	virtual void accept( Visitor &v ) { v.visit( this ); }
+	virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const;
+  private:
+	Expression * tuple;
+	unsigned int index;
+};
+
+/// MemberTupleExpr represents a tuple member selection operation on a struct type, e.g. s.[a, b, c] after processing by the expression analyzer
+class MemberTupleExpr : public Expression {
+  public:
+	MemberTupleExpr( Expression * member, Expression * aggregate, Expression * _aname = nullptr );
+	MemberTupleExpr( const MemberTupleExpr &other );
+	virtual ~MemberTupleExpr();
+
+	Expression * get_member() const { return member; }
+	Expression * get_aggregate() const { return aggregate; }
+	MemberTupleExpr * set_member( Expression *newValue ) { member = newValue; return this; }
+	MemberTupleExpr * set_aggregate( Expression *newValue ) { aggregate = newValue; return this; }
+
+	virtual MemberTupleExpr *clone() const { return new MemberTupleExpr( *this ); }
+	virtual void accept( Visitor &v ) { v.visit( this ); }
+	virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const;
+  private:
+	Expression * member;
+	Expression * aggregate;
+};
+
+/// TupleAssignExpr represents a multiple assignment operation, where both sides of the assignment have tuple type, e.g. [a, b, c] = [d, e, f];, or a mass assignment operation, where the left hand side has tuple type and the right hand side does not, e.g. [a, b, c] = 5.0;
+class TupleAssignExpr : public Expression {
+  public:
+	TupleAssignExpr( const std::list< Expression * > & assigns, const std::list< ObjectDecl * > & tempDecls, Expression * _aname = nullptr );
+	TupleAssignExpr( const TupleAssignExpr &other );
+	virtual ~TupleAssignExpr();
+
+	std::list< Expression * > & get_assigns() { return assigns; }
+	std::list< ObjectDecl * > & get_tempDecls() { return tempDecls; }
+
+	virtual TupleAssignExpr *clone() const { return new TupleAssignExpr( *this ); }
+	virtual void accept( Visitor &v ) { v.visit( this ); }
+	virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const;
+  private:
+	std::list< Expression * > assigns; // assignment expressions that use tempDecls
+	std::list< ObjectDecl * > tempDecls; // temporaries for address of lhs exprs
+};
+
+/// StmtExpr represents a GCC 'statement expression', e.g. ({ int x = 5; x; })
+class StmtExpr : public Expression {
+public:
+	StmtExpr( CompoundStmt *statements );
+	StmtExpr( const StmtExpr & other );
+	virtual ~StmtExpr();
+
+	CompoundStmt * get_statements() const { return statements; }
+	StmtExpr * set_statements( CompoundStmt * newValue ) { statements = newValue; return this; }
+
+	virtual StmtExpr *clone() const { return new StmtExpr( *this ); }
+	virtual void accept( Visitor &v ) { v.visit( this ); }
+	virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const;
+private:
+	CompoundStmt * statements;
 };
 
Index: src/SynTree/Mutator.cc
===================================================================
--- src/SynTree/Mutator.cc	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/SynTree/Mutator.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -216,4 +216,5 @@
 	mutateAll( memberExpr->get_results(), *this );
 	memberExpr->set_aggregate( maybeMutate( memberExpr->get_aggregate(), *this ) );
+	memberExpr->set_member( maybeMutate( memberExpr->get_member(), *this ) );
 	return memberExpr;
 }
@@ -307,16 +308,4 @@
 }
 
-Expression *Mutator::mutate( TupleExpr *tupleExpr ) {
-	mutateAll( tupleExpr->get_results(), *this );
-	mutateAll( tupleExpr->get_exprs(), *this );
-	return tupleExpr;
-}
-
-Expression *Mutator::mutate( SolvedTupleExpr *tupleExpr ) {
-	mutateAll( tupleExpr->get_results(), *this );
-	mutateAll( tupleExpr->get_exprs(), *this );
-	return tupleExpr;
-}
-
 Expression *Mutator::mutate( TypeExpr *typeExpr ) {
 	mutateAll( typeExpr->get_results(), *this );
@@ -361,4 +350,36 @@
 	rangeExpr->set_high( maybeMutate( rangeExpr->get_high(), *this ) );
 	return rangeExpr;
+}
+
+Expression *Mutator::mutate( TupleExpr *tupleExpr ) {
+	mutateAll( tupleExpr->get_results(), *this );
+	mutateAll( tupleExpr->get_exprs(), *this );
+	return tupleExpr;
+}
+
+Expression *Mutator::mutate( TupleIndexExpr *tupleExpr ) {
+	mutateAll( tupleExpr->get_results(), *this );
+	tupleExpr->set_tuple( maybeMutate( tupleExpr->get_tuple(), *this ) );
+	return tupleExpr;
+}
+
+Expression *Mutator::mutate( MemberTupleExpr *tupleExpr ) {
+	mutateAll( tupleExpr->get_results(), *this );
+	tupleExpr->set_member( maybeMutate( tupleExpr->get_member(), *this ) );
+	tupleExpr->set_aggregate( maybeMutate( tupleExpr->get_aggregate(), *this ) );
+	return tupleExpr;
+}
+
+Expression *Mutator::mutate( TupleAssignExpr *assignExpr ) {
+	mutateAll( assignExpr->get_results(), *this );
+	mutateAll( assignExpr->get_tempDecls(), *this );
+	mutateAll( assignExpr->get_assigns(), *this );
+	return assignExpr;
+}
+
+Expression *Mutator::mutate( StmtExpr *stmtExpr ) {
+	mutateAll( stmtExpr->get_results(), *this );
+	stmtExpr->set_statements( maybeMutate( stmtExpr->get_statements(), *this ) );
+	return stmtExpr;
 }
 
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/SynTree/Mutator.h	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -71,6 +71,4 @@
 	virtual Expression* mutate( ConditionalExpr *conditionalExpr );
 	virtual Expression* mutate( CommaExpr *commaExpr );
-	virtual Expression* mutate( TupleExpr *tupleExpr );
-	virtual Expression* mutate( SolvedTupleExpr *tupleExpr );
 	virtual Expression* mutate( TypeExpr *typeExpr );
 	virtual Expression* mutate( AsmExpr *asmExpr );
@@ -80,4 +78,9 @@
 	virtual Expression* mutate( UntypedValofExpr *valofExpr );
 	virtual Expression* mutate( RangeExpr *rangeExpr );
+	virtual Expression* mutate( TupleExpr *tupleExpr );
+	virtual Expression* mutate( TupleIndexExpr *tupleExpr );
+	virtual Expression* mutate( MemberTupleExpr *tupleExpr );
+	virtual Expression* mutate( TupleAssignExpr *assignExpr );
+	virtual Expression* mutate( StmtExpr * stmtExpr );
 
 	virtual Type* mutate( VoidType *basicType );
Index: src/SynTree/ReferenceToType.cc
===================================================================
--- src/SynTree/ReferenceToType.cc	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/SynTree/ReferenceToType.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -56,4 +56,6 @@
 	}
 } // namespace
+
+StructInstType::StructInstType( const Type::Qualifiers & tq, StructDecl * baseStruct ) : Parent( tq, baseStruct->get_name() ), baseStruct( baseStruct ) {}
 
 std::string StructInstType::typeString() const { return "struct"; }
Index: src/SynTree/SynTree.h
===================================================================
--- src/SynTree/SynTree.h	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/SynTree/SynTree.h	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -76,6 +76,4 @@
 class ConditionalExpr;
 class CommaExpr;
-class TupleExpr;
-class SolvedTupleExpr;
 class TypeExpr;
 class AsmExpr;
@@ -85,4 +83,9 @@
 class UntypedValofExpr;
 class RangeExpr;
+class TupleExpr;
+class TupleIndexExpr;
+class MemberTupleExpr;
+class TupleAssignExpr;
+class StmtExpr;
 
 class Type;
Index: src/SynTree/TupleExpr.cc
===================================================================
--- src/SynTree/TupleExpr.cc	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/SynTree/TupleExpr.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// TupleExpr.cc -- 
+// TupleExpr.cc --
 //
 // Author           : Richard C. Bilson
@@ -16,4 +16,6 @@
 #include "Expression.h"
 #include "Common/utility.h"
+#include "Type.h"
+#include "Declaration.h"
 
 TupleExpr::TupleExpr( Expression *_aname ) : Expression( _aname ) {
@@ -34,17 +36,70 @@
 }
 
-SolvedTupleExpr::SolvedTupleExpr( std::list<Expression *> &_exprs, Expression *_aname ) : Expression( _aname ) {
-	std::copy(_exprs.begin(), _exprs.end(), back_inserter(exprs));
+TupleIndexExpr::TupleIndexExpr( Expression * tuple, unsigned int index ) {
+	// TupleType * type = safe_dynamic_cast< TypeType * >( tuple->get_ )
+	assert( tuple->get_results().size() >= index );
+	add_result( *std::next( tuple->get_results().begin(), index ) );
 }
 
-SolvedTupleExpr::SolvedTupleExpr( const SolvedTupleExpr &other ) : Expression( other ) {
-	cloneAll( other.exprs, exprs );
+TupleIndexExpr::TupleIndexExpr( const TupleIndexExpr &other ) : Expression( other ), tuple( other.tuple->clone() ), index( other.index ) {
 }
 
-void SolvedTupleExpr::print( std::ostream &os, int indent ) const {
-	os << std::string( indent, ' ' ) << "Solved Tuple:" << std::endl;
-	printAll( exprs, os, indent+2 );
+TupleIndexExpr::~TupleIndexExpr() {
+	delete tuple;
+}
+
+void TupleIndexExpr::print( std::ostream &os, int indent ) const {
+	os << std::string( indent, ' ' ) << "Tuple Index Expression, with tuple:" << std::endl;
+	tuple->print( os, indent+2 );
+	os << std::string( indent+2, ' ' ) << "with index: " << index << std::endl;
 	Expression::print( os, indent );
 }
+
+MemberTupleExpr::MemberTupleExpr( Expression * member, Expression * aggregate, Expression * _aname ) : Expression( _aname ) {
+	cloneAll( member->get_results(), get_results() ); // xxx - ???
+}
+
+MemberTupleExpr::MemberTupleExpr( const MemberTupleExpr &other ) : Expression( other ), member( other.member->clone() ), aggregate( other.aggregate->clone() ) {
+}
+
+MemberTupleExpr::~MemberTupleExpr() {
+	delete member;
+	delete aggregate;
+}
+
+void MemberTupleExpr::print( std::ostream &os, int indent ) const {
+	os << std::string( indent, ' ' ) << "Member Tuple Expression, with aggregate:" << std::endl;
+	aggregate->print( os, indent+2 );
+	os << std::string( indent+2, ' ' ) << "with member: " << std::endl;
+	member->print( os, indent+2 );
+	Expression::print( os, indent );
+}
+
+
+TupleAssignExpr::TupleAssignExpr( const std::list< Expression * > & assigns, const std::list< ObjectDecl * > & tempDecls, Expression * _aname ) : Expression( _aname ), assigns( assigns ), tempDecls( tempDecls ) {
+	for ( Expression * expr : assigns ) {
+		cloneAll( expr->get_results(), get_results() );
+	}
+}
+
+TupleAssignExpr::TupleAssignExpr( const TupleAssignExpr &other ) : Expression( other ), tempDecls( other.tempDecls ) /* temporary */ {
+	cloneAll( other.assigns, assigns );
+	// xxx - clone needs to go into assigns and replace tempDecls
+}
+
+TupleAssignExpr::~TupleAssignExpr() {
+	deleteAll( assigns );
+	// deleteAll( tempDecls );
+}
+
+void TupleAssignExpr::print( std::ostream &os, int indent ) const {
+	os << std::string( indent, ' ' ) << "Tuple Assignment Expression, with temporaries:" << std::endl;
+	printAll( tempDecls, os, indent+4 );
+	os << std::string( indent+2, ' ' ) << "with assignments: " << std::endl;
+	printAll( assigns, os, indent+4 );
+	Expression::print( os, indent );
+}
+
+
 
 // Local Variables: //
Index: src/SynTree/TupleType.cc
===================================================================
--- src/SynTree/TupleType.cc	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/SynTree/TupleType.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// TupleType.cc -- 
+// TupleType.cc --
 //
 // Author           : Richard C. Bilson
@@ -17,5 +17,5 @@
 #include "Common/utility.h"
 
-TupleType::TupleType( const Type::Qualifiers &tq ) : Type( tq ) {
+TupleType::TupleType( const Type::Qualifiers &tq, const std::list< Type * > & types ) : Type( tq ), types( types ) {
 }
 
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/SynTree/Type.h	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -234,4 +234,5 @@
   public:
 	StructInstType( const Type::Qualifiers &tq, const std::string &name ) : Parent( tq, name ), baseStruct( 0 ) {}
+	StructInstType( const Type::Qualifiers &tq, StructDecl * baseStruct );
 	StructInstType( const StructInstType &other ) : Parent( other ), baseStruct( other.baseStruct ) {}
 
@@ -348,9 +349,15 @@
 class TupleType : public Type {
   public:
-	TupleType( const Type::Qualifiers &tq );
+	TupleType( const Type::Qualifiers &tq, const std::list< Type * > & types = std::list< Type * >() );
 	TupleType( const TupleType& );
 	virtual ~TupleType();
 
+	typedef std::list<Type*> value_type;
+	typedef value_type::iterator iterator;
+
 	std::list<Type*>& get_types() { return types; }
+
+	iterator begin() { return types.begin(); }
+	iterator end() { return types.end(); }
 
 	virtual TupleType *clone() const { return new TupleType( *this ); }
Index: src/SynTree/Visitor.cc
===================================================================
--- src/SynTree/Visitor.cc	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/SynTree/Visitor.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -182,4 +182,5 @@
 	acceptAll( memberExpr->get_results(), *this );
 	maybeAccept( memberExpr->get_aggregate(), *this );
+	maybeAccept( memberExpr->get_member(), *this );
 }
 
@@ -260,14 +261,4 @@
 }
 
-void Visitor::visit( TupleExpr *tupleExpr ) {
-	acceptAll( tupleExpr->get_results(), *this );
-	acceptAll( tupleExpr->get_exprs(), *this );
-}
-
-void Visitor::visit( SolvedTupleExpr *tupleExpr ) {
-	acceptAll( tupleExpr->get_results(), *this );
-	acceptAll( tupleExpr->get_exprs(), *this );
-}
-
 void Visitor::visit( TypeExpr *typeExpr ) {
 	acceptAll( typeExpr->get_results(), *this );
@@ -306,4 +297,31 @@
 	maybeAccept( rangeExpr->get_low(), *this );
 	maybeAccept( rangeExpr->get_high(), *this );
+}
+
+void Visitor::visit( TupleExpr *tupleExpr ) {
+	acceptAll( tupleExpr->get_results(), *this );
+	acceptAll( tupleExpr->get_exprs(), *this );
+}
+
+void Visitor::visit( TupleIndexExpr *tupleExpr ) {
+	acceptAll( tupleExpr->get_results(), *this );
+	maybeAccept( tupleExpr->get_tuple(), *this );
+}
+
+void Visitor::visit( MemberTupleExpr *tupleExpr ) {
+	acceptAll( tupleExpr->get_results(), *this );
+	maybeAccept( tupleExpr->get_member(), *this );
+	maybeAccept( tupleExpr->get_aggregate(), *this );
+}
+
+void Visitor::visit( TupleAssignExpr *assignExpr ) {
+	acceptAll( assignExpr->get_results(), *this );
+	acceptAll( assignExpr->get_tempDecls(), *this );
+	acceptAll( assignExpr->get_assigns(), *this );
+}
+
+void Visitor::visit( StmtExpr *stmtExpr ) {
+	acceptAll( stmtExpr->get_results(), *this );
+	maybeAccept( stmtExpr->get_statements(), *this );
 }
 
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/SynTree/Visitor.h	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -71,6 +71,4 @@
 	virtual void visit( ConditionalExpr *conditionalExpr );
 	virtual void visit( CommaExpr *commaExpr );
-	virtual void visit( TupleExpr *tupleExpr );
-	virtual void visit( SolvedTupleExpr *tupleExpr );
 	virtual void visit( TypeExpr *typeExpr );
 	virtual void visit( AsmExpr *asmExpr );
@@ -80,4 +78,9 @@
 	virtual void visit( UntypedValofExpr *valofExpr );
 	virtual void visit( RangeExpr *rangeExpr );
+	virtual void visit( TupleExpr *tupleExpr );
+	virtual void visit( TupleIndexExpr *tupleExpr );
+	virtual void visit( MemberTupleExpr *tupleExpr );
+	virtual void visit( TupleAssignExpr *assignExpr );
+	virtual void visit( StmtExpr * stmtExpr );
 
 	virtual void visit( VoidType *basicType );
Index: src/Tuples/NameMatcher.cc
===================================================================
--- src/Tuples/NameMatcher.cc	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ 	(revision )
@@ -1,67 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// NameMatcher.cc -- 
-//
-// Author           : Rodolfo G. Esteves
-// Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Mon May 18 15:00:06 2015
-// Update Count     : 1
-//
-
-#include "NameMatcher.h"
-#include "NameMatcher.h"
-
-namespace Tuples {
-	NameMatcher::NameMatcher( std::list< DeclarationWithType* > &formals ) : current( 0 ) {
-		int cnt = 0;
-		for ( std::list< DeclarationWithType *>::const_iterator f = formals.begin(); f != formals.end(); ++f ) {
-			table.insert( std::pair< std::string, int >( (*f)->get_name(), cnt++ ) );
-			index.push_back(*f);
-		} // for
-		exprs.reserve( index.size() );
-	}
-
-	NameMatcher::~NameMatcher() {}
-
-	void NameMatcher::match( ResolvExpr::AltList &alternatives ) throw (NoMatch) {
-		if ( alternatives.size() != index.size() )
-			throw NoMatch("Length of actuals and formals differ");
-
-		for ( ResolvExpr::AltList::const_iterator a = alternatives.begin(); a != alternatives.end(); ++a ) {
-			if ( a->expr->get_argName() != 0 )
-				if ( NameExpr *name = dynamic_cast<NameExpr *>( a->expr->get_argName() ) ) {
-					if ( table.find( name->get_name() ) != table.end() ) {
-						std::cerr << "Rearranging to " << table[ name->get_name() ] << "position in the list." << std::endl;
-						exprs[ table[ name->get_name() ] ] = &(*a);
-					} else
-						throw NoMatch( name->get_name() + "no such  designation" );
-				} /*else if ( TupleExpr *tup = dynamic_cast<TupleExpr *>( a->expr->get_argName() ) )
-					std::cerr << "Designated expression" << std::endl; */
-			exprs.push_back( &(*a) );
-		} // for
-
-		/*std::cerr << "In matcher/match: ";
-		  if ( exprs.size() != index.size() )
-		  std::cerr << "exprs and index differ in length" << std::endl;
-		  else
-		  std::cerr << "is all good." << std::endl;
-		*/
-	}
-
-	ResolvExpr::Alternative &NameMatcher::get_next() throw (NoMoreElements) {
-		if ( current++ >= (int)(index.size()) )
-			throw NoMoreElements();
-		return *(new ResolvExpr::Alternative());
-	}
-} // namespace Tuples
-
-// Local Variables: //
-// tab-width: 4 //
-// mode: c++ //
-// compile-command: "make install" //
-// End: //
Index: src/Tuples/NameMatcher.h
===================================================================
--- src/Tuples/NameMatcher.h	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ 	(revision )
@@ -1,62 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// NameMatcher.h -- 
-//
-// Author           : Rodolfo G. Esteves
-// Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Mon May 18 15:01:37 2015
-// Update Count     : 3
-//
-
-#ifndef _NAMEMATCHER_H_
-#define _NAMEMATCHER_H_
-
-#include <map>
-#include <vector>
-#include <string>
-
-#include "SynTree/SynTree.h"
-#include "SynTree/Mutator.h"
-
-#include "SynTree/Type.h"
-#include "SynTree/Declaration.h"
-#include "SynTree/Expression.h"
-#include "SynTree/Statement.h"
-
-#include "ResolvExpr/Alternative.h"
-
-namespace Tuples {
-	struct NoMoreElements {};
-	struct NoMatch {
-		NoMatch( std::string msg ) : message( msg ) {}
-		std::string message;
-	};
-
-	class NameMatcher {
-	  public:
-		NameMatcher( std::list< DeclarationWithType* >& );
-		~NameMatcher();
-
-		void match( ResolvExpr::AltList &alternatives ) throw (NoMatch) ;
-		ResolvExpr::Alternative &get_next() throw (NoMoreElements);
-
-	  private:
-		int current;
-		std::vector< DeclarationWithType* > index;
-		std::vector< const ResolvExpr::Alternative * > exprs;
-		std::map< std::string, int> table;
-	};
-} // namespace Tuples
-
-#endif // _NAMEMATCHER_H_
-
-// Local Variables: //
-// tab-width: 4 //
-// mode: c++ //
-// compile-command: "make install" //
-// End: //
Index: src/Tuples/TupleAssignment.cc
===================================================================
--- src/Tuples/TupleAssignment.cc	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/Tuples/TupleAssignment.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// TupleAssignment.cc -- 
+// TupleAssignment.cc --
 //
 // Author           : Rodolfo G. Esteves
@@ -18,5 +18,6 @@
 #include "ResolvExpr/typeops.h"
 #include "SynTree/Expression.h"
-#include "TupleAssignment.h"
+#include "SynTree/Initializer.h"
+#include "Tuples.h"
 #include "Common/SemanticError.h"
 
@@ -27,383 +28,220 @@
 #include <cassert>
 #include <set>
+#include <unordered_set>
 
 namespace Tuples {
-	TupleAssignSpotter::TupleAssignSpotter( ResolvExpr::AlternativeFinder *f = 0 )
-		: currentFinder(f), matcher(0), hasMatched( false ) {}
-
-	bool TupleAssignSpotter::pointsToTuple( Expression *expr ) {
+	class TupleAssignSpotter {
+	  public:
+		// dispatcher for Tuple (multiple and mass) assignment operations
+		TupleAssignSpotter( ResolvExpr::AlternativeFinder & );
+		void spot( UntypedExpr * expr, std::list<ResolvExpr::AltList> &possibilities );
+
+	  private:
+		void match();
+		// records for assignment generation
+		struct Options {
+			void print( std::ostream & );
+			int size() const { return options.size(); }
+			bool empty() const { return options.empty(); }
+			typedef std::list< ResolvExpr::AltList >::iterator iterator;
+			iterator begin() { return options.begin(); }
+			iterator end() { return options.end(); }
+
+			std::list< ResolvExpr::AltList > options;
+		};
+
+		struct Matcher {
+		  public:
+			Matcher( TupleAssignSpotter &spotter, Expression *_lhs, Expression *_rhs );
+			virtual ~Matcher() {}
+			virtual void match( std::list< Expression * > &out ) = 0;
+			std::list< Expression * > lhs, rhs;
+			TupleAssignSpotter &spotter;
+			std::list< ObjectDecl * > tmpDecls;
+		};
+
+		struct MassAssignMatcher : public Matcher {
+		  public:
+			MassAssignMatcher( TupleAssignSpotter &spotter, Expression *lhs, Expression *rhs ) : Matcher( spotter, lhs, rhs ) {
+				this->rhs.push_back( rhs );
+			}
+			virtual void match( std::list< Expression * > &out );
+		};
+
+		struct MultipleAssignMatcher : public Matcher {
+		  public:
+			MultipleAssignMatcher( TupleAssignSpotter &spot, Expression *lhs, Expression *rhs );
+			virtual void match( std::list< Expression * > &out );
+		};
+
+		ResolvExpr::AlternativeFinder &currentFinder;
+		// Expression *rhs, *lhs;
+		Matcher *matcher = nullptr;
+		Options options;
+	};
+
+	bool isTupleVar( DeclarationWithType *decl ) {
+		return dynamic_cast< TupleType * >( decl->get_type() );
+	}
+
+	/// true if expr is an expression of tuple type, i.e. a tuple expression, tuple variable, or MRV (multiple-return-value) function
+	bool isTuple( Expression *expr ) {
+		if ( ! expr ) return false;
+
+		// xxx - used to include cast to varExpr and call to isTupleVar, but this doesn't seem like it should be necessary
+		return dynamic_cast<TupleExpr *>(expr) || expr->get_results().size() > 1;
+	}
+
+	bool pointsToTuple( Expression *expr ) {
 		// also check for function returning tuple of reference types
-		if (AddressExpr *addr = dynamic_cast<AddressExpr *>(expr) )
-			if ( isTuple(addr->get_arg() ) )
-				return true;
+		if ( AddressExpr *addr = dynamic_cast< AddressExpr * >( expr) ) {
+			return isTuple( addr->get_arg() );
+		}
 		return false;
 	}
 
-	bool TupleAssignSpotter::isTupleVar( DeclarationWithType *decl ) {
-		if ( dynamic_cast<TupleType *>(decl->get_type()) )
-			return true;
-		return false;
-	}
-
-	bool TupleAssignSpotter::isTuple( Expression *expr, bool isRight ) {
-		// true if `expr' is an expression returning a tuple: tuple, tuple variable or MRV function
-		if ( ! expr ) return false;
-
-		if ( dynamic_cast<TupleExpr *>(expr) )
-			return true;
-		else if ( VariableExpr *var = dynamic_cast<VariableExpr *>(expr) ) {
-			if ( isTupleVar(var->get_var()) )
-				return true;
-		}
-
-		return false;
-	}
-
-	bool TupleAssignSpotter::match() {
-		assert ( matcher != 0 );
-
-		std::list< Expression * > new_assigns;
-		if ( ! matcher->match(new_assigns) )
-			return false;
-
-		if ( new_assigns.empty() ) return false;
-		/*return */matcher->solve( new_assigns );
-		if ( dynamic_cast<TupleAssignSpotter::MultipleAssignMatcher *>( matcher ) ) {
-			// now resolve new assignments
-			std::list< Expression * > solved_assigns;
-			ResolvExpr::AltList solved_alts;
-			assert( currentFinder != 0 );
-
-			ResolvExpr::AltList current;
-			for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i ) {
-				//try {
-				ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() );
-				finder.findWithAdjustment(*i);
-				// prune expressions that don't coincide with
-				ResolvExpr::AltList alts = finder.get_alternatives();
-				assert( alts.size() == 1 );
-				assert(alts.front().expr != 0 );
-				current.push_back( finder.get_alternatives().front() );
-				solved_assigns.push_back( alts.front().expr->clone() );
-				//solved_assigns.back()->print(std::cerr);
-				/*} catch( ... ) {
-				  continue; // no reasonable alternative found
-				  }*/
-			}
-			options.add_option( current );
-
-			return true;
-		} else { // mass assignment
-			//if ( new_assigns.empty() ) return false;
-			std::list< Expression * > solved_assigns;
-			ResolvExpr::AltList solved_alts;
-			assert( currentFinder != 0 );
-
-			ResolvExpr::AltList current;
-			if ( optMass.empty() ) {
-				for ( std::list< Expression * >::size_type i = 0; i != new_assigns.size(); ++i )
-					optMass.push_back( ResolvExpr::AltList() );
-			}
-			int cnt = 0;
-			for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i, cnt++ ) {
-
-				ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() );
-				finder.findWithAdjustment(*i);
-				ResolvExpr::AltList alts = finder.get_alternatives();
-				assert( alts.size() == 1 );
-				assert(alts.front().expr != 0 );
-				current.push_back( finder.get_alternatives().front() );
-				optMass[cnt].push_back( finder.get_alternatives().front() );
-				solved_assigns.push_back( alts.front().expr->clone() );
-			}
-
-			return true;
-		}
-
-		return false;
-	}
-
-	bool TupleAssignSpotter::isMVR( Expression *expr ) {
-		if ( expr->get_results().size() > 1 ) {
-			// MVR processing
-			return true;
-		}
-		return false;
-	}
-
-	bool TupleAssignSpotter::isTupleAssignment( UntypedExpr * expr, std::list<ResolvExpr::AltList> &possibilities ) {
+	bool isTupleExpr( Expression *expr ) {
+		return expr->get_results().size() > 1;
+	}
+
+	void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * expr, std::list<ResolvExpr::AltList> &possibilities ) {
+		TupleAssignSpotter spotter( currentFinder );
+		spotter.spot( expr, possibilities );
+	}
+
+	TupleAssignSpotter::TupleAssignSpotter( ResolvExpr::AlternativeFinder &f )
+		: currentFinder(f) {}
+
+	void TupleAssignSpotter::spot( UntypedExpr * expr, std::list<ResolvExpr::AltList> &possibilities ) {
 		if (  NameExpr *assgnop = dynamic_cast< NameExpr * >(expr->get_function()) ) {
-
 			if ( assgnop->get_name() == std::string("?=?") ) {
-
 				for ( std::list<ResolvExpr::AltList>::iterator ali = possibilities.begin(); ali != possibilities.end(); ++ali ) {
 					assert( ali->size() == 2 );
-					ResolvExpr::AltList::iterator opit = ali->begin();
-					ResolvExpr::Alternative op1 = *opit, op2 = *(++opit);
-
+					ResolvExpr::Alternative op1 = ali->front(), op2 = ali->back();
+
+					MultipleAssignMatcher multiMatcher( *this, op1.expr, op2.expr );
+					MassAssignMatcher massMatcher( *this, op1.expr, op2.expr );
 					if ( pointsToTuple(op1.expr) ) { // also handles tuple vars
-						if ( isTuple( op2.expr, true ) )
-							matcher = new MultipleAssignMatcher(op1.expr, op2.expr);
-						else if ( isMVR( op2.expr ) ) {
-							// handle MVR differently
-						} else
+						if ( isTuple( op2.expr ) ) {
+							matcher = &multiMatcher;
+						} else {
 							// mass assignment
-							matcher = new MassAssignMatcher(op1.expr, op2.expr);
-
-						std::list< ResolvExpr::AltList > options;
-						if ( match() )
-							/*
-							  if ( hasMatched ) {
-							  // throw SemanticError("Ambiguous tuple assignment");
-							  } else {*/
-							// Matched for the first time
-							hasMatched = true;
-						/*} */
-					} /* else if ( isTuple( op2 ) )
-						 throw SemanticError("Inapplicable tuple assignment.");
-					  */
-				}
-
-				if ( hasMatched ) {
-					if ( dynamic_cast<TupleAssignSpotter::MultipleAssignMatcher *>( matcher ) ) {
-						//options.print( std::cerr );
-						std::list< ResolvExpr::AltList >best = options.get_best();
-						if ( best.size() == 1 ) {
-							std::list<Expression *> solved_assigns;
-							for ( ResolvExpr::AltList::iterator i = best.front().begin(); i != best.front().end(); ++i ) {
-								solved_assigns.push_back( i->expr );
-							}
-							/* assigning cost zero? */
-							currentFinder->get_alternatives().push_front( ResolvExpr::Alternative(new SolvedTupleExpr(solved_assigns/*, SolvedTupleExpr::MULTIPLE*/), currentFinder->get_environ(), ResolvExpr::Cost() ) );
+							matcher = &massMatcher;
 						}
-					} else {
-						assert( ! optMass.empty() );
-						ResolvExpr::AltList winners;
-						for ( std::vector< ResolvExpr::AltList >::iterator i = optMass.begin(); i != optMass.end(); ++i )
-							findMinCostAlt( i->begin(), i->end(), back_inserter(winners) );
-
-						std::list< Expression *> solved_assigns;
-						for ( ResolvExpr::AltList::iterator i = winners.begin(); i != winners.end(); ++i )
-							solved_assigns.push_back( i->expr );
-						currentFinder->get_alternatives().push_front( ResolvExpr::Alternative(new SolvedTupleExpr(solved_assigns/*, SolvedTupleExpr::MASS*/), currentFinder->get_environ(), ResolvExpr::Cost() ) );
+						match();
+					} else if ( isTuple( op2.expr ) ) {
+						throw SemanticError("Cannot assign a tuple value into a non-tuple lvalue.", expr);
 					}
 				}
 			}
 		}
-		return hasMatched;
-	}
-
-	void TupleAssignSpotter::Matcher::init( Expression *_lhs, Expression *_rhs ) {
-		lhs.clear();
-		if (AddressExpr *addr = dynamic_cast<AddressExpr *>(_lhs) )
+	}
+
+	void TupleAssignSpotter::match() {
+		assert ( matcher != 0 );
+
+		std::list< Expression * > new_assigns;
+		matcher->match( new_assigns );
+
+		if ( new_assigns.empty() ) return;
+		ResolvExpr::AltList current;
+		// now resolve new assignments
+		for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i ) {
+			ResolvExpr::AlternativeFinder finder( currentFinder.get_indexer(), currentFinder.get_environ() );
+			finder.findWithAdjustment(*i);
+			// prune expressions that don't coincide with
+			ResolvExpr::AltList alts = finder.get_alternatives();
+			assert( alts.size() == 1 );
+			assert( alts.front().expr != 0 );
+			current.push_back( alts.front() );
+		}
+
+		// extract expressions from the assignment alternatives to produce a list of assignments that
+		// together form a single alternative
+		std::list< Expression *> solved_assigns;
+		for ( ResolvExpr::Alternative & alt : current ) {
+			solved_assigns.push_back( alt.expr->clone() );
+		}
+		// xxx - need to do this??
+		// TypeEnvironment compositeEnv;
+		// simpleCombineEnvironments( i->begin(), i->end(), compositeEnv );
+		currentFinder.get_alternatives().push_front( ResolvExpr::Alternative(new TupleAssignExpr(solved_assigns, matcher->tmpDecls), currentFinder.get_environ(), ResolvExpr::sumCost( current ) ) );
+	}
+
+	TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter, Expression *lhs, Expression *rhs ) : spotter(spotter) {
+		// xxx - shouldn't need to be &<tuple-expr>, just &<lvalue-tuple-type>
+		if (AddressExpr *addr = dynamic_cast<AddressExpr *>(lhs) )
 			if ( TupleExpr *tuple = dynamic_cast<TupleExpr *>(addr->get_arg()) )
-				std::copy( tuple->get_exprs().begin(), tuple->get_exprs().end(), back_inserter(lhs) );
-
-		rhs.clear();
-	}
-
-	TupleAssignSpotter::Matcher::Matcher( /*TupleAssignSpotter &spot,*/ Expression *_lhs, Expression *_rhs ) /*: own_spotter(spot) */{
-		init(_lhs,_rhs);
-	}
-
-	TupleAssignSpotter::MultipleAssignMatcher::MultipleAssignMatcher( Expression *_lhs, Expression *_rhs )/* : own_spotter(spot) */{
-		init(_lhs,_rhs);
-
-		if ( TupleExpr *tuple = dynamic_cast<TupleExpr *>(_rhs) )
-			std::copy( tuple->get_exprs().begin(), tuple->get_exprs().end(), back_inserter(rhs) );
-	}
-
-	UntypedExpr *TupleAssignSpotter::Matcher::createAssgn( Expression *left, Expression *right ) {
-		if ( left && right ) {
-			std::list< Expression * > args;
-			args.push_back(new AddressExpr(left->clone()));  args.push_back(right->clone());
-			return new UntypedExpr(new NameExpr("?=?"), args);
-		} else
-			throw 0; // xxx - diagnose the problem
-	}
-
-	bool TupleAssignSpotter::MassAssignMatcher::match( std::list< Expression * > &out ) {
-		if ( lhs.empty() || (rhs.size() != 1) ) return false;
-
-		for ( std::list< Expression * >::iterator l = lhs.begin(); l != lhs.end(); l++ ) {
-			std::list< Expression * > args;
-			args.push_back( new AddressExpr(*l) );
-			args.push_back( rhs.front() );
-			out.push_back( new UntypedExpr(new NameExpr("?=?"), args) );
-		}
-
-		return true;
-	}
-
-	bool TupleAssignSpotter::MassAssignMatcher::solve( std::list< Expression * > &assigns ) {
-		/*
-		  std::list< Expression * > solved_assigns;
-		  ResolvExpr::AltList solved_alts;
-		  assert( currentFinder != 0 );
-
-		  ResolvExpr::AltList current;
-		  if ( optMass.empty() ) {
-		  for ( std::list< Expression * >::size_type i = 0; i != new_assigns.size(); ++i )
-		  optMass.push_back( ResolvExpr::AltList() );
-		  }
-		  int cnt = 0;
-		  for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i, cnt++ ) {
-
-		  ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() );
-		  finder.findWithAdjustment(*i);
-		  ResolvExpr::AltList alts = finder.get_alternatives();
-		  assert( alts.size() == 1 );
-		  assert(alts.front().expr != 0 );
-		  current.push_back( finder.get_alternatives().front() );
-		  optMass[cnt].push_back( finder.get_alternatives().front() );
-		  solved_assigns.push_back( alts.front().expr->clone() );
-		  }
-		*/
-		return true;
-	}
-
-	bool TupleAssignSpotter::MultipleAssignMatcher::match( std::list< Expression * > &out ) {
-		// need more complicated matching
+				std::copy( tuple->get_exprs().begin(), tuple->get_exprs().end(), back_inserter(this->lhs) );
+	}
+
+	TupleAssignSpotter::MultipleAssignMatcher::MultipleAssignMatcher( TupleAssignSpotter &spotter, Expression *lhs, Expression *rhs ) : Matcher( spotter, lhs, rhs ) {
+
+		if ( TupleExpr *tuple = dynamic_cast<TupleExpr *>(rhs) )
+			std::copy( tuple->get_exprs().begin(), tuple->get_exprs().end(), back_inserter(this->rhs) );
+	}
+
+	UntypedExpr * createAssgn( ObjectDecl *left, ObjectDecl *right ) {
+		assert( left && right );
+		std::list< Expression * > args;
+		args.push_back( new AddressExpr( new UntypedExpr( new NameExpr("*?"), std::list< Expression * >{ new VariableExpr( left ) } ) ) );
+		args.push_back( new VariableExpr( right ) );
+		return new UntypedExpr( new NameExpr( "?=?" ), args );
+	}
+
+	ObjectDecl * newObject( UniqueName & namer, Expression * expr ) {
+		Type * type;
+		assert( expr->get_results().size() >= 1 );
+		if ( expr->get_results().size() > 1 ) {
+			TupleType * tt = new TupleType( Type::Qualifiers() );
+			cloneAll( expr->get_results(), tt->get_types() );
+			type = tt;
+		} else {
+			type = expr->get_results().front()->clone();
+		}
+		return new ObjectDecl( namer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, type, new SingleInit( expr->clone() ) );
+	}
+
+	void TupleAssignSpotter::MassAssignMatcher::match( std::list< Expression * > &out ) {
+		static UniqueName lhsNamer( "__massassign_L" );
+		static UniqueName rhsNamer( "__massassign_R" );
+		assert ( ! lhs.empty() && rhs.size() == 1);
+
+		ObjectDecl * rtmp = newObject( rhsNamer, rhs.front() );
+		for ( Expression * l : lhs ) {
+			ObjectDecl * ltmp = newObject( lhsNamer, new AddressExpr( l ) );
+			out.push_back( createAssgn( ltmp, rtmp ) );
+			tmpDecls.push_back( ltmp );
+		}
+		tmpDecls.push_back( rtmp );
+	}
+
+	void TupleAssignSpotter::MultipleAssignMatcher::match( std::list< Expression * > &out ) {
+		static UniqueName lhsNamer( "__multassign_L" );
+		static UniqueName rhsNamer( "__multassign_R" );
+		// xxx - need more complicated matching?
 		if ( lhs.size() == rhs.size() ) {
-			zipWith( lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), back_inserter(out), TupleAssignSpotter::Matcher::createAssgn );
-			return true;
-		} //else
-		//std::cerr << "The length of (left, right) is: (" << lhs.size() << "," << rhs.size() << ")" << std::endl;*/
-		return false;
-	}
-
-	bool TupleAssignSpotter::MultipleAssignMatcher::solve( std::list< Expression * > &assigns ) {
-		/*
-		  std::list< Expression * > solved_assigns;
-		  ResolvExpr::AltList solved_alts;
-		  assert( currentFinder != 0 );
-
-		  ResolvExpr::AltList current;
-		  for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i ) {
-		  //try {
-		  ResolvExpr::AlternativeFinder finder( currentFinder->get_indexer(), currentFinder->get_environ() );
-		  finder.findWithAdjustment(*i);
-		  // prune expressions that don't coincide with
-		  ResolvExpr::AltList alts = finder.get_alternatives();
-		  assert( alts.size() == 1 );
-		  assert(alts.front().expr != 0 );
-		  current.push_back( finder.get_alternatives().front() );
-		  solved_assigns.push_back( alts.front().expr->clone() );
-		  //solved_assigns.back()->print(std::cerr);
-		  //} catch( ... ) {
-		  //continue; // no reasonable alternative found
-		  //}
-		  }
-		  options.add_option( current );
-		*/
-
-		return true;
-	}
-
-	void TupleAssignSpotter::Options::add_option( ResolvExpr::AltList &opt ) {
-		using namespace std;
-
-		options.push_back( opt );
-		/*
-		  vector< Cost > costs;
-		  costs.reserve( opt.size() );
-		  transform( opt.begin(), opt.end(), back_inserter(costs), ptr_fun(extract_cost) );
-		*/
-		// transpose matrix
-		if ( costMatrix.empty() )
-			for ( unsigned int i = 0; i< opt.size(); ++i)
-				costMatrix.push_back( vector<ResolvExpr::Cost>() );
-
-		int cnt = 0;
-		for ( ResolvExpr::AltList::iterator i = opt.begin(); i != opt.end(); ++i, cnt++ )
-			costMatrix[cnt].push_back( i->cost );
-
-		return;
-	}
-
-	std::list< ResolvExpr::AltList > TupleAssignSpotter::Options::get_best() {
-		using namespace std;
-		using namespace ResolvExpr;
-		list< ResolvExpr::AltList > ret;
-		list< multiset<int> > solns;
-		for ( vector< vector<Cost> >::iterator i = costMatrix.begin(); i != costMatrix.end(); ++i ) {
-			list<int> current;
-			findMinCost( i->begin(), i->end(), back_inserter(current) );
-			solns.push_back( multiset<int>(current.begin(), current.end()) );
-		}
-		// need to combine
-		multiset<int> result;
-		lift_intersection( solns.begin(), solns.end(), inserter( result, result.begin() ) );
-		if ( result.size() != 1 )
-			throw SemanticError("Ambiguous tuple expression");
-		ret.push_back(get_option( *(result.begin() )));
-		return ret;
+			std::list< ObjectDecl * > ltmp;
+			std::list< ObjectDecl * > rtmp;
+			std::transform( lhs.begin(), lhs.end(), back_inserter( ltmp ), []( Expression * expr ){
+				return newObject( lhsNamer, new AddressExpr( expr ) );
+			});
+			std::transform( rhs.begin(), rhs.end(), back_inserter( rtmp ), []( Expression * expr ){
+				return newObject( rhsNamer, expr );
+			});
+			zipWith( ltmp.begin(), ltmp.end(), rtmp.begin(), rtmp.end(), back_inserter(out), createAssgn );
+			tmpDecls.splice( tmpDecls.end(), ltmp );
+			tmpDecls.splice( tmpDecls.end(), rtmp );
+		}
 	}
 
 	void TupleAssignSpotter::Options::print( std::ostream &ostr ) {
-		using namespace std;
-
-		for ( vector< vector < ResolvExpr::Cost > >::iterator i = costMatrix.begin(); i != costMatrix.end(); ++i ) {
-			for ( vector < ResolvExpr::Cost >::iterator j = i->begin(); j != i->end(); ++j )
-				ostr << *j << " " ;
+		for ( ResolvExpr::AltList & l : options ) {
+			for ( ResolvExpr::Alternative & alt : l ) {
+				alt.print( ostr );
+				ostr << " ";
+			}
 			ostr << std::endl;
 		} // for
-		return;
-	}
-
-	ResolvExpr::Cost extract_cost( ResolvExpr::Alternative &alt ) {
-		return alt.cost;
-	}
-
-	template< typename InputIterator, typename OutputIterator >
-	void TupleAssignSpotter::Options::findMinCost( InputIterator begin, InputIterator end, OutputIterator out ) {
-		using namespace ResolvExpr;
-		std::list<int> alternatives;
-
-		// select the alternatives that have the minimum parameter cost
-		Cost minCost = Cost::infinity;
-		unsigned int index = 0;
-		for ( InputIterator i = begin; i != end; ++i, index++ ) {
-			if ( *i < minCost ) {
-				minCost = *i;
-				alternatives.clear();
-				alternatives.push_back( index );
-			} else if ( *i == minCost ) {
-				alternatives.push_back( index );
-			}
-		}
-		std::copy( alternatives.begin(), alternatives.end(), out );
-	}
-
-	template< class InputIterator, class OutputIterator >
-	void TupleAssignSpotter::Options::lift_intersection( InputIterator begin, InputIterator end, OutputIterator out ) {
-		if ( begin == end ) return;
-		InputIterator test = begin;
-
-		if (++test == end)
-			{ copy(begin->begin(), begin->end(), out); return; }
-
-
-		std::multiset<int> cur; // InputIterator::value_type::value_type
-		copy( begin->begin(), begin->end(), inserter( cur, cur.begin() ) );
-
-		while ( test != end ) {
-			std::multiset<int> temp;
-			set_intersection( cur.begin(), cur.end(), test->begin(), test->end(), inserter(temp,temp.begin()) );
-			cur.clear();
-			copy( temp.begin(), temp.end(), inserter(cur,cur.begin()));
-			++test;
-		}
-
-		copy( cur.begin(), cur.end(), out );
-		return;
-	}
-
-	ResolvExpr::AltList TupleAssignSpotter::Options::get_option( std::list< ResolvExpr::AltList >::size_type index ) {
-		if ( index >= options.size() )
-			throw 0; // XXX
-		std::list< ResolvExpr::AltList >::iterator it = options.begin();
-		for ( std::list< ResolvExpr::AltList >::size_type i = 0; i < index; ++i, ++it );
-		return *it;
 	}
 } // namespace Tuples
Index: src/Tuples/TupleAssignment.h
===================================================================
--- src/Tuples/TupleAssignment.h	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ 	(revision )
@@ -1,136 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// TupleAssignment.h -- 
-//
-// Author           : Rodolfo G. Esteves
-// Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Mon May 18 15:04:02 2015
-// Update Count     : 2
-//
-
-#ifndef _TUPLE_ASSIGNMENT_H_
-#define _TUPLE_ASSIGNMENT_H_
-
-#include <string>
-#include <vector>
-#include "ResolvExpr/AlternativeFinder.h"
-
-#include "SynTree/Expression.h"
-#include "SynTree/Declaration.h"
-#include "SynTree/Type.h"
-
-namespace Tuples {
-	class TupleAssignSpotter {
-	  public:
-		// dispatcher for Tuple (multiple and mass) assignment operations
-		TupleAssignSpotter( ResolvExpr::AlternativeFinder * );
-		~TupleAssignSpotter() { delete matcher; matcher = 0; }
-
-		bool pointsToTuple( Expression * );
-		static bool isTupleVar( DeclarationWithType * );
-		bool isTuple( Expression *, bool isRight = false );
-		bool isMVR( Expression * );
-		bool isTupleAssignment( UntypedExpr *, std::list<ResolvExpr::AltList> & );
-		bool match();
-	  private:
-		// records for assignment generation
-		class Options {
-		  public:
-			void add_option( ResolvExpr::AltList &opt );
-			std::list< ResolvExpr::AltList > get_best();
-			void print( std::ostream & );
-			int size() const { return options.size(); }
-			ResolvExpr::AltList get_option( std::list< ResolvExpr::AltList >::size_type index );
-
-			// should really use the one in ResolvExpr/AlternativeFinder, but it's too coupled with the object
-			template< typename InputIterator, typename OutputIterator >
-			void findMinCost( InputIterator begin, InputIterator end, OutputIterator out );
-
-			template< typename InputIterator, typename OutputIterator >
-			void lift_intersection( InputIterator begin, InputIterator end, OutputIterator out );
-		  private:
-			std::list< ResolvExpr::AltList > options;
-			std::vector< std::vector< ResolvExpr::Cost > > costMatrix;
-		};
-
-		class Matcher {
-		  public:
-			Matcher( /*TupleAssignSpotter &spot, */Expression *_lhs, Expression *_rhs );
-			virtual ~Matcher() {}
-			virtual bool match( std::list< Expression * > &out ) = 0;
-			virtual bool solve( std::list< Expression * > &assigns ) = 0;
-			static UntypedExpr *createAssgn( Expression *left, Expression *right );
-		  protected:
-			Matcher() /*: own_spotter( TupleAssignSpotter(0) ) */{}
-			void init(/* TupleAssignSpotter &, */Expression *_lhs, Expression *_rhs );
-			std::list< Expression * > lhs, rhs;
-			//TupleAssignSpotter &own_spotter;
-		};
-
-		class MassAssignMatcher : public Matcher {
-		  public:
-			MassAssignMatcher( Expression *_lhs, Expression *_rhs ) : Matcher( _lhs, _rhs ) {
-				rhs.push_back( _rhs );
-			}
-			virtual bool match( std::list< Expression * > &out );
-			virtual bool solve( std::list< Expression * > &assigns );
-		  private:
-			//std::vector< ResolvExpr::AltList > optMass;
-		};
-
-		class MultipleAssignMatcher : public Matcher {
-		  public:
-			MultipleAssignMatcher( Expression *_lhs, Expression *_rhs );
-			virtual bool match( std::list< Expression * > &out );
-			virtual bool solve( std::list< Expression * > &assigns );
-		  private:
-			//Options options;
-		};
-
-		friend class Matcher;
-
-		ResolvExpr::AlternativeFinder *currentFinder;
-		//std::list<Expression *> rhs, lhs;
-		Expression *rhs, *lhs;
-		Matcher *matcher;
-		bool hasMatched;
-		Options options;
-		std::vector< ResolvExpr::AltList > optMass;
-	};
-
-	ResolvExpr::Cost extract_cost( ResolvExpr::Alternative & );
-
-	template< typename InputIterator, typename OutputIterator >
-	void findMinCostAlt( InputIterator begin, InputIterator end, OutputIterator out ) {
-		using namespace ResolvExpr;
-		AltList alternatives;
-
-		// select the alternatives that have the minimum parameter cost
-		Cost minCost = Cost::infinity;
-		for ( AltList::iterator i = begin; i != end; ++i ) {
-			if ( i->cost < minCost ) {
-				minCost = i->cost;
-				i->cost = i->cvtCost;
-				alternatives.clear();
-				alternatives.push_back( *i );
-			} else if ( i->cost == minCost ) {
-				i->cost = i->cvtCost;
-				alternatives.push_back( *i );
-			}
-		}
-		std::copy( alternatives.begin(), alternatives.end(), out );
-	}
-} // namespace Tuples
-
-#endif // _TUPLE_ASSIGNMENT_H_
-
-// Local Variables: //
-// tab-width: 4 //
-// mode: c++ //
-// compile-command: "make install" //
-// End: //
Index: src/Tuples/TupleExpansion.cc
===================================================================
--- src/Tuples/TupleExpansion.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/Tuples/TupleExpansion.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -0,0 +1,98 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// TupleAssignment.cc --
+//
+// Author           : Rodolfo G. Esteves
+// Created On       : Mon May 18 07:44:20 2015
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon May 18 15:02:53 2015
+// Update Count     : 2
+//
+
+#include <iterator>
+#include <iostream>
+#include <cassert>
+#include "Tuples.h"
+#include "GenPoly/DeclMutator.h"
+#include "SynTree/Mutator.h"
+#include "SynTree/Statement.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Type.h"
+#include "SymTab/Mangler.h"
+#include "Common/ScopedMap.h"
+
+namespace Tuples {
+	class TupleAssignExpander : public Mutator {
+	public:
+		virtual Expression * mutate( TupleAssignExpr * tupleExpr );
+	};
+
+	class TupleTypeReplacer : public GenPoly::DeclMutator {
+	  public:
+		typedef GenPoly::DeclMutator Parent;
+
+		virtual Type * mutate( TupleType * tupleType );
+
+		virtual CompoundStmt * mutate( CompoundStmt * stmt ) {
+			typeMap.beginScope();
+			stmt = Parent::mutate( stmt );
+			typeMap.endScope();
+			return stmt;
+		}
+	  private:
+		ScopedMap< std::string, StructDecl * > typeMap;
+	};
+
+	void expandTuples( std::list< Declaration * > & translationUnit ) {
+		TupleAssignExpander expander;
+		mutateAll( translationUnit, expander );
+
+		TupleTypeReplacer replacer;
+		replacer.mutateDeclarationList( translationUnit );
+	}
+
+	Expression * TupleAssignExpander::mutate( TupleAssignExpr * tupleExpr ) {
+		CompoundStmt * compoundStmt = new CompoundStmt( noLabels );
+		std::list< Statement * > & stmts = compoundStmt->get_kids();
+		for ( ObjectDecl * obj : tupleExpr->get_tempDecls() ) {
+			stmts.push_back( new DeclStmt( noLabels, obj ) );
+		}
+		for ( Expression * assign : tupleExpr->get_assigns() ) {
+			stmts.push_back( new ExprStmt( noLabels, assign ) );
+		}
+		tupleExpr->get_tempDecls().clear();
+		tupleExpr->get_assigns().clear();
+		delete tupleExpr;
+		return new StmtExpr( compoundStmt );
+	}
+
+	Type * TupleTypeReplacer::mutate( TupleType * tupleType ) {
+		std::string mangleName = SymTab::Mangler::mangleType( tupleType );
+		TupleType * newType = safe_dynamic_cast< TupleType * > ( Parent::mutate( tupleType ) );
+		if ( ! typeMap.count( mangleName ) ) {
+			// generate struct type to replace tuple type
+			StructDecl * decl = new StructDecl( "_tuple_type_" + mangleName );
+			decl->set_body( true );
+			int cnt = 0;
+			for ( Type * t : *newType ) {
+				decl->get_members().push_back( new ObjectDecl( "field_"+std::to_string(++cnt), DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, t->clone(), nullptr ) );
+			}
+			typeMap[mangleName] = decl;
+			addDeclaration( decl );
+		}
+		delete newType;
+		return new StructInstType( newType->get_qualifiers(), typeMap[mangleName] );
+	}
+
+} // namespace Tuples
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
+
Index: src/Tuples/Tuples.h
===================================================================
--- src/Tuples/Tuples.h	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
+++ src/Tuples/Tuples.h	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -0,0 +1,41 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// Tuples.h --
+//
+// Author           : Rodolfo G. Esteves
+// Created On       : Mon May 18 07:44:20 2015
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon May 18 15:04:02 2015
+// Update Count     : 2
+//
+
+#ifndef _TUPLES_H_
+#define _TUPLE_H_
+
+#include <string>
+#include <vector>
+#include "ResolvExpr/AlternativeFinder.h"
+
+#include "SynTree/Expression.h"
+#include "SynTree/Declaration.h"
+#include "SynTree/Type.h"
+
+namespace Tuples {
+	// TupleAssignment.cc
+	void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * assign, std::list<ResolvExpr::AltList> & possibilities );
+
+	// TupleExpansion.cc
+	void expandTuples( std::list< Declaration * > & translationUnit );
+} // namespace Tuples
+
+#endif // _TUPLE_ASSIGNMENT_H_
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/Tuples/module.mk
===================================================================
--- src/Tuples/module.mk	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/Tuples/module.mk	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -6,5 +6,5 @@
 ## file "LICENCE" distributed with Cforall.
 ##
-## module.mk -- 
+## module.mk --
 ##
 ## Author           : Richard C. Bilson
@@ -16,3 +16,3 @@
 
 SRC += 	Tuples/TupleAssignment.cc \
-	Tuples/NameMatcher.cc
+	Tuples/TupleExpansion.cc
Index: src/main.cc
===================================================================
--- src/main.cc	(revision 1eba45207b5f4260dca6a87522e61f09a0d8f014)
+++ src/main.cc	(revision fd782b2be4d8d0e2485b8b387f34d18a1f6b3b52)
@@ -42,4 +42,5 @@
 #include "Common/UnimplementedError.h"
 #include "../config.h"
+#include "Tuples/Tuples.h"
 
 using namespace std;
@@ -265,4 +266,6 @@
 		OPTPRINT( "convertLvalue" )
 		GenPoly::convertLvalue( translationUnit );
+		OPTPRINT( "expandTuples" ); // xxx - is this the right place for this?
+		Tuples::expandTuples( translationUnit );
 
 		if ( bboxp ) {
