]> Cypherpunks repositories - gostls13.git/commitdiff
- use stringtorune library function for faster rune scanning
authorRobert Griesemer <gri@golang.org>
Mon, 20 Oct 2008 22:03:40 +0000 (15:03 -0700)
committerRobert Griesemer <gri@golang.org>
Mon, 20 Oct 2008 22:03:40 +0000 (15:03 -0700)
- converted 2 right-recursive parsing functions into iterative versions
- renamed node.go -> ast.go (clearer)

R=r
OCL=17496
CL=17498

usr/gri/pretty/Makefile
usr/gri/pretty/Makefile.iant
usr/gri/pretty/ast.go [moved from usr/gri/pretty/node.go with 98% similarity]
usr/gri/pretty/parser.go
usr/gri/pretty/printer.go
usr/gri/pretty/scanner.go

index 24b00bb2309e0ee5e1db84e8990fef449af9d18b..e6153b4a439b41ad2790c1c247ec8cd7f1e5542a 100644 (file)
@@ -19,11 +19,11 @@ clean:
 
 pretty.6:      parser.6 printer.6 platform.6 scanner.6
 
-printer.6:     node.6 scanner.6
+printer.6:     ast.6 scanner.6
 
-parser.6:      scanner.6 utils.6 printer.6 node.6
+parser.6:      scanner.6 utils.6 printer.6 ast.6
 
-node.6:        scanner.6
+ast.6: scanner.6
 
 scanner.6:     utils.6 platform.6
 
index e80b2585eff2bd1ff0c03f3cd0b574ec2fed739c..d91c47a4b8f7825d3d0e0715393b79c5fa1f9e86 100644 (file)
@@ -9,7 +9,7 @@ GO = /home/iant/go/bin/gccgo
 LDFLAGS = -Wl,-R,/home/iant/go/lib
 
 PRETTY_OBJS = \
-       node.o \
+       ast.o \
        pretty.o \
        parser.o \
        platform.o \
@@ -33,11 +33,11 @@ clean:
 
 pretty.o:      parser.o printer.o platform.o scanner.o flag.o
 
-parser.o:      node.o scanner.o utils.o printer.o
+parser.o:      ast.o scanner.o utils.o printer.o
 
 scanner.o:     utils.o platform.o
 
-node.o:        scanner.o
+ast.o: scanner.o
 
 flag.o:        fmt.o
        $(GO) -O2 -c -g $(GOROOT)/src/lib/flag.go
similarity index 98%
rename from usr/gri/pretty/node.go
rename to usr/gri/pretty/ast.go
index a465a7856dcdb4440e663cddd9a12a0081c17654..5673088e3b3592bad4ec951d90b12adce21ed214 100644 (file)
@@ -1,8 +1,8 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
+// Copyright 2009 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package Node
+package AST
 
 import Scanner "scanner"
 
index db3856d86372dceeae02bcd30b752258161ae09f..81e8af8f7f80bdf37cef9185f22d4f5d297fca81 100644 (file)
@@ -5,7 +5,7 @@
 package Parser
 
 import Scanner "scanner"
-import Node "node"
+import AST "ast"
 
 
 export type Parser struct {
@@ -16,7 +16,7 @@ export type Parser struct {
        // Scanner
        scanner *Scanner.Scanner;
        tokchan *<-chan *Scanner.Token;
-       comments *Node.List;
+       comments *AST.List;
        
        // Scanner.Token
        pos int;  // token source position
@@ -78,7 +78,7 @@ func (P *Parser) Next0() {
 
 func (P *Parser) Next() {
        for P.Next0(); P.tok == Scanner.COMMENT; P.Next0() {
-               P.comments.Add(Node.NewComment(P.pos, P.val));
+               P.comments.Add(AST.NewComment(P.pos, P.val));
        }
 }
 
@@ -90,7 +90,7 @@ func (P *Parser) Open(verbose, sixg bool, scanner *Scanner.Scanner, tokchan *<-c
        
        P.scanner = scanner;
        P.tokchan = tokchan;
-       P.comments = Node.NewList();
+       P.comments = AST.NewList();
        
        P.Next();
        P.expr_lev = 1;
@@ -126,52 +126,52 @@ func (P *Parser) OptSemicolon() {
 // ----------------------------------------------------------------------------
 // AST support
 
-func ExprType(x *Node.Expr) *Node.Type {
-       var t *Node.Type;
+func ExprType(x *AST.Expr) *AST.Type {
+       var t *AST.Type;
        if x.tok == Scanner.TYPE {
                t = x.t;
        } else if x.tok == Scanner.IDENT {
                // assume a type name
-               t = Node.NewType(x.pos, Scanner.IDENT);
+               t = AST.NewType(x.pos, Scanner.IDENT);
                t.expr = x;
        } else if x.tok == Scanner.PERIOD && x.y != nil && ExprType(x.x) != nil {
                // possibly a qualified (type) identifier
-               t = Node.NewType(x.pos, Scanner.IDENT);
+               t = AST.NewType(x.pos, Scanner.IDENT);
                t.expr = x;
        }
        return t;
 }
 
 
-func (P *Parser) NoType(x *Node.Expr) *Node.Expr {
+func (P *Parser) NoType(x *AST.Expr) *AST.Expr {
        if x != nil && x.tok == Scanner.TYPE {
                P.Error(x.pos, "expected expression, found type");
-               x = Node.NewLit(x.pos, Scanner.INT, "");
+               x = AST.NewLit(x.pos, Scanner.INT, "");
        }
        return x;
 }
 
 
-func (P *Parser) NewExpr(pos, tok int, x, y *Node.Expr) *Node.Expr {
-       return Node.NewExpr(pos, tok, P.NoType(x), P.NoType(y));
+func (P *Parser) NewExpr(pos, tok int, x, y *AST.Expr) *AST.Expr {
+       return AST.NewExpr(pos, tok, P.NoType(x), P.NoType(y));
 }
 
 
 // ----------------------------------------------------------------------------
 // Common productions
 
-func (P *Parser) TryType() *Node.Type;
-func (P *Parser) ParseExpression(prec int) *Node.Expr;
-func (P *Parser) ParseStatement() *Node.Stat;
-func (P *Parser) ParseDeclaration() *Node.Decl;
+func (P *Parser) TryType() *AST.Type;
+func (P *Parser) ParseExpression(prec int) *AST.Expr;
+func (P *Parser) ParseStatement() *AST.Stat;
+func (P *Parser) ParseDeclaration() *AST.Decl;
 
 
-func (P *Parser) ParseIdent() *Node.Expr {
+func (P *Parser) ParseIdent() *AST.Expr {
        P.Trace("Ident");
 
-       x := Node.BadExpr;
+       x := AST.BadExpr;
        if P.tok == Scanner.IDENT {
-               x = Node.NewLit(P.pos, Scanner.IDENT, P.val);
+               x = AST.NewLit(P.pos, Scanner.IDENT, P.val);
                if P.verbose {
                        P.PrintIndent();
                        print("Ident = \"", x.s, "\"\n");
@@ -186,7 +186,7 @@ func (P *Parser) ParseIdent() *Node.Expr {
 }
 
 
-func (P *Parser) ParseIdentList() *Node.Expr {
+func (P *Parser) ParseIdentList() *AST.Expr {
        P.Trace("IdentList");
 
        x := P.ParseIdent();
@@ -205,13 +205,13 @@ func (P *Parser) ParseIdentList() *Node.Expr {
 // ----------------------------------------------------------------------------
 // Types
 
-func (P *Parser) ParseType() *Node.Type {
+func (P *Parser) ParseType() *AST.Type {
        P.Trace("Type");
        
        t := P.TryType();
        if t == nil {
                P.Error(P.pos, "type expected");
-               t = Node.BadType;
+               t = AST.BadType;
        }
        
        P.Ecart();
@@ -219,7 +219,7 @@ func (P *Parser) ParseType() *Node.Type {
 }
 
 
-func (P *Parser) ParseVarType() *Node.Type {
+func (P *Parser) ParseVarType() *AST.Type {
        P.Trace("VarType");
        
        typ := P.ParseType();
@@ -229,7 +229,7 @@ func (P *Parser) ParseVarType() *Node.Type {
 }
 
 
-func (P *Parser) ParseQualifiedIdent() *Node.Expr {
+func (P *Parser) ParseQualifiedIdent() *AST.Expr {
        P.Trace("QualifiedIdent");
 
        x := P.ParseIdent();
@@ -245,10 +245,10 @@ func (P *Parser) ParseQualifiedIdent() *Node.Expr {
 }
 
 
-func (P *Parser) ParseTypeName() *Node.Type {
+func (P *Parser) ParseTypeName() *AST.Type {
        P.Trace("TypeName");
        
-       t := Node.NewType(P.pos, P.tok);
+       t := AST.NewType(P.pos, P.tok);
        t.expr = P.ParseQualifiedIdent();
 
        P.Ecart();
@@ -256,10 +256,10 @@ func (P *Parser) ParseTypeName() *Node.Type {
 }
 
 
-func (P *Parser) ParseArrayType() *Node.Type {
+func (P *Parser) ParseArrayType() *AST.Type {
        P.Trace("ArrayType");
        
-       t := Node.NewType(P.pos, Scanner.LBRACK);
+       t := AST.NewType(P.pos, Scanner.LBRACK);
        P.Expect(Scanner.LBRACK);
        if P.tok != Scanner.RBRACK {
                t.expr = P.ParseExpression(1);
@@ -272,21 +272,21 @@ func (P *Parser) ParseArrayType() *Node.Type {
 }
 
 
-func (P *Parser) ParseChannelType() *Node.Type {
+func (P *Parser) ParseChannelType() *AST.Type {
        P.Trace("ChannelType");
        
-       t := Node.NewType(P.pos, Scanner.CHAN);
-       t.mode = Node.FULL;
+       t := AST.NewType(P.pos, Scanner.CHAN);
+       t.mode = AST.FULL;
        if P.tok == Scanner.CHAN {
                P.Next();
                if P.tok == Scanner.ARROW {
                        P.Next();
-                       t.mode = Node.SEND;
+                       t.mode = AST.SEND;
                }
        } else {
                P.Expect(Scanner.ARROW);
                P.Expect(Scanner.CHAN);
-               t.mode = Node.RECV;
+               t.mode = AST.RECV;
        }
        t.elt = P.ParseVarType();
 
@@ -298,11 +298,11 @@ func (P *Parser) ParseChannelType() *Node.Type {
 // TODO: The code below (ParseVarDecl, ParseVarDeclList) is all too
 // complicated. There must be a better way to do this.
 
-func (P *Parser) ParseVarDecl(expect_ident bool) *Node.Type {
-       t := Node.BadType;
+func (P *Parser) ParseVarDecl(expect_ident bool) *AST.Type {
+       t := AST.BadType;
        if expect_ident {
                x := P.ParseIdent();
-               t = Node.NewType(x.pos, Scanner.IDENT);
+               t = AST.NewType(x.pos, Scanner.IDENT);
                t.expr = x;
        } else {
                t = P.ParseType();
@@ -311,7 +311,7 @@ func (P *Parser) ParseVarDecl(expect_ident bool) *Node.Type {
 }
 
 
-func (P *Parser) ParseVarDeclList(list *Node.List) {
+func (P *Parser) ParseVarDeclList(list *AST.List) {
        P.Trace("VarDeclList");
 
        // parse a list of types
@@ -322,7 +322,7 @@ func (P *Parser) ParseVarDeclList(list *Node.List) {
                list.Add(P.ParseVarDecl(i0 > 0));
        }
 
-       var typ *Node.Type;
+       var typ *AST.Type;
        if i0 > 0 {
                // not the first parameter section; we must have a type
                typ = P.ParseType();
@@ -336,23 +336,23 @@ func (P *Parser) ParseVarDeclList(list *Node.List) {
                // all list entries must be identifiers
                // convert the type entries into identifiers
                for i, n := i0, list.len(); i < n; i++ {
-                       t := list.at(i).(*Node.Type);
+                       t := list.at(i).(*AST.Type);
                        if t.tok == Scanner.IDENT && t.expr.tok == Scanner.IDENT {
                                list.set(i, t.expr);
                        } else {
-                               list.set(i, Node.BadExpr);
+                               list.set(i, AST.BadExpr);
                                P.Error(t.pos, "identifier expected");
                        }
                }
                // add type
-               list.Add(Node.NewTypeExpr(typ));
+               list.Add(AST.NewTypeExpr(typ));
 
        } else {
                // all list entries are types
                // convert all type entries into type expressions
                for i, n := i0, list.len(); i < n; i++ {
-                       t := list.at(i).(*Node.Type);
-                       list.set(i, Node.NewTypeExpr(t));
+                       t := list.at(i).(*AST.Type);
+                       list.set(i, AST.NewTypeExpr(t));
                }
                
                if P.tok == Scanner.COMMA {
@@ -364,10 +364,10 @@ func (P *Parser) ParseVarDeclList(list *Node.List) {
 }
 
 
-func (P *Parser) ParseParameterList() *Node.List {
+func (P *Parser) ParseParameterList() *AST.List {
        P.Trace("ParameterList");
        
-       list := Node.NewList();
+       list := AST.NewList();
        P.ParseVarDeclList(list);
        for P.tok == Scanner.COMMA {
                P.Next();
@@ -379,10 +379,10 @@ func (P *Parser) ParseParameterList() *Node.List {
 }
 
 
-func (P *Parser) ParseParameters() *Node.Type {
+func (P *Parser) ParseParameters() *AST.Type {
        P.Trace("Parameters");
        
-       t := Node.NewType(P.pos, Scanner.STRUCT);
+       t := AST.NewType(P.pos, Scanner.STRUCT);
        P.Expect(Scanner.LPAREN);
        if P.tok != Scanner.RPAREN {
                t.list = P.ParseParameterList();
@@ -410,18 +410,18 @@ func (P *Parser) ParseResultList() {
 }
 
 
-func (P *Parser) ParseResult() *Node.Type {
+func (P *Parser) ParseResult() *AST.Type {
        P.Trace("Result");
        
-       var t *Node.Type;
+       var t *AST.Type;
        if P.tok == Scanner.LPAREN {
                t = P.ParseParameters();
        } else {
                typ := P.TryType();
                if typ != nil {
-                       t = Node.NewType(P.pos, Scanner.STRUCT);
-                       t.list = Node.NewList();
-                       t.list.Add(Node.NewTypeExpr(typ));
+                       t = AST.NewType(P.pos, Scanner.STRUCT);
+                       t.list = AST.NewList();
+                       t.list.Add(AST.NewTypeExpr(typ));
                }
        }
 
@@ -436,10 +436,10 @@ func (P *Parser) ParseResult() *Node.Type {
 // (params) type
 // (params) (results)
 
-func (P *Parser) ParseFunctionType() *Node.Type {
+func (P *Parser) ParseFunctionType() *AST.Type {
        P.Trace("FunctionType");
        
-       t := Node.NewType(P.pos, Scanner.LPAREN);
+       t := AST.NewType(P.pos, Scanner.LPAREN);
        t.list = P.ParseParameters().list;  // TODO find better solution
        t.elt = P.ParseResult();
        
@@ -448,24 +448,24 @@ func (P *Parser) ParseFunctionType() *Node.Type {
 }
 
 
-func (P *Parser) ParseMethodSpec(list *Node.List) {
+func (P *Parser) ParseMethodSpec(list *AST.List) {
        P.Trace("MethodDecl");
        
        list.Add(P.ParseIdent());
-       list.Add(Node.NewTypeExpr(P.ParseFunctionType()));
+       list.Add(AST.NewTypeExpr(P.ParseFunctionType()));
        
        P.Ecart();
 }
 
 
-func (P *Parser) ParseInterfaceType() *Node.Type {
+func (P *Parser) ParseInterfaceType() *AST.Type {
        P.Trace("InterfaceType");
        
-       t := Node.NewType(P.pos, Scanner.INTERFACE);
+       t := AST.NewType(P.pos, Scanner.INTERFACE);
        P.Expect(Scanner.INTERFACE);
        if P.tok == Scanner.LBRACE {
                P.Next();
-               t.list = Node.NewList();
+               t.list = AST.NewList();
                for P.tok == Scanner.IDENT {
                        P.ParseMethodSpec(t.list);
                        if P.tok != Scanner.RBRACE {
@@ -480,10 +480,10 @@ func (P *Parser) ParseInterfaceType() *Node.Type {
 }
 
 
-func (P *Parser) ParseMapType() *Node.Type {
+func (P *Parser) ParseMapType() *AST.Type {
        P.Trace("MapType");
        
-       t := Node.NewType(P.pos, Scanner.MAP);
+       t := AST.NewType(P.pos, Scanner.MAP);
        P.Expect(Scanner.MAP);
        P.Expect(Scanner.LBRACK);
        t.key = P.ParseVarType();
@@ -495,14 +495,14 @@ func (P *Parser) ParseMapType() *Node.Type {
 }
 
 
-func (P *Parser) ParseStructType() *Node.Type {
+func (P *Parser) ParseStructType() *AST.Type {
        P.Trace("StructType");
 
-       t := Node.NewType(P.pos, Scanner.STRUCT);
+       t := AST.NewType(P.pos, Scanner.STRUCT);
        P.Expect(Scanner.STRUCT);
        if P.tok == Scanner.LBRACE {
                P.Next();
-               t.list = Node.NewList();
+               t.list = AST.NewList();
                for P.tok == Scanner.IDENT {
                        P.ParseVarDeclList(t.list);
                        if P.tok != Scanner.RBRACE {
@@ -518,10 +518,10 @@ func (P *Parser) ParseStructType() *Node.Type {
 }
 
 
-func (P *Parser) ParsePointerType() *Node.Type {
+func (P *Parser) ParsePointerType() *AST.Type {
        P.Trace("PointerType");
        
-       t := Node.NewType(P.pos, Scanner.MUL);
+       t := AST.NewType(P.pos, Scanner.MUL);
        P.Expect(Scanner.MUL);
        t.elt = P.ParseType();
        
@@ -530,10 +530,10 @@ func (P *Parser) ParsePointerType() *Node.Type {
 }
 
 
-func (P *Parser) TryType() *Node.Type {
+func (P *Parser) TryType() *AST.Type {
        P.Trace("Type (try)");
        
-       t := Node.BadType;
+       t := AST.BadType;
        switch P.tok {
        case Scanner.IDENT: t = P.ParseTypeName();
        case Scanner.LBRACK: t = P.ParseArrayType();
@@ -554,10 +554,10 @@ func (P *Parser) TryType() *Node.Type {
 // ----------------------------------------------------------------------------
 // Blocks
 
-func (P *Parser) ParseStatementList() *Node.List {
+func (P *Parser) ParseStatementList() *AST.List {
        P.Trace("StatementList");
        
-       list := Node.NewList();
+       list := AST.NewList();
        for P.tok != Scanner.CASE && P.tok != Scanner.DEFAULT && P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
                s := P.ParseStatement();
                if s != nil {
@@ -583,7 +583,7 @@ func (P *Parser) ParseStatementList() *Node.List {
 }
 
 
-func (P *Parser) ParseBlock() *Node.List {
+func (P *Parser) ParseBlock() *AST.List {
        P.Trace("Block");
        
        P.Expect(Scanner.LBRACE);
@@ -599,27 +599,31 @@ func (P *Parser) ParseBlock() *Node.List {
 // ----------------------------------------------------------------------------
 // Expressions
 
-// TODO make this non-recursive
-func (P *Parser) ParseExpressionList() *Node.Expr {
+func (P *Parser) ParseExpressionList() *AST.Expr {
        P.Trace("ExpressionList");
 
        x := P.ParseExpression(1);
-       if P.tok == Scanner.COMMA {
+       for first := true; P.tok == Scanner.COMMA; {
                pos := P.pos;
                P.Next();
-               y := P.ParseExpressionList();
-               x = P.NewExpr(pos, Scanner.COMMA, x, y);
+               y := P.ParseExpression(1);
+               if first {
+                       x = P.NewExpr(pos, Scanner.COMMA, x, y);
+                       first = false;
+               } else {
+                       x.y = P.NewExpr(pos, Scanner.COMMA, x.y, y);
+               }
        }
-       
+
        P.Ecart();
        return x;
 }
 
 
-func (P *Parser) ParseFunctionLit() *Node.Expr {
+func (P *Parser) ParseFunctionLit() *AST.Expr {
        P.Trace("FunctionLit");
        
-       x := Node.NewLit(P.pos, Scanner.FUNC, "");
+       x := AST.NewLit(P.pos, Scanner.FUNC, "");
        P.Expect(Scanner.FUNC);
        x.t = P.ParseFunctionType();
        P.scope_lev++;
@@ -631,10 +635,10 @@ func (P *Parser) ParseFunctionLit() *Node.Expr {
 }
 
 
-func (P *Parser) ParseOperand() *Node.Expr {
+func (P *Parser) ParseOperand() *AST.Expr {
        P.Trace("Operand");
 
-       x := Node.BadExpr;
+       x := AST.BadExpr;
        switch P.tok {
        case Scanner.IDENT:
                x = P.ParseIdent();
@@ -649,7 +653,7 @@ func (P *Parser) ParseOperand() *Node.Expr {
                P.Expect(Scanner.RPAREN);
 
        case Scanner.INT, Scanner.FLOAT, Scanner.STRING:
-               x = Node.NewLit(P.pos, P.tok, P.val);
+               x = AST.NewLit(P.pos, P.tok, P.val);
                P.Next();
                if x.tok == Scanner.STRING {
                        for ; P.tok == Scanner.STRING; P.Next() {
@@ -663,7 +667,7 @@ func (P *Parser) ParseOperand() *Node.Expr {
        default:
                t := P.TryType();
                if t != nil {
-                       x = Node.NewTypeExpr(t);
+                       x = AST.NewTypeExpr(t);
                } else {
                        P.Error(P.pos, "operand expected");
                        P.Next();  // make progress
@@ -675,7 +679,7 @@ func (P *Parser) ParseOperand() *Node.Expr {
 }
 
 
-func (P *Parser) ParseSelectorOrTypeGuard(x *Node.Expr) *Node.Expr {
+func (P *Parser) ParseSelectorOrTypeGuard(x *AST.Expr) *AST.Expr {
        P.Trace("SelectorOrTypeGuard");
 
        x = P.NewExpr(P.pos, Scanner.PERIOD, x, nil);
@@ -695,7 +699,7 @@ func (P *Parser) ParseSelectorOrTypeGuard(x *Node.Expr) *Node.Expr {
 }
 
 
-func (P *Parser) ParseIndex(x *Node.Expr) *Node.Expr {
+func (P *Parser) ParseIndex(x *AST.Expr) *AST.Expr {
        P.Trace("IndexOrSlice");
        
        pos := P.pos;
@@ -708,9 +712,9 @@ func (P *Parser) ParseIndex(x *Node.Expr) *Node.Expr {
 }
 
 
-func (P *Parser) ParseBinaryExpr(prec1 int) *Node.Expr
+func (P *Parser) ParseBinaryExpr(prec1 int) *AST.Expr
 
-func (P *Parser) ParseCall(x *Node.Expr) *Node.Expr {
+func (P *Parser) ParseCall(x *AST.Expr) *AST.Expr {
        P.Trace("Call");
 
        x = P.NewExpr(P.pos, Scanner.LPAREN, x, nil);
@@ -737,46 +741,58 @@ func (P *Parser) ParseCall(x *Node.Expr) *Node.Expr {
 }
 
 
-func (P *Parser) ParseCompositeList(mode int) *Node.Expr {
+func (P *Parser) ParseCompositeList() *AST.Expr {
        x := P.ParseExpression(0);
-       
-       switch mode {
-       case 0:  // first element determines mode
-               mode = 1;
-               if x.tok == Scanner.COLON {
-                       mode = 2;
-               }
-       case 1:
-               if x.tok == Scanner.COLON {
-                       P.Error(x.x.pos, "single value expected; found pair");
-               }
-       case 2:
-               if x.tok != Scanner.COLON {
-                       P.Error(x.pos, "key:value pair expected; found single value");
-               }
-       }
-
        if P.tok == Scanner.COMMA {
                pos := P.pos;
                P.Next();
-               if P.tok != Scanner.RBRACE {
-                       y := P.ParseCompositeList(mode);
-                       x = P.NewExpr(pos, Scanner.COMMA, x, y);
+               
+               // first element determines mode
+               singles := true;
+               if x.tok == Scanner.COLON {
+                       singles = false;
                }
-       }
+               
+               for first := true; P.tok != Scanner.RBRACE && P.tok != Scanner.EOF; {
+                       y := P.ParseExpression(0);
 
+                       if singles {
+                               if y.tok == Scanner.COLON {
+                                       P.Error(y.x.pos, "single value expected; found pair");
+                               }
+                       } else {
+                               if y.tok != Scanner.COLON {
+                                       P.Error(y.pos, "key:value pair expected; found single value");
+                               }
+                       }
+                       
+                       if first {
+                               x = P.NewExpr(pos, Scanner.COMMA, x, y);
+                       } else {
+                               x.y = P.NewExpr(pos, Scanner.COMMA, x.y, y);
+                       }
+               
+                       if P.tok == Scanner.COMMA {
+                               pos = P.pos;
+                               P.Next();
+                       } else {
+                               break;
+                       }
+
+               }
+       }
        return x;
 }
 
 
-func (P *Parser) ParseCompositeLit(t *Node.Type) *Node.Expr {
+func (P *Parser) ParseCompositeLit(t *AST.Type) *AST.Expr {
        P.Trace("CompositeLit");
        
        x := P.NewExpr(P.pos, Scanner.LBRACE, nil, nil);
        x.t = t;
        P.Expect(Scanner.LBRACE);
        if P.tok != Scanner.RBRACE {
-               x.y = P.ParseCompositeList(0);
+               x.y = P.ParseCompositeList();
        }
        P.Expect(Scanner.RBRACE);
        
@@ -785,7 +801,7 @@ func (P *Parser) ParseCompositeLit(t *Node.Type) *Node.Expr {
 }
 
 
-func (P *Parser) ParsePrimaryExpr() *Node.Expr {
+func (P *Parser) ParsePrimaryExpr() *AST.Expr {
        P.Trace("PrimaryExpr");
        
        x := P.ParseOperand();
@@ -798,7 +814,7 @@ func (P *Parser) ParsePrimaryExpr() *Node.Expr {
                        // assume a composite literal only if x could be a type
                        // and if we are not inside control clause (expr_lev > 0)
                        // (composites inside control clauses must be parenthesized)
-                       var t *Node.Type;
+                       var t *AST.Type;
                        if P.expr_lev > 0 {
                                t = ExprType(x);
                        }
@@ -817,10 +833,10 @@ exit:
 }
 
 
-func (P *Parser) ParseUnaryExpr() *Node.Expr {
+func (P *Parser) ParseUnaryExpr() *AST.Expr {
        P.Trace("UnaryExpr");
        
-       x := Node.BadExpr;
+       x := AST.BadExpr;
        switch P.tok {
        case Scanner.ADD, Scanner.SUB, Scanner.MUL, Scanner.NOT, Scanner.XOR, Scanner.ARROW, Scanner.AND:
                pos, tok := P.pos, P.tok;
@@ -828,9 +844,9 @@ func (P *Parser) ParseUnaryExpr() *Node.Expr {
                y := P.ParseUnaryExpr();
                if tok == Scanner.MUL && y.tok == Scanner.TYPE {
                        // pointer type
-                       t := Node.NewType(pos, Scanner.MUL);
+                       t := AST.NewType(pos, Scanner.MUL);
                        t.elt = y.t;
-                       x = Node.NewTypeExpr(t);
+                       x = AST.NewTypeExpr(t);
                } else {
                        x = P.NewExpr(pos, tok, nil, y);
                }
@@ -844,7 +860,7 @@ func (P *Parser) ParseUnaryExpr() *Node.Expr {
 }
 
 
-func (P *Parser) ParseBinaryExpr(prec1 int) *Node.Expr {
+func (P *Parser) ParseBinaryExpr(prec1 int) *AST.Expr {
        P.Trace("BinaryExpr");
        
        x := P.ParseUnaryExpr();
@@ -862,7 +878,7 @@ func (P *Parser) ParseBinaryExpr(prec1 int) *Node.Expr {
 }
 
 
-func (P *Parser) ParseExpression(prec int) *Node.Expr {
+func (P *Parser) ParseExpression(prec int) *AST.Expr {
        P.Trace("Expression");
        indent := P.indent;
 
@@ -882,16 +898,16 @@ func (P *Parser) ParseExpression(prec int) *Node.Expr {
 // ----------------------------------------------------------------------------
 // Statements
 
-func (P *Parser) ParseSimpleStat() *Node.Stat {
+func (P *Parser) ParseSimpleStat() *AST.Stat {
        P.Trace("SimpleStat");
        
-       s := Node.BadStat;
+       s := AST.BadStat;
        x := P.ParseExpressionList();
        
        switch P.tok {
        case Scanner.COLON:
                // label declaration
-               s = Node.NewStat(P.pos, Scanner.COLON);
+               s = AST.NewStat(P.pos, Scanner.COLON);
                s.expr = x;
                if x.len() != 1 {
                        P.Error(x.pos, "illegal label declaration");
@@ -911,8 +927,8 @@ func (P *Parser) ParseSimpleStat() *Node.Stat {
                if xl, yl := x.len(), y.len(); xl > 1 && yl > 1 && xl != yl {
                        P.Error(x.pos, "arity of lhs doesn't match rhs");
                }
-               s = Node.NewStat(x.pos, Scanner.EXPRSTAT);
-               s.expr = Node.NewExpr(pos, tok, x, y);
+               s = AST.NewStat(x.pos, Scanner.EXPRSTAT);
+               s.expr = AST.NewExpr(pos, tok, x, y);
 
        default:
                var pos, tok int;
@@ -922,7 +938,7 @@ func (P *Parser) ParseSimpleStat() *Node.Stat {
                } else {
                        pos, tok = x.pos, Scanner.EXPRSTAT;
                }
-               s = Node.NewStat(pos, tok);
+               s = AST.NewStat(pos, tok);
                s.expr = x;
                if x.len() != 1 {
                        P.Error(x.pos, "only one expression allowed");
@@ -934,10 +950,10 @@ func (P *Parser) ParseSimpleStat() *Node.Stat {
 }
 
 
-func (P *Parser) ParseGoStat() *Node.Stat {
+func (P *Parser) ParseGoStat() *AST.Stat {
        P.Trace("GoStat");
        
-       s := Node.NewStat(P.pos, Scanner.GO);
+       s := AST.NewStat(P.pos, Scanner.GO);
        P.Expect(Scanner.GO);
        s.expr = P.ParseExpression(1);
        
@@ -946,10 +962,10 @@ func (P *Parser) ParseGoStat() *Node.Stat {
 }
 
 
-func (P *Parser) ParseReturnStat() *Node.Stat {
+func (P *Parser) ParseReturnStat() *AST.Stat {
        P.Trace("ReturnStat");
        
-       s := Node.NewStat(P.pos, Scanner.RETURN);
+       s := AST.NewStat(P.pos, Scanner.RETURN);
        P.Expect(Scanner.RETURN);
        if P.tok != Scanner.SEMICOLON && P.tok != Scanner.RBRACE {
                s.expr = P.ParseExpressionList();
@@ -960,10 +976,10 @@ func (P *Parser) ParseReturnStat() *Node.Stat {
 }
 
 
-func (P *Parser) ParseControlFlowStat(tok int) *Node.Stat {
+func (P *Parser) ParseControlFlowStat(tok int) *AST.Stat {
        P.Trace("ControlFlowStat");
        
-       s := Node.NewStat(P.pos, tok);
+       s := AST.NewStat(P.pos, tok);
        P.Expect(tok);
        if tok != Scanner.FALLTHROUGH && P.tok == Scanner.IDENT {
                s.expr = P.ParseIdent();
@@ -974,10 +990,10 @@ func (P *Parser) ParseControlFlowStat(tok int) *Node.Stat {
 }
 
 
-func (P *Parser) ParseControlClause(keyword int) *Node.Stat {
+func (P *Parser) ParseControlClause(keyword int) *AST.Stat {
        P.Trace("ControlClause");
        
-       s := Node.NewStat(P.pos, keyword);
+       s := AST.NewStat(P.pos, keyword);
        P.Expect(keyword);
        if P.tok != Scanner.LBRACE {
                prev_lev := P.expr_lev;
@@ -1009,22 +1025,22 @@ func (P *Parser) ParseControlClause(keyword int) *Node.Stat {
 }
 
 
-func (P *Parser) ParseIfStat() *Node.Stat {
+func (P *Parser) ParseIfStat() *AST.Stat {
        P.Trace("IfStat");
 
        s := P.ParseControlClause(Scanner.IF);
        s.block = P.ParseBlock();
        if P.tok == Scanner.ELSE {
                P.Next();
-               s1 := Node.BadStat;
+               s1 := AST.BadStat;
                if P.sixg {
                        s1 = P.ParseStatement();
                        if s1 != nil {
                                // not the empty statement
                                if s1.tok != Scanner.LBRACE {
                                        // wrap in a block if we don't have one
-                                       b := Node.NewStat(P.pos, Scanner.LBRACE);
-                                       b.block = Node.NewList();
+                                       b := AST.NewStat(P.pos, Scanner.LBRACE);
+                                       b.block = AST.NewList();
                                        b.block.Add(s1);
                                        s1 = b;
                                }
@@ -1033,7 +1049,7 @@ func (P *Parser) ParseIfStat() *Node.Stat {
                } else if P.tok == Scanner.IF {
                        s1 = P.ParseIfStat();
                } else {
-                       s1 = Node.NewStat(P.pos, Scanner.LBRACE);
+                       s1 = AST.NewStat(P.pos, Scanner.LBRACE);
                        s1.block = P.ParseBlock();
                }
                s.post = s1;
@@ -1044,7 +1060,7 @@ func (P *Parser) ParseIfStat() *Node.Stat {
 }
 
 
-func (P *Parser) ParseForStat() *Node.Stat {
+func (P *Parser) ParseForStat() *AST.Stat {
        P.Trace("ForStat");
        
        s := P.ParseControlClause(Scanner.FOR);
@@ -1055,10 +1071,10 @@ func (P *Parser) ParseForStat() *Node.Stat {
 }
 
 
-func (P *Parser) ParseCase() *Node.Stat {
+func (P *Parser) ParseCase() *AST.Stat {
        P.Trace("Case");
        
-       s := Node.NewStat(P.pos, P.tok);
+       s := AST.NewStat(P.pos, P.tok);
        if P.tok == Scanner.CASE {
                P.Next();
                s.expr = P.ParseExpressionList();
@@ -1072,7 +1088,7 @@ func (P *Parser) ParseCase() *Node.Stat {
 }
 
 
-func (P *Parser) ParseCaseClause() *Node.Stat {
+func (P *Parser) ParseCaseClause() *AST.Stat {
        P.Trace("CaseClause");
 
        s := P.ParseCase();
@@ -1085,11 +1101,11 @@ func (P *Parser) ParseCaseClause() *Node.Stat {
 }
 
 
-func (P *Parser) ParseSwitchStat() *Node.Stat {
+func (P *Parser) ParseSwitchStat() *AST.Stat {
        P.Trace("SwitchStat");
        
        s := P.ParseControlClause(Scanner.SWITCH);
-       s.block = Node.NewList();
+       s.block = AST.NewList();
        P.Expect(Scanner.LBRACE);
        for P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
                s.block.Add(P.ParseCaseClause());
@@ -1102,10 +1118,10 @@ func (P *Parser) ParseSwitchStat() *Node.Stat {
 }
 
 
-func (P *Parser) ParseCommCase() *Node.Stat {
+func (P *Parser) ParseCommCase() *AST.Stat {
        P.Trace("CommCase");
 
-       s := Node.NewStat(P.pos, Scanner.CASE);
+       s := AST.NewStat(P.pos, Scanner.CASE);
        if P.tok == Scanner.CASE {
                P.Next();
                P.ParseExpression(1);
@@ -1124,7 +1140,7 @@ func (P *Parser) ParseCommCase() *Node.Stat {
 }
 
 
-func (P *Parser) ParseCommClause() *Node.Stat {
+func (P *Parser) ParseCommClause() *AST.Stat {
        P.Trace("CommClause");
        
        s := P.ParseCommCase();
@@ -1137,11 +1153,11 @@ func (P *Parser) ParseCommClause() *Node.Stat {
 }
 
 
-func (P *Parser) ParseSelectStat() *Node.Stat {
+func (P *Parser) ParseSelectStat() *AST.Stat {
        P.Trace("SelectStat");
        
-       s := Node.NewStat(P.pos, Scanner.SELECT);
-       s.block = Node.NewList();
+       s := AST.NewStat(P.pos, Scanner.SELECT);
+       s.block = AST.NewList();
        P.Expect(Scanner.SELECT);
        P.Expect(Scanner.LBRACE);
        for P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
@@ -1155,10 +1171,10 @@ func (P *Parser) ParseSelectStat() *Node.Stat {
 }
 
 
-func (P *Parser) ParseRangeStat() *Node.Stat {
+func (P *Parser) ParseRangeStat() *AST.Stat {
        P.Trace("RangeStat");
        
-       s := Node.NewStat(P.pos, Scanner.RANGE);
+       s := AST.NewStat(P.pos, Scanner.RANGE);
        P.Expect(Scanner.RANGE);
        P.ParseIdentList();
        P.Expect(Scanner.DEFINE);
@@ -1170,14 +1186,14 @@ func (P *Parser) ParseRangeStat() *Node.Stat {
 }
 
 
-func (P *Parser) ParseStatement() *Node.Stat {
+func (P *Parser) ParseStatement() *AST.Stat {
        P.Trace("Statement");
        indent := P.indent;
 
-       s := Node.BadStat;
+       s := AST.BadStat;
        switch P.tok {
        case Scanner.CONST, Scanner.TYPE, Scanner.VAR:
-               s = Node.NewStat(P.pos, P.tok);
+               s = AST.NewStat(P.pos, P.tok);
                s.decl = P.ParseDeclaration();
        case Scanner.FUNC:
                // for now we do not allow local function declarations,
@@ -1196,7 +1212,7 @@ func (P *Parser) ParseStatement() *Node.Stat {
        case Scanner.BREAK, Scanner.CONTINUE, Scanner.GOTO, Scanner.FALLTHROUGH:
                s = P.ParseControlFlowStat(P.tok);
        case Scanner.LBRACE:
-               s = Node.NewStat(P.pos, Scanner.LBRACE);
+               s = AST.NewStat(P.pos, Scanner.LBRACE);
                s.block = P.ParseBlock();
        case Scanner.IF:
                s = P.ParseIfStat();
@@ -1224,10 +1240,10 @@ func (P *Parser) ParseStatement() *Node.Stat {
 // ----------------------------------------------------------------------------
 // Declarations
 
-func (P *Parser) ParseImportSpec() *Node.Decl {
+func (P *Parser) ParseImportSpec() *AST.Decl {
        P.Trace("ImportSpec");
        
-       d := Node.NewDecl(P.pos, Scanner.IMPORT, false);
+       d := AST.NewDecl(P.pos, Scanner.IMPORT, false);
        if P.tok == Scanner.PERIOD {
                P.Error(P.pos, `"import ." not yet handled properly`);
                P.Next();
@@ -1237,7 +1253,7 @@ func (P *Parser) ParseImportSpec() *Node.Decl {
        
        if P.tok == Scanner.STRING {
                // TODO eventually the scanner should strip the quotes
-               d.val = Node.NewLit(P.pos, Scanner.STRING, P.val);
+               d.val = AST.NewLit(P.pos, Scanner.STRING, P.val);
                P.Next();
        } else {
                P.Expect(Scanner.STRING);  // use Expect() error handling
@@ -1248,10 +1264,10 @@ func (P *Parser) ParseImportSpec() *Node.Decl {
 }
 
 
-func (P *Parser) ParseConstSpec(exported bool) *Node.Decl {
+func (P *Parser) ParseConstSpec(exported bool) *AST.Decl {
        P.Trace("ConstSpec");
        
-       d := Node.NewDecl(P.pos, Scanner.CONST, exported);
+       d := AST.NewDecl(P.pos, Scanner.CONST, exported);
        d.ident = P.ParseIdent();
        d.typ = P.TryType();
        if P.tok == Scanner.ASSIGN {
@@ -1264,10 +1280,10 @@ func (P *Parser) ParseConstSpec(exported bool) *Node.Decl {
 }
 
 
-func (P *Parser) ParseTypeSpec(exported bool) *Node.Decl {
+func (P *Parser) ParseTypeSpec(exported bool) *AST.Decl {
        P.Trace("TypeSpec");
 
-       d := Node.NewDecl(P.pos, Scanner.TYPE, exported);
+       d := AST.NewDecl(P.pos, Scanner.TYPE, exported);
        d.ident = P.ParseIdent();
        d.typ = P.ParseType();
        P.opt_semi = true;
@@ -1277,10 +1293,10 @@ func (P *Parser) ParseTypeSpec(exported bool) *Node.Decl {
 }
 
 
-func (P *Parser) ParseVarSpec(exported bool) *Node.Decl {
+func (P *Parser) ParseVarSpec(exported bool) *AST.Decl {
        P.Trace("VarSpec");
        
-       d := Node.NewDecl(P.pos, Scanner.VAR, exported);
+       d := AST.NewDecl(P.pos, Scanner.VAR, exported);
        d.ident = P.ParseIdentList();
        if P.tok == Scanner.ASSIGN {
                P.Next();
@@ -1299,7 +1315,7 @@ func (P *Parser) ParseVarSpec(exported bool) *Node.Decl {
 
 
 // TODO replace this by using function pointers derived from methods
-func (P *Parser) ParseSpec(exported bool, keyword int) *Node.Decl {
+func (P *Parser) ParseSpec(exported bool, keyword int) *AST.Decl {
        switch keyword {
        case Scanner.IMPORT: return P.ParseImportSpec();
        case Scanner.CONST: return P.ParseConstSpec(exported);
@@ -1311,15 +1327,15 @@ func (P *Parser) ParseSpec(exported bool, keyword int) *Node.Decl {
 }
 
 
-func (P *Parser) ParseDecl(exported bool, keyword int) *Node.Decl {
+func (P *Parser) ParseDecl(exported bool, keyword int) *AST.Decl {
        P.Trace("Decl");
        
-       d := Node.BadDecl;
+       d := AST.BadDecl;
        P.Expect(keyword);
        if P.tok == Scanner.LPAREN {
                P.Next();
-               d = Node.NewDecl(P.pos, keyword, exported);
-               d.list = Node.NewList();
+               d = AST.NewDecl(P.pos, keyword, exported);
+               d.list = AST.NewList();
                for P.tok != Scanner.RPAREN && P.tok != Scanner.EOF {
                        d.list.Add(P.ParseSpec(exported, keyword));
                        if P.tok == Scanner.SEMICOLON {
@@ -1349,13 +1365,13 @@ func (P *Parser) ParseDecl(exported bool, keyword int) *Node.Decl {
 // func (recv) ident (params) type
 // func (recv) ident (params) (results)
 
-func (P *Parser) ParseFunctionDecl(exported bool) *Node.Decl {
+func (P *Parser) ParseFunctionDecl(exported bool) *AST.Decl {
        P.Trace("FunctionDecl");
        
-       d := Node.NewDecl(P.pos, Scanner.FUNC, exported);
+       d := AST.NewDecl(P.pos, Scanner.FUNC, exported);
        P.Expect(Scanner.FUNC);
        
-       var recv *Node.Type;
+       var recv *AST.Type;
        if P.tok == Scanner.LPAREN {
                pos := P.pos;
                recv = P.ParseParameters();
@@ -1379,10 +1395,10 @@ func (P *Parser) ParseFunctionDecl(exported bool) *Node.Decl {
 }
 
 
-func (P *Parser) ParseExportDecl() *Node.Decl {
+func (P *Parser) ParseExportDecl() *AST.Decl {
        P.Trace("ExportDecl");
        
-       d := Node.NewDecl(P.pos, Scanner.EXPORT, false);
+       d := AST.NewDecl(P.pos, Scanner.EXPORT, false);
        d.ident = P.ParseIdentList();
 
        P.Ecart();
@@ -1390,11 +1406,11 @@ func (P *Parser) ParseExportDecl() *Node.Decl {
 }
 
 
-func (P *Parser) ParseDeclaration() *Node.Decl {
+func (P *Parser) ParseDeclaration() *AST.Decl {
        P.Trace("Declaration");
        indent := P.indent;
        
-       d := Node.BadDecl;
+       d := AST.BadDecl;
        exported := false;
        if P.tok == Scanner.EXPORT {
                if P.scope_lev == 0 {
@@ -1436,14 +1452,14 @@ func (P *Parser) ParseDeclaration() *Node.Decl {
 // ----------------------------------------------------------------------------
 // Program
 
-func (P *Parser) ParseProgram() *Node.Program {
+func (P *Parser) ParseProgram() *AST.Program {
        P.Trace("Program");
        
-       p := Node.NewProgram(P.pos);
+       p := AST.NewProgram(P.pos);
        P.Expect(Scanner.PACKAGE);
        p.ident = P.ParseIdent();
        
-       p.decls = Node.NewList();
+       p.decls = AST.NewList();
        for P.tok == Scanner.IMPORT {
                p.decls.Add(P.ParseDecl(false, Scanner.IMPORT));
                P.OptSemicolon();
index d66ef8185d44ae3cd2e1789757ebccfe251b8029..3072b6a46e971b2afc2aa9d6a78f022493b17899 100644 (file)
@@ -5,7 +5,7 @@
 package Printer
 
 import Scanner "scanner"
-import Node "node"
+import AST "ast"
 
 
 export type Printer struct {
@@ -16,7 +16,7 @@ export type Printer struct {
        newl int;  // pending "\n"'s
 
        // comments
-       clist *Node.List;
+       clist *AST.List;
        cindex int;
        cpos int;
 }
@@ -30,7 +30,7 @@ func (P *Printer) String(pos int, s string) {
        /*
        for pos > P.cpos {
                // we have a comment
-               c := P.clist.at(P.cindex).(*Node.Comment);
+               c := P.clist.at(P.cindex).(*AST.Comment);
                if c.text[1] == '/' {
                        print("  " + c.text);
                        if P.newl <= 0 {
@@ -41,7 +41,7 @@ func (P *Printer) String(pos int, s string) {
                }
                P.cindex++;
                if P.cindex < P.clist.len() {
-                       P.cpos = P.clist.at(P.cindex).(*Node.Comment).pos;
+                       P.cpos = P.clist.at(P.cindex).(*AST.Comment).pos;
                } else {
                        P.cpos = 1000000000;  // infinite
                }
@@ -100,14 +100,14 @@ func (P *Printer) Error(pos int, tok int, msg string) {
 // ----------------------------------------------------------------------------
 // Types
 
-func (P *Printer) Type(t *Node.Type)
-func (P *Printer) Expr(x *Node.Expr)
+func (P *Printer) Type(t *AST.Type)
+func (P *Printer) Expr(x *AST.Expr)
 
-func (P *Printer) Parameters(pos int, list *Node.List) {
+func (P *Printer) Parameters(pos int, list *AST.List) {
        P.String(pos, "(");
        var prev int;
        for i, n := 0, list.len(); i < n; i++ {
-               x := list.at(i).(*Node.Expr);
+               x := list.at(i).(*AST.Expr);
                if i > 0 {
                        if prev == x.tok || prev == Scanner.TYPE {
                                P.String(0, ", ");
@@ -122,11 +122,11 @@ func (P *Printer) Parameters(pos int, list *Node.List) {
 }
 
 
-func (P *Printer) Fields(list *Node.List) {
+func (P *Printer) Fields(list *AST.List) {
        P.OpenScope(" {");
        var prev int;
        for i, n := 0, list.len(); i < n; i++ {
-               x := list.at(i).(*Node.Expr);
+               x := list.at(i).(*AST.Expr);
                if i > 0 {
                        if prev == Scanner.TYPE {
                                P.String(0, ";");
@@ -145,7 +145,7 @@ func (P *Printer) Fields(list *Node.List) {
 }
 
 
-func (P *Printer) Type(t *Node.Type) {
+func (P *Printer) Type(t *AST.Type) {
        switch t.tok {
        case Scanner.IDENT:
                P.Expr(t.expr);
@@ -174,9 +174,9 @@ func (P *Printer) Type(t *Node.Type) {
        case Scanner.CHAN:
                var m string;
                switch t.mode {
-               case Node.FULL: m = "chan ";
-               case Node.RECV: m = "<-chan ";
-               case Node.SEND: m = "chan <- ";
+               case AST.FULL: m = "chan ";
+               case AST.RECV: m = "<-chan ";
+               case AST.SEND: m = "chan <- ";
                }
                P.String(t.pos, m);
                P.Type(t.elt);
@@ -201,9 +201,9 @@ func (P *Printer) Type(t *Node.Type) {
 // ----------------------------------------------------------------------------
 // Expressions
 
-func (P *Printer) Block(list *Node.List, indent bool);
+func (P *Printer) Block(list *AST.List, indent bool);
 
-func (P *Printer) Expr1(x *Node.Expr, prec1 int) {
+func (P *Printer) Expr1(x *AST.Expr, prec1 int) {
        if x == nil {
                return;  // empty expression list
        }
@@ -288,7 +288,7 @@ func (P *Printer) Expr1(x *Node.Expr, prec1 int) {
 }
 
 
-func (P *Printer) Expr(x *Node.Expr) {
+func (P *Printer) Expr(x *AST.Expr) {
        P.Expr1(x, Scanner.LowestPrec);
 }
 
@@ -296,17 +296,17 @@ func (P *Printer) Expr(x *Node.Expr) {
 // ----------------------------------------------------------------------------
 // Statements
 
-func (P *Printer) Stat(s *Node.Stat)
+func (P *Printer) Stat(s *AST.Stat)
 
-func (P *Printer) StatementList(list *Node.List) {
+func (P *Printer) StatementList(list *AST.List) {
        for i, n := 0, list.len(); i < n; i++ {
-               P.Stat(list.at(i).(*Node.Stat));
+               P.Stat(list.at(i).(*AST.Stat));
                P.newl = 1;
        }
 }
 
 
-func (P *Printer) Block(list *Node.List, indent bool) {
+func (P *Printer) Block(list *AST.List, indent bool) {
        P.OpenScope("{");
        if !indent {
                P.indent--;
@@ -319,7 +319,7 @@ func (P *Printer) Block(list *Node.List, indent bool) {
 }
 
 
-func (P *Printer) ControlClause(s *Node.Stat) {
+func (P *Printer) ControlClause(s *AST.Stat) {
        has_post := s.tok == Scanner.FOR && s.post != nil;  // post also used by "if"
        if s.init == nil && !has_post {
                // no semicolons required
@@ -351,9 +351,9 @@ func (P *Printer) ControlClause(s *Node.Stat) {
 }
 
 
-func (P *Printer) Declaration(d *Node.Decl, parenthesized bool);
+func (P *Printer) Declaration(d *AST.Decl, parenthesized bool);
 
-func (P *Printer) Stat(s *Node.Stat) {
+func (P *Printer) Stat(s *AST.Stat) {
        switch s.tok {
        case Scanner.EXPRSTAT:
                // expression statement
@@ -432,7 +432,7 @@ func (P *Printer) Stat(s *Node.Stat) {
 // Declarations
 
 
-func (P *Printer) Declaration(d *Node.Decl, parenthesized bool) {
+func (P *Printer) Declaration(d *AST.Decl, parenthesized bool) {
        if !parenthesized {
                if d.exported {
                        P.String(0, "export ");
@@ -444,7 +444,7 @@ func (P *Printer) Declaration(d *Node.Decl, parenthesized bool) {
        if d.tok != Scanner.FUNC && d.list != nil {
                P.OpenScope("(");
                for i := 0; i < d.list.len(); i++ {
-                       P.Declaration(d.list.at(i).(*Node.Decl), true);
+                       P.Declaration(d.list.at(i).(*AST.Decl), true);
                        P.semi, P.newl = true, 1;
                }
                P.CloseScope(")");
@@ -501,12 +501,12 @@ func (P *Printer) Declaration(d *Node.Decl, parenthesized bool) {
 // ----------------------------------------------------------------------------
 // Program
 
-func (P *Printer) Program(p *Node.Program) {
+func (P *Printer) Program(p *AST.Program) {
        // TODO should initialize all fields?
        P.clist = p.comments;
        P.cindex = 0;
        if p.comments.len() > 0 {
-               P.cpos = p.comments.at(0).(*Node.Comment).pos;
+               P.cpos = p.comments.at(0).(*AST.Comment).pos;
        } else {
                P.cpos = 1000000000;  // infinite
        }
index fcca40d5a7e18513f453747f54ab493b38b9ca09..634094e0b4e6ca33c48618f3e76fe2dab44ebc0c 100644 (file)
@@ -295,6 +295,21 @@ export type Scanner struct {
 // Read the next Unicode char into S.ch.
 // S.ch < 0 means end-of-file.
 func (S *Scanner) Next() {
+       if S.pos < len(S.src) {
+               // assume ascii
+               r, w := int(S.src[S.pos]), 1;
+               if r > 0x80 {
+                       // wasn't ascii
+                       r, w = sys.stringtorune(S.src, S.pos);
+               }
+               S.ch = r;
+               S.chpos = S.pos;
+               S.pos += w;
+       } else {
+               S.ch = -1;  // eof
+               S.chpos = len(S.src);
+       }
+/*
        const (
                Bit1 = 7;
                Bitx = 6;
@@ -389,6 +404,7 @@ bad:
        S.chpos = S.pos;
        S.pos += 1;
        return;
+*/
 }