- parsing support for composite literals

R=r
OCL=13394
CL=13394
diff --git a/usr/gri/gosrc/parser.go b/usr/gri/gosrc/parser.go
index c40b70b..302db22 100644
--- a/usr/gri/gosrc/parser.go
+++ b/usr/gri/gosrc/parser.go
@@ -474,6 +474,7 @@
 	P.TryResult();
 	P.CloseScope();
 	
+	P.Ecart();
 	return name, MakeFunctionType(sig, p0, r0, true);
 }
 
@@ -684,12 +685,82 @@
 }
 
 
+func (P *Parser) ParseExpressionPair() {
+	P.Trace("ExpressionPair");
+
+	P.ParseExpression();
+	P.Expect(Scanner.COLON);
+	P.ParseExpression();
+	
+	P.Ecart();
+}
+
+
+func (P *Parser) ParseExpressionPairList() {
+	P.Trace("ExpressionPairList");
+
+	P.ParseExpressionPair();
+	for (P.tok == Scanner.COMMA) {
+		P.ParseExpressionPair();
+	}
+	
+	P.Ecart();
+}
+
+
+func (P *Parser) ParseCompositeLit(typ *Globals.Type) {
+	P.Trace("CompositeLit");
+	
+	// TODO I think we should use {} instead of () for
+	// composite literals to syntactically distinguish
+	// them from conversions. For now: allow both.
+	var paren int;
+	if P.tok == Scanner.LPAREN {
+		P.Next();
+		paren = Scanner.RPAREN;
+	} else {
+		P.Expect(Scanner.LBRACE);
+		paren = Scanner.RBRACE;
+	}
+	
+	// TODO: should allow trailing ','
+	if P.tok != paren {
+		P.ParseExpression();
+		if P.tok == Scanner.COMMA {
+			P.Next();
+			if P.tok != paren {
+				P.ParseExpressionList();
+			}
+		} else if P.tok == Scanner.COLON {
+			P.Next();
+			P.ParseExpression();
+			if P.tok == Scanner.COMMA {
+				P.Next();
+				if P.tok != paren {
+					P.ParseExpressionPairList();
+				}
+			}
+		}
+	}
+
+	P.Expect(paren);
+
+	P.Ecart();
+}
+
+
 func (P *Parser) ParseOperand() {
 	P.Trace("Operand");
 	
 	switch P.tok {
 	case Scanner.IDENT:
 		P.ParseQualifiedIdent();
+		// TODO enable code below
+		/*
+		if obj.kind == Object.TYPE {
+			P.ParseCompositeLit(obj.typ);
+		}
+		*/
 	case Scanner.LPAREN:
 		P.Next();
 		P.ParseExpression();
@@ -706,8 +777,13 @@
 	case Scanner.NEW:
 		P.ParseNew();
 	default:
-		P.Error(P.pos, "operand expected");
-		P.Next();  // make progress
+		typ := P.TryType();
+		if typ != nil {
+			P.ParseCompositeLit(typ);
+		} else {
+			P.Error(P.pos, "operand expected");
+			P.Next();  // make progress
+		}
 	}
 	
 	P.Ecart();
@@ -863,7 +939,7 @@
 	P.ParseBinaryExpr(1);
 	
 	if indent != P.indent {
-		panic "imbalanced tracing code";
+		panic "imbalanced tracing code (Expression)";
 	}
 	P.Ecart();
 }
@@ -1194,7 +1270,7 @@
 	}
 
 	if indent != P.indent {
-		panic "imbalanced tracing code"
+		panic "imbalanced tracing code (Statement)"
 	}
 	P.Ecart();
 	return res;
@@ -1431,7 +1507,7 @@
 		P.Next();  // make progress
 	}
 	if indent != P.indent {
-		panic "imbalanced tracing code"
+		panic "imbalanced tracing code (Declaration)"
 	}
 	
 	P.Ecart();