- scanner returns now triple (tok, tok_pos, tok_val)
- initial try-out of AST data structures
- removed test_parser (not working anymore - parser needs more infrastructure)

SVN=128089
diff --git a/usr/gri/gosrc/parser.go b/usr/gri/gosrc/parser.go
index 6bf6ecd..28fdf39 100644
--- a/usr/gri/gosrc/parser.go
+++ b/usr/gri/gosrc/parser.go
@@ -9,6 +9,7 @@
 import Object "object"
 import Type "type"
 import Universe "universe"
+import AST "ast"
 
 
 // So I can submit and have a running parser for now...
@@ -20,9 +21,13 @@
 	comp *Globals.Compilation;
 	verbose, indent int;
 	S *Scanner.Scanner;
+	
+	// Token
 	tok int;  // one token look-ahead
-	beg, end int;  // token position
-	ident string;  // last ident seen
+	pos int;  // token source position
+	val string;  // token value (for IDENT, NUMBER, STRING only)
+
+	// Semantic analysis
 	top_scope *Globals.Scope;
 	exports *Globals.List;
 }
@@ -57,13 +62,10 @@
 
 
 func (P *Parser) Next() {
-	P.tok, P.beg, P.end = P.S.Scan();
-	if P.tok == Scanner.IDENT {
-		P.ident = P.S.src[P.beg : P.end];
-	}
+	P.tok, P.pos, P.val = P.S.Scan();
 	if P.verbose > 1 {
 		P.PrintIndent();
-		print "[", P.beg, "] ", Scanner.TokenName(P.tok), "\n";
+		print "[", P.pos, "] ", Scanner.TokenName(P.tok), "\n";
 	}
 }
 
@@ -86,7 +88,7 @@
 
 func (P *Parser) Expect(tok int) {
 	if P.tok != tok {
-		P.Error(P.beg, "expected '" + Scanner.TokenName(tok) + "', found '" + Scanner.TokenName(P.tok) + "'");
+		P.Error(P.pos, "expected '" + Scanner.TokenName(tok) + "', found '" + Scanner.TokenName(P.tok) + "'");
 	}
 	P.Next();  // make progress in any case
 }
@@ -157,7 +159,7 @@
 
 	ident := "";
 	if P.tok == Scanner.IDENT {
-		ident = P.ident;
+		ident = P.val;
 		if P.verbose > 0 {
 			P.PrintIndent();
 			print "Ident = \"", ident, "\"\n";
@@ -175,7 +177,7 @@
 func (P *Parser) ParseIdentDecl(kind int) *Globals.Object {
 	P.Trace("IdentDecl");
 	
-	pos := P.beg;
+	pos := P.pos;
 	obj := Globals.NewObject(pos, kind, P.ParseIdent());
 	P.Declare(obj);
 	
@@ -214,7 +216,7 @@
 	P.Trace("QualifiedIdent");
 
 	if EnableSemanticTests {
-		pos := P.beg;
+		pos := P.pos;
 		ident := P.ParseIdent();
 		obj := P.Lookup(ident);
 		if obj == nil {
@@ -250,7 +252,7 @@
 	
 	typ := P.TryType();
 	if typ == nil {
-		P.Error(P.beg, "type expected");
+		P.Error(P.pos, "type expected");
 		typ = Universe.bad_t;
 	}
 	
@@ -515,7 +517,7 @@
 func (P *Parser) ParseStatement() {
 	P.Trace("Statement");
 	if !P.TryStatement() {
-		P.Error(P.beg, "statement expected");
+		P.Error(P.pos, "statement expected");
 		P.Next();  // make progress
 	}
 	P.Ecart();
@@ -602,7 +604,7 @@
 	case Scanner.NEW:
 		P.ParseNew();
 	default:
-		P.Error(P.beg, "operand expected");
+		P.Error(P.pos, "operand expected");
 		P.Next();  // make progress
 	}
 	P.Ecart();
@@ -678,7 +680,7 @@
 }
 
 
-func (P *Parser) ParseUnaryExpr() {
+func (P *Parser) ParseUnaryExpr() *AST.Expr {
 	P.Trace("UnaryExpr");
 	switch P.tok {
 	case Scanner.ADD: fallthrough;
@@ -691,10 +693,11 @@
 		P.Next();
 		P.ParseUnaryExpr();
 		P.Ecart();
-		return;
+		return nil;  // TODO fix this
 	}
 	P.ParsePrimaryExpr();
 	P.Ecart();
+	return nil;  // TODO fix this
 }
 
 
@@ -718,15 +721,22 @@
 }
 
 
-func (P *Parser) ParseBinaryExpr(prec1 int) {
+func (P *Parser) ParseBinaryExpr(prec1 int) *AST.Expr {
 	P.Trace("BinaryExpr");
-	P.ParseUnaryExpr();
+	
+	x := P.ParseUnaryExpr();
 	for prec := Precedence(P.tok); prec >= prec1; prec-- {
 		for Precedence(P.tok) == prec {
+			e := new(AST.Expr);
+			e.typ = Universe.undef_t;  // TODO fix this
+			e.op = P.tok;  // TODO should we use tokens or separate operator constants?
+			e.x = x;
 			P.Next();
-			P.ParseBinaryExpr(prec + 1);
+			e.y = P.ParseBinaryExpr(prec + 1);
+			x = e;
 		}
 	}
+	
 	P.Ecart();
 }
 
@@ -1012,7 +1022,7 @@
 	case Scanner.RECV:
 		P.ParseSimpleStat();  // send or receive
 	case Scanner.IDENT:
-		switch P.ident {
+		switch P.val {
 		case "print", "panic":
 			P.ParseBuiltinStat();
 		default:
@@ -1127,7 +1137,7 @@
 func (P *Parser) ParseTypeSpec() {
 	P.Trace("TypeSpec");
 	
-	pos := P.beg;
+	pos := P.pos;
 	ident := P.ParseIdent();
 	obj := P.top_scope.Lookup(ident);  // only lookup in top scope!
 	if obj != nil {
@@ -1274,7 +1284,7 @@
 	case Scanner.EXPORT:
 		P.ParseExportDecl();
 	default:
-		P.Error(P.beg, "declaration expected");
+		P.Error(P.pos, "declaration expected");
 		P.Next();  // make progress
 	}
 	if indent != P.indent {