summaryrefslogtreecommitdiff
path: root/usr/gri/pretty/parser.go
diff options
context:
space:
mode:
Diffstat (limited to 'usr/gri/pretty/parser.go')
-rw-r--r--usr/gri/pretty/parser.go575
1 files changed, 339 insertions, 236 deletions
diff --git a/usr/gri/pretty/parser.go b/usr/gri/pretty/parser.go
index c2af6ce20..0eced7fdb 100644
--- a/usr/gri/pretty/parser.go
+++ b/usr/gri/pretty/parser.go
@@ -29,7 +29,7 @@ type Parser struct {
val string; // token value (for IDENT, NUMBER, STRING only)
// Non-syntactic parser control
- opt_semi bool; // true if semicolon is optional
+ opt_semi bool; // true if semicolon separator is optional in statement list
// Nesting levels
scope_lev int; // 0 = global scope, 1 = function scope of global functions, etc.
@@ -170,6 +170,7 @@ func (P *Parser) closeScope() {
}
+/*
func (P *Parser) declareInScope(scope *SymbolTable.Scope, x AST.Expr, kind int, typ *AST.Type) {
if P.scope_lev < 0 {
panic("cannot declare objects in other packages");
@@ -207,15 +208,16 @@ func (P *Parser) declare(x AST.Expr, kind int, typ *AST.Type) {
}
P.declareInScope(P.top_scope, x, kind, typ);
}
+*/
// ----------------------------------------------------------------------------
// Common productions
-func (P *Parser) tryType() *AST.Type;
+func (P *Parser) tryType() AST.Expr;
func (P *Parser) parseExpression(prec int) AST.Expr;
func (P *Parser) parseStatement() AST.Stat;
-func (P *Parser) parseDeclaration() *AST.Decl;
+func (P *Parser) parseDeclaration() AST.Decl;
// If scope != nil, lookup identifier in scope. Otherwise create one.
@@ -270,10 +272,34 @@ func (P *Parser) parseIdentList(x AST.Expr) AST.Expr {
}
+func (P *Parser) parseIdentList2(x AST.Expr) []*AST.Ident {
+ if P.trace {
+ defer un(trace(P, "IdentList"));
+ }
+
+ list := vector.New(0);
+ if x == nil {
+ x = P.parseIdent(nil);
+ }
+ list.Push(x);
+ for P.tok == Scanner.COMMA {
+ P.next();
+ list.Push(P.parseIdent(nil));
+ }
+
+ // convert vector
+ idents := make([]*AST.Ident, list.Len());
+ for i := 0; i < list.Len(); i++ {
+ idents[i] = list.At(i).(*AST.Ident);
+ }
+ return idents;
+}
+
+
// ----------------------------------------------------------------------------
// Types
-func (P *Parser) parseType() *AST.Type {
+func (P *Parser) parseType() AST.Expr {
if P.trace {
defer un(trace(P, "Type"));
}
@@ -281,14 +307,14 @@ func (P *Parser) parseType() *AST.Type {
t := P.tryType();
if t == nil {
P.error(P.pos, "type expected");
- t = AST.BadType;
+ t = &AST.BadExpr(P.pos);
}
return t;
}
-func (P *Parser) parseVarType() *AST.Type {
+func (P *Parser) parseVarType() AST.Expr {
if P.trace {
defer un(trace(P, "VarType"));
}
@@ -314,88 +340,90 @@ func (P *Parser) parseQualifiedIdent() AST.Expr {
}
-func (P *Parser) parseTypeName() *AST.Type {
+func (P *Parser) parseTypeName() AST.Expr {
if P.trace {
defer un(trace(P, "TypeName"));
}
- t := AST.NewType(P.pos, AST.TYPENAME);
- t.Expr = P.parseQualifiedIdent();
-
- return t;
+ return P.parseQualifiedIdent();
}
-func (P *Parser) parseArrayType() *AST.Type {
+func (P *Parser) parseArrayType() *AST.ArrayType {
if P.trace {
defer un(trace(P, "ArrayType"));
}
- t := AST.NewType(P.pos, AST.ARRAY);
+ pos := P.pos;
P.expect(Scanner.LBRACK);
+ var len AST.Expr;
if P.tok == Scanner.ELLIPSIS {
- t.Expr = &AST.BinaryExpr(P.pos, Scanner.ELLIPSIS, nil, nil);
+ len = &AST.Ellipsis(P.pos);
P.next();
} else if P.tok != Scanner.RBRACK {
- t.Expr = P.parseExpression(1);
+ len = P.parseExpression(1);
}
P.expect(Scanner.RBRACK);
- t.Elt = P.parseType();
+ elt := P.parseType();
- return t;
+ return &AST.ArrayType(pos, len, elt);
}
-func (P *Parser) parseChannelType() *AST.Type {
+func (P *Parser) parseChannelType() *AST.ChannelType {
if P.trace {
defer un(trace(P, "ChannelType"));
}
- t := AST.NewType(P.pos, AST.CHANNEL);
- t.Mode = AST.FULL;
+ pos := P.pos;
+ mode := AST.FULL;
if P.tok == Scanner.CHAN {
P.next();
if P.tok == Scanner.ARROW {
P.next();
- t.Mode = AST.SEND;
+ mode = AST.SEND;
}
} else {
P.expect(Scanner.ARROW);
P.expect(Scanner.CHAN);
- t.Mode = AST.RECV;
+ mode = AST.RECV;
}
- t.Elt = P.parseVarType();
+ val := P.parseVarType();
- return t;
+ return &AST.ChannelType(pos, mode, val);
}
-func (P *Parser) parseVar(expect_ident bool) *AST.Type {
- t := AST.BadType;
- if expect_ident {
- x := P.parseIdent(nil);
- t = AST.NewType(x.Pos(), AST.TYPENAME);
- t.Expr = x;
- } else if P.tok == Scanner.ELLIPSIS {
- t = AST.NewType(P.pos, AST.ELLIPSIS);
+func (P *Parser) tryParameterType() AST.Expr {
+ if P.tok == Scanner.ELLIPSIS {
+ pos := P.tok;
P.next();
- } else {
- t = P.parseType();
+ return &AST.Ellipsis(pos);
}
- return t;
+ return P.tryType();
+}
+
+
+func (P *Parser) parseParameterType() AST.Expr {
+ typ := P.tryParameterType();
+ if typ == nil {
+ P.error(P.tok, "type expected");
+ typ = &AST.BadExpr(P.pos);
+ }
+ return typ;
}
-func (P *Parser) parseVarList(list *vector.Vector, ellipsis_ok bool) {
+func (P *Parser) parseParameterDecl(ellipsis_ok bool) (*vector.Vector, AST.Expr) {
if P.trace {
- defer un(trace(P, "VarList"));
+ defer un(trace(P, "ParameterDecl"));
}
- // assume a list of types
- // (a list of identifiers looks like a list of type names)
- i0 := list.Len();
+ // a list of identifiers looks like a list of type names
+ list := vector.New(0);
for {
- list.Push(P.parseVar(ellipsis_ok /* param list */ && i0 > 0));
+ // TODO do not allow ()'s here
+ list.Push(P.parseParameterType());
if P.tok == Scanner.COMMA {
P.next();
} else {
@@ -404,115 +432,87 @@ func (P *Parser) parseVarList(list *vector.Vector, ellipsis_ok bool) {
}
// if we had a list of identifiers, it must be followed by a type
- typ := P.tryType();
- if typ == nil && P.tok == Scanner.ELLIPSIS {
- typ = AST.NewType(P.pos, AST.ELLIPSIS);
- P.next();
- }
+ typ := P.tryParameterType();
+
+ return list, typ;
+}
- if ellipsis_ok /* param list */ && i0 > 0 && typ == nil {
- // not the first parameter section; we must have a type
- P.error(P.pos, "type expected");
- typ = AST.BadType;
+
+func (P *Parser) parseParameterList(ellipsis_ok bool) []*AST.Field {
+ if P.trace {
+ defer un(trace(P, "ParameterList"));
}
- // convert the list into a list of (type) expressions
+ list, typ := P.parseParameterDecl(false);
if typ != nil {
- // 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).(*AST.Type);
- if t.Form == AST.TYPENAME {
- if ident, ok := t.Expr.(*AST.Ident); ok {
- list.Set(i, ident);
- continue;
- }
- }
- list.Set(i, &AST.BadExpr(0));
- P.error(t.Pos, "identifier expected");
+ // IdentifierList Type
+ // convert list of identifiers into []*Ident
+ idents := make([]*AST.Ident, list.Len());
+ for i := 0; i < list.Len(); i++ {
+ idents[i] = list.At(i).(*AST.Ident);
+ }
+ list.Init(0);
+ list.Push(&AST.Field(idents, typ, nil));
+
+ for P.tok == Scanner.COMMA {
+ P.next();
+ idents := P.parseIdentList2(nil);
+ typ := P.parseParameterType();
+ list.Push(&AST.Field(idents, typ, nil));
}
- // add type
- list.Push(&AST.TypeLit(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).(*AST.Type);
- list.Set(i, &AST.TypeLit(t));
+ // Type { "," Type }
+ // convert list of types into list of *Param
+ for i := 0; i < list.Len(); i++ {
+ list.Set(i, &AST.Field(nil, list.At(i).(AST.Expr), nil));
}
}
-}
-
-func (P *Parser) parseParameterList(ellipsis_ok bool) *vector.Vector {
- if P.trace {
- defer un(trace(P, "ParameterList"));
+ // convert list
+ params := make([]*AST.Field, list.Len());
+ for i := 0; i < list.Len(); i++ {
+ params[i] = list.At(i).(*AST.Field);
}
- list := vector.New(0);
- P.parseVarList(list, ellipsis_ok);
- for P.tok == Scanner.COMMA {
- P.next();
- P.parseVarList(list, ellipsis_ok);
- }
-
- return list;
+ return params;
}
-func (P *Parser) parseParameters(ellipsis_ok bool) *AST.Type {
+// TODO make sure Go spec is updated
+func (P *Parser) parseParameters(ellipsis_ok bool) []*AST.Field {
if P.trace {
defer un(trace(P, "Parameters"));
}
- t := AST.NewType(P.pos, AST.STRUCT);
+ var params []*AST.Field;
P.expect(Scanner.LPAREN);
if P.tok != Scanner.RPAREN {
- t.List = P.parseParameterList(ellipsis_ok);
+ params = P.parseParameterList(ellipsis_ok);
}
- t.End = P.pos;
P.expect(Scanner.RPAREN);
- return t;
+ return params;
}
-func (P *Parser) parseResultList() {
- if P.trace {
- defer un(trace(P, "ResultList"));
- }
-
- P.parseType();
- for P.tok == Scanner.COMMA {
- P.next();
- P.parseType();
- }
- if P.tok != Scanner.RPAREN {
- P.parseType();
- }
-}
-
-
-func (P *Parser) parseResult(ftyp *AST.Type) *AST.Type {
+func (P *Parser) parseResult() []*AST.Field {
if P.trace {
defer un(trace(P, "Result"));
}
- var t *AST.Type;
+ var result []*AST.Field;
if P.tok == Scanner.LPAREN {
- t = P.parseParameters(false);
+ result = P.parseParameters(false);
} else if P.tok != Scanner.FUNC {
typ := P.tryType();
if typ != nil {
- t = AST.NewType(P.pos, AST.STRUCT);
- t.List = vector.New(0);
- t.List.Push(&AST.TypeLit(typ));
- t.End = P.pos;
+ result = make([]*AST.Field, 1);
+ result[0] = &AST.Field(nil, typ, nil);
}
}
- return t;
+ return result;
}
@@ -522,120 +522,189 @@ func (P *Parser) parseResult(ftyp *AST.Type) *AST.Type {
// (params) type
// (params) (results)
-func (P *Parser) parseSignature() *AST.Type {
+func (P *Parser) parseSignature() *AST.Signature {
if P.trace {
defer un(trace(P, "Signature"));
}
- P.openScope();
- P.scope_lev++;
+ //P.openScope();
+ //P.scope_lev++;
- t := AST.NewType(P.pos, AST.FUNCTION);
- t.Scope = P.top_scope;
- t.List = P.parseParameters(true).List; // TODO find better solution
- t.End = P.pos;
- t.Elt = P.parseResult(t);
+ //t.Scope = P.top_scope;
+ params := P.parseParameters(true); // TODO find better solution
+ //t.End = P.pos;
+ result := P.parseResult();
- P.scope_lev--;
- P.closeScope();
+ //P.scope_lev--;
+ //P.closeScope();
- return t;
+ return &AST.Signature(params, result);
}
-func (P *Parser) parseFunctionType() *AST.Type {
+func (P *Parser) parseFunctionType() *AST.FunctionType {
if P.trace {
defer un(trace(P, "FunctionType"));
}
+ pos := P.pos;
P.expect(Scanner.FUNC);
- return P.parseSignature();
+ sig := P.parseSignature();
+
+ return &AST.FunctionType(pos, sig);
}
-func (P *Parser) parseMethodOrInterfaceSpec(list *vector.Vector) {
+func (P *Parser) parseMethodSpec() *AST.Field {
if P.trace {
- defer un(trace(P, "MethodOrInterfaceSpec"));
+ defer un(trace(P, "MethodSpec"));
}
+ var idents []*AST.Ident;
+ var typ AST.Expr;
x := P.parseQualifiedIdent();
if tmp, is_ident := x.(*AST.Ident); is_ident && (P.tok == Scanner.COMMA || P.tok == Scanner.LPAREN) {
// method(s)
- list.Push(P.parseIdentList(x));
- list.Push(&AST.TypeLit(P.parseSignature()));
+ idents = P.parseIdentList2(x);
+ typ = &AST.FunctionType(0, P.parseSignature());
} else {
// embedded interface
- list.Push(x);
+ typ = x;
}
+
+ return &AST.Field(idents, typ, nil);
}
-func (P *Parser) parseInterfaceType() *AST.Type {
+func (P *Parser) parseInterfaceType() *AST.InterfaceType {
if P.trace {
defer un(trace(P, "InterfaceType"));
}
- t := AST.NewType(P.pos, AST.INTERFACE);
+ pos := P.pos;
+ end := 0;
+ var methods []*AST.Field;
+
P.expect(Scanner.INTERFACE);
if P.tok == Scanner.LBRACE {
P.next();
- P.openScope();
- P.scope_lev++;
+ //P.openScope();
+ //P.scope_lev++;
- t.List = vector.New(0);
+ list := vector.New(0);
for P.tok == Scanner.IDENT {
- P.parseMethodOrInterfaceSpec(t.List);
+ list.Push(P.parseMethodSpec());
if P.tok != Scanner.RBRACE {
P.expect(Scanner.SEMICOLON);
}
}
- t.End = P.pos;
+ //t.End = P.pos;
- P.scope_lev--;
- P.closeScope();
+ //P.scope_lev--;
+ //P.closeScope();
+ end = P.pos;
P.expect(Scanner.RBRACE);
+ P.opt_semi = true;
+
+ // convert vector
+ methods = make([]*AST.Field, list.Len());
+ for i := list.Len() - 1; i >= 0; i-- {
+ methods[i] = list.At(i).(*AST.Field);
+ }
}
- return t;
+ return &AST.InterfaceType(pos, methods, end);
}
-func (P *Parser) parseMapType() *AST.Type {
+func (P *Parser) parseMapType() *AST.MapType {
if P.trace {
defer un(trace(P, "MapType"));
}
- t := AST.NewType(P.pos, AST.MAP);
+ pos := P.pos;
P.expect(Scanner.MAP);
P.expect(Scanner.LBRACK);
- t.Key = P.parseVarType();
+ key := P.parseVarType();
P.expect(Scanner.RBRACK);
- t.Elt = P.parseVarType();
+ val := P.parseVarType();
- return t;
+ return &AST.MapType(pos, key, val);
}
func (P *Parser) parseOperand() AST.Expr
-func (P *Parser) parseStructType() *AST.Type {
+
+func (P *Parser) parseFieldDecl() *AST.Field {
+ if P.trace {
+ defer un(trace(P, "FieldDecl"));
+ }
+
+ // a list of identifiers looks like a list of type names
+ list := vector.New(0);
+ for {
+ // TODO do not allow ()'s here
+ list.Push(P.parseType());
+ if P.tok == Scanner.COMMA {
+ P.next();
+ } else {
+ break;
+ }
+ }
+
+ // if we had a list of identifiers, it must be followed by a type
+ typ := P.tryType();
+
+ // optional tag
+ var tag AST.Expr;
+ if P.tok == Scanner.STRING {
+ // ParseOperand takes care of string concatenation
+ tag = P.parseOperand();
+ }
+
+ // analyze case
+ var idents []*AST.Ident;
+ if typ != nil {
+ // non-empty identifier list followed by a type
+ idents = make([]*AST.Ident, list.Len());
+ for i := 0; i < list.Len(); i++ {
+ if ident, is_ident := list.At(i).(*AST.Ident); is_ident {
+ idents[i] = ident;
+ } else {
+ P.error(list.At(i).(AST.Expr).Pos(), "identifier expected");
+ }
+ }
+ } else {
+ // anonymous field
+ if list.Len() == 1 {
+ // TODO should do more checks here
+ typ = list.At(0).(AST.Expr);
+ } else {
+ P.error(P.pos, "anonymous field expected");
+ }
+ }
+
+ return &AST.Field(idents, typ, tag);
+}
+
+
+func (P *Parser) parseStructType() AST.Expr {
if P.trace {
defer un(trace(P, "StructType"));
}
- t := AST.NewType(P.pos, AST.STRUCT);
+ pos := P.pos;
+ end := 0;
+ var fields []*AST.Field;
+
P.expect(Scanner.STRUCT);
if P.tok == Scanner.LBRACE {
P.next();
- t.List = vector.New(0);
- t.Scope = SymbolTable.NewScope(nil);
+ list := vector.New(0);
for P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
- P.parseVarList(t.List, false);
- if P.tok == Scanner.STRING {
- // ParseOperand takes care of string concatenation
- t.List.Push(P.parseOperand());
- }
+ list.Push(P.parseFieldDecl());
if P.tok == Scanner.SEMICOLON {
P.next();
} else {
@@ -643,36 +712,36 @@ func (P *Parser) parseStructType() *AST.Type {
}
}
P.OptSemicolon();
- t.End = P.pos;
+ end = P.pos;
P.expect(Scanner.RBRACE);
+ P.opt_semi = true;
- // enter fields into struct scope
- for i, n := 0, t.List.Len(); i < n; i++ {
- if x, ok := t.List.At(i).(*AST.Ident); ok {
- P.declareInScope(t.Scope, x, SymbolTable.FIELD, nil);
- }
+ // convert vector
+ fields = make([]*AST.Field, list.Len());
+ for i := list.Len() - 1; i >= 0; i-- {
+ fields[i] = list.At(i).(*AST.Field);
}
}
- return t;
+ return AST.StructType(pos, fields, end);
}
-func (P *Parser) parsePointerType() *AST.Type {
+func (P *Parser) parsePointerType() AST.Expr {
if P.trace {
defer un(trace(P, "PointerType"));
}
- t := AST.NewType(P.pos, AST.POINTER);
+ pos := P.pos;
P.expect(Scanner.MUL);
- t.Elt = P.parseType();
+ base := P.parseType();
- return t;
+ return &AST.PointerType(pos, base);
}
-func (P *Parser) tryType() *AST.Type {
+func (P *Parser) tryType() AST.Expr {
if P.trace {
defer un(trace(P, "Type (try)"));
}
@@ -687,10 +756,11 @@ func (P *Parser) tryType() *AST.Type {
case Scanner.STRUCT: return P.parseStructType();
case Scanner.MUL: return P.parsePointerType();
case Scanner.LPAREN:
+ pos := P.pos;
P.next();
t := P.parseType();
P.expect(Scanner.RPAREN);
- return t;
+ return &AST.Group(pos, t);
}
// no type found
@@ -725,7 +795,7 @@ func (P *Parser) parseStatementList(list *vector.Vector) {
}
-func (P *Parser) parseBlock(ftyp *AST.Type, tok int) *AST.Block {
+func (P *Parser) parseBlock(tok int) *AST.Block {
if P.trace {
defer un(trace(P, "Block"));
}
@@ -733,6 +803,7 @@ func (P *Parser) parseBlock(ftyp *AST.Type, tok int) *AST.Block {
b := AST.NewBlock(P.pos, tok);
P.expect(tok);
+ /*
P.openScope();
// enter recv and parameters into function scope
if ftyp != nil {
@@ -747,9 +818,13 @@ func (P *Parser) parseBlock(ftyp *AST.Type, tok int) *AST.Block {
}
}
}
-
+ */
+
P.parseStatementList(b.List);
+
+ /*
P.closeScope();
+ */
if tok == Scanner.LBRACE {
b.End = P.pos;
@@ -795,7 +870,7 @@ func (P *Parser) parseFunctionLit() AST.Expr {
P.expect(Scanner.FUNC);
typ := P.parseSignature();
P.scope_lev++;
- body := P.parseBlock(typ, Scanner.LBRACE);
+ body := P.parseBlock(Scanner.LBRACE);
P.scope_lev--;
return &AST.FunctionLit(pos, typ, body);
@@ -812,10 +887,11 @@ func (P *Parser) parseOperand() AST.Expr {
return P.parseIdent(P.top_scope);
case Scanner.LPAREN:
+ pos := P.pos;
P.next();
x := P.parseExpression(1);
P.expect(Scanner.RPAREN);
- return x;
+ return &AST.Group(pos, x);
case Scanner.INT, Scanner.FLOAT, Scanner.STRING:
x := &AST.BasicLit(P.pos, P.tok, P.val);
@@ -835,7 +911,7 @@ func (P *Parser) parseOperand() AST.Expr {
default:
t := P.tryType();
if t != nil {
- return &AST.TypeLit(t);
+ return t;
} else {
P.error(P.pos, "operand expected");
P.next(); // make progress
@@ -978,6 +1054,8 @@ func (P *Parser) parseUnaryExpr() AST.Expr {
pos, tok := P.pos, P.tok;
P.next();
y := P.parseUnaryExpr();
+ return &AST.UnaryExpr(pos, tok, y);
+ /*
if lit, ok := y.(*AST.TypeLit); ok && tok == Scanner.MUL {
// pointer type
t := AST.NewType(pos, AST.POINTER);
@@ -986,6 +1064,7 @@ func (P *Parser) parseUnaryExpr() AST.Expr {
} else {
return &AST.UnaryExpr(pos, tok, y);
}
+ */
}
return P.parsePrimaryExpr();
@@ -1180,7 +1259,7 @@ func (P *Parser) parseIfStat() *AST.IfStat {
pos := P.pos;
P.expect(Scanner.IF);
init, cond, dummy := P.parseControlClause(false);
- body := P.parseBlock(nil, Scanner.LBRACE);
+ body := P.parseBlock(Scanner.LBRACE);
var else_ AST.Stat;
if P.tok == Scanner.ELSE {
P.next();
@@ -1211,7 +1290,7 @@ func (P *Parser) parseForStat() *AST.ForStat {
pos := P.pos;
P.expect(Scanner.FOR);
init, cond, post := P.parseControlClause(true);
- body := P.parseBlock(nil, Scanner.LBRACE);
+ body := P.parseBlock(Scanner.LBRACE);
P.closeScope();
return &AST.ForStat(pos, init, cond, post, body);
@@ -1233,7 +1312,7 @@ func (P *Parser) parseCaseClause() *AST.CaseClause {
P.expect(Scanner.DEFAULT);
}
- return &AST.CaseClause(pos, expr, P.parseBlock(nil, Scanner.COLON));
+ return &AST.CaseClause(pos, expr, P.parseBlock(Scanner.COLON));
}
@@ -1286,7 +1365,7 @@ func (P *Parser) parseCommClause() *AST.CaseClause {
P.expect(Scanner.DEFAULT);
}
- return &AST.CaseClause(pos, expr, P.parseBlock(nil, Scanner.COLON));
+ return &AST.CaseClause(pos, expr, P.parseBlock(Scanner.COLON));
}
@@ -1337,7 +1416,7 @@ func (P *Parser) parseStatement() AST.Stat {
case Scanner.BREAK, Scanner.CONTINUE, Scanner.GOTO, Scanner.FALLTHROUGH:
return P.parseControlFlowStat(P.tok);
case Scanner.LBRACE:
- return &AST.CompositeStat(P.parseBlock(nil, Scanner.LBRACE));
+ return &AST.CompositeStat(P.parseBlock(Scanner.LBRACE));
case Scanner.IF:
return P.parseIfStat();
case Scanner.FOR:
@@ -1360,90 +1439,105 @@ func (P *Parser) parseStatement() AST.Stat {
// ----------------------------------------------------------------------------
// Declarations
-func (P *Parser) parseImportSpec(d *AST.Decl) {
+func (P *Parser) parseImportSpec(pos int) *AST.ImportDecl {
if P.trace {
defer un(trace(P, "ImportSpec"));
}
+ var ident *AST.Ident;
if P.tok == Scanner.PERIOD {
P.error(P.pos, `"import ." not yet handled properly`);
P.next();
} else if P.tok == Scanner.IDENT {
- d.Ident = P.parseIdent(nil);
+ ident = P.parseIdent(nil);
}
+ var path AST.Expr;
if P.tok == Scanner.STRING {
// TODO eventually the scanner should strip the quotes
- d.Val = &AST.BasicLit(P.pos, Scanner.STRING, P.val);
+ path = &AST.BasicLit(P.pos, Scanner.STRING, P.val);
P.next();
} else {
P.expect(Scanner.STRING); // use expect() error handling
}
+
+ return &AST.ImportDecl(pos, ident, path);
}
-func (P *Parser) parseConstSpec(d *AST.Decl) {
+func (P *Parser) parseConstSpec(pos int) *AST.ConstDecl {
if P.trace {
defer un(trace(P, "ConstSpec"));
}
- d.Ident = P.parseIdentList(nil);
- d.Typ = P.tryType();
+ idents := P.parseIdentList2(nil);
+ typ := P.tryType();
+ var vals AST.Expr;
if P.tok == Scanner.ASSIGN {
P.next();
- d.Val = P.parseExpressionList();
+ vals = P.parseExpressionList();
}
+
+ return &AST.ConstDecl(pos, idents, typ, vals);
}
-func (P *Parser) parseTypeSpec(d *AST.Decl) {
+func (P *Parser) parseTypeSpec(pos int) *AST.TypeDecl {
if P.trace {
defer un(trace(P, "TypeSpec"));
}
- d.Ident = P.parseIdent(nil);
- d.Typ = P.parseType();
- P.opt_semi = true;
+ ident := P.parseIdent(nil);
+ typ := P.parseType();
+
+ return &AST.TypeDecl(pos, ident, typ);
}
-func (P *Parser) parseVarSpec(d *AST.Decl) {
+func (P *Parser) parseVarSpec(pos int) *AST.VarDecl {
if P.trace {
defer un(trace(P, "VarSpec"));
}
- d.Ident = P.parseIdentList(nil);
+ idents := P.parseIdentList2(nil);
+ var typ AST.Expr;
+ var vals AST.Expr;
if P.tok == Scanner.ASSIGN {
P.next();
- d.Val = P.parseExpressionList();
+ vals = P.parseExpressionList();
} else {
- d.Typ = P.parseVarType();
+ typ = P.parseVarType();
if P.tok == Scanner.ASSIGN {
P.next();
- d.Val = P.parseExpressionList();
+ vals = P.parseExpressionList();
}
}
+
+ return &AST.VarDecl(pos, idents, typ, vals);
}
-func (P *Parser) parseSpec(d *AST.Decl) {
+func (P *Parser) parseSpec(pos, keyword int) AST.Decl {
kind := SymbolTable.NONE;
- switch d.Tok {
- case Scanner.IMPORT: P.parseImportSpec(d); kind = SymbolTable.PACKAGE;
- case Scanner.CONST: P.parseConstSpec(d); kind = SymbolTable.CONST;
- case Scanner.TYPE: P.parseTypeSpec(d); kind = SymbolTable.TYPE;
- case Scanner.VAR: P.parseVarSpec(d); kind = SymbolTable.VAR;
- default: unreachable();
+ switch keyword {
+ case Scanner.IMPORT: return P.parseImportSpec(pos);
+ case Scanner.CONST: return P.parseConstSpec(pos);
+ case Scanner.TYPE: return P.parseTypeSpec(pos);
+ case Scanner.VAR: return P.parseVarSpec(pos);
}
+
+ unreachable();
+ return nil;
+ /*
// semantic checks
if d.Tok == Scanner.IMPORT {
if d.Ident != nil {
- P.declare(d.Ident, kind, nil);
+ //P.declare(d.Ident, kind, nil);
}
} else {
- P.declare(d.Ident, kind, d.Typ);
+ //P.declare(d.Ident, kind, d.Typ);
if d.Val != nil {
// initialization/assignment
llen := AST.ExprLen(d.Ident);
@@ -1463,38 +1557,42 @@ func (P *Parser) parseSpec(d *AST.Decl) {
// TODO
}
}
+ */
}
-func (P *Parser) parseDecl(keyword int) *AST.Decl {
+func (P *Parser) parseDecl(keyword int) AST.Decl {
if P.trace {
defer un(trace(P, "Decl"));
}
- d := AST.NewDecl(P.pos, keyword);
+ pos := P.pos;
P.expect(keyword);
if P.tok == Scanner.LPAREN {
P.next();
- d.List = vector.New(0);
+ list := vector.New(0);
for P.tok != Scanner.RPAREN && P.tok != Scanner.EOF {
- d1 := AST.NewDecl(P.pos, keyword);
- P.parseSpec(d1);
- d.List.Push(d1);
+ list.Push(P.parseSpec(0, keyword));
if P.tok == Scanner.SEMICOLON {
P.next();
} else {
break;
}
}
- d.End = P.pos;
+ end := P.pos;
P.expect(Scanner.RPAREN);
P.opt_semi = true;
-
- } else {
- P.parseSpec(d);
+
+ // convert vector
+ decls := make([]AST.Decl, list.Len());
+ for i := 0; i < list.Len(); i++ {
+ decls[i] = list.At(i).(AST.Decl);
+ }
+
+ return &AST.DeclList(pos, keyword, decls, end);
}
- return d;
+ return P.parseSpec(pos, keyword);
}
@@ -1507,54 +1605,53 @@ func (P *Parser) parseDecl(keyword int) *AST.Decl {
// func (recv) ident (params) type
// func (recv) ident (params) (results)
-func (P *Parser) parseFunctionDecl() *AST.Decl {
+func (P *Parser) parseFunctionDecl() *AST.FuncDecl {
if P.trace {
defer un(trace(P, "FunctionDecl"));
}
- d := AST.NewDecl(P.pos, Scanner.FUNC);
+ pos := P.pos;
P.expect(Scanner.FUNC);
- var recv *AST.Type;
+ var recv *AST.Field;
if P.tok == Scanner.LPAREN {
pos := P.pos;
- recv = P.parseParameters(true);
- if recv.Nfields() != 1 {
+ tmp := P.parseParameters(true);
+ if len(tmp) == 1 {
+ recv = tmp[0];
+ } else {
P.error(pos, "must have exactly one receiver");
}
}
ident := P.parseIdent(nil);
- d.Ident = ident;
- d.Typ = P.parseSignature();
- d.Typ.Key = recv;
+ sig := P.parseSignature();
+ var body *AST.Block;
if P.tok == Scanner.LBRACE {
- d.Body = P.parseBlock(d.Typ, Scanner.LBRACE);
+ body = P.parseBlock(Scanner.LBRACE);
}
- return d;
+ return &AST.FuncDecl(pos, recv, ident, sig, body);
}
-func (P *Parser) parseDeclaration() *AST.Decl {
+func (P *Parser) parseDeclaration() AST.Decl {
if P.trace {
defer un(trace(P, "Declaration"));
}
- d := AST.BadDecl;
-
switch P.tok {
case Scanner.CONST, Scanner.TYPE, Scanner.VAR:
- d = P.parseDecl(P.tok);
+ return P.parseDecl(P.tok);
case Scanner.FUNC:
- d = P.parseFunctionDecl();
- default:
- P.error(P.pos, "declaration expected");
- P.next(); // make progress
+ return P.parseFunctionDecl();
}
-
- return d;
+
+ pos := P.pos;
+ P.error(pos, "declaration expected");
+ P.next(); // make progress
+ return &AST.BadDecl(pos);
}
@@ -1573,18 +1670,24 @@ func (P *Parser) ParseProgram() *AST.Program {
// package body
{ P.openScope();
- p.Decls = vector.New(0);
+ list := vector.New(0);
for P.tok == Scanner.IMPORT {
- p.Decls.Push(P.parseDecl(Scanner.IMPORT));
+ list.Push(P.parseDecl(Scanner.IMPORT));
P.OptSemicolon();
}
if !P.deps {
for P.tok != Scanner.EOF {
- p.Decls.Push(P.parseDeclaration());
+ list.Push(P.parseDeclaration());
P.OptSemicolon();
}
}
P.closeScope();
+
+ // convert list
+ p.Decls = make([]AST.Decl, list.Len());
+ for i := 0; i < list.Len(); i++ {
+ p.Decls[i] = list.At(i).(AST.Decl);
+ }
}
p.Comments = P.comments;