summaryrefslogtreecommitdiff
path: root/usr/gri/pretty/parser.go
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2009-01-23 13:50:14 -0800
committerRobert Griesemer <gri@golang.org>2009-01-23 13:50:14 -0800
commit570c88d37bc1dac66a9aac157295fb156bb3983b (patch)
tree74ae3764ec0a9531e354e85110633301aa4ac012 /usr/gri/pretty/parser.go
parent79b4e2caa79f4133788adbe79013d0b2ecc66984 (diff)
downloadgolang-570c88d37bc1dac66a9aac157295fb156bb3983b.tar.gz
- snapshot before making larger change
R=r OCL=23403 CL=23403
Diffstat (limited to 'usr/gri/pretty/parser.go')
-rw-r--r--usr/gri/pretty/parser.go56
1 files changed, 29 insertions, 27 deletions
diff --git a/usr/gri/pretty/parser.go b/usr/gri/pretty/parser.go
index fbea1fcda..fc20c2fbe 100644
--- a/usr/gri/pretty/parser.go
+++ b/usr/gri/pretty/parser.go
@@ -5,6 +5,7 @@
package Parser
import (
+ "fmt";
"array";
Scanner "scanner";
AST "ast";
@@ -170,7 +171,7 @@ func (P *Parser) CloseScope() {
}
-func (P *Parser) DeclareInScope(scope *AST.Scope, x *AST.Expr, kind int) {
+func (P *Parser) DeclareInScope(scope *AST.Scope, x *AST.Expr, kind int, typ *AST.Type) {
if P.scope_lev < 0 {
panic("cannot declare objects in other packages");
}
@@ -178,10 +179,16 @@ func (P *Parser) DeclareInScope(scope *AST.Scope, x *AST.Expr, kind int) {
assert(x.Tok == Scanner.IDENT);
obj := x.Obj;
obj.Kind = kind;
+ obj.Typ = typ;
obj.Pnolev = P.scope_lev;
- if scope.LookupLocal(obj.Ident) == nil {
+ switch {
+ case scope.LookupLocal(obj.Ident) == nil:
scope.Insert(obj);
- } else {
+ case kind == AST.TYPE:
+ // possibly a forward declaration
+ case kind == AST.FUNC:
+ // possibly a forward declaration
+ default:
P.Error(obj.Pos, `"` + obj.Ident + `" is declared already`);
}
}
@@ -189,12 +196,12 @@ func (P *Parser) DeclareInScope(scope *AST.Scope, x *AST.Expr, kind int) {
// Declare a comma-separated list of idents or a single ident.
-func (P *Parser) Declare(p *AST.Expr, kind int) {
+func (P *Parser) Declare(p *AST.Expr, kind int, typ *AST.Type) {
for p.Tok == Scanner.COMMA {
- P.DeclareInScope(P.top_scope, p.X, kind);
+ P.DeclareInScope(P.top_scope, p.X, kind, typ);
p = p.Y;
}
- P.DeclareInScope(P.top_scope, p, kind);
+ P.DeclareInScope(P.top_scope, p, kind, typ);
}
@@ -344,6 +351,7 @@ func (P *Parser) ParseTypeName() *AST.Type {
t := AST.NewType(P.pos, AST.TYPENAME);
t.Expr = P.ParseQualifiedIdent();
+ t.Elt = t.Expr.Typ;
P.Ecart();
return t;
@@ -652,7 +660,7 @@ func (P *Parser) ParseStructType() *AST.Type {
for i, n := 0, t.List.Len(); i < n; i++ {
x := t.List.At(i).(*AST.Expr);
if x.Tok == Scanner.IDENT {
- P.DeclareInScope(t.Scope, x, AST.FIELD);
+ P.DeclareInScope(t.Scope, x, AST.FIELD, nil);
}
}
}
@@ -741,7 +749,7 @@ func (P *Parser) ParseBlock(ftyp *AST.Type, tok int) *AST.Block {
for i, n := 0, ftyp.List.Len(); i < n; i++ {
x := ftyp.List.At(i).(*AST.Expr);
if x.Tok == Scanner.IDENT {
- P.DeclareInScope(P.top_scope, x, AST.VAR);
+ P.DeclareInScope(P.top_scope, x, AST.VAR, nil);
}
}
}
@@ -858,8 +866,8 @@ func (P *Parser) ParseSelectorOrTypeGuard(x *AST.Expr) *AST.Expr {
if P.tok == Scanner.IDENT {
// TODO should always guarantee x.Typ != nil
var scope *AST.Scope;
- if x.Typ != nil {
- scope = x.Typ.Scope;
+ if x.X.Typ != nil {
+ scope = x.X.Typ.Scope;
}
x.Y = P.ParseIdent(scope);
x.Typ = x.Y.Obj.Typ;
@@ -1478,10 +1486,6 @@ func (P *Parser) ParseImportSpec(d *AST.Decl) {
P.Expect(Scanner.STRING); // use Expect() error handling
}
- if d.Ident != nil {
- P.Declare(d.Ident, AST.PACKAGE);
- }
-
P.Ecart();
}
@@ -1496,8 +1500,6 @@ func (P *Parser) ParseConstSpec(d *AST.Decl) {
d.Val = P.ParseExpressionList();
}
- P.Declare(d.Ident, AST.CONST);
-
P.Ecart();
}
@@ -1528,28 +1530,28 @@ func (P *Parser) ParseVarSpec(d *AST.Decl) {
}
}
- P.Declare(d.Ident, AST.VAR);
-
P.Ecart();
}
func (P *Parser) ParseSpec(d *AST.Decl) {
+ kind := AST.NONE;
+
switch d.Tok {
- case Scanner.IMPORT: P.ParseImportSpec(d);
- case Scanner.CONST: P.ParseConstSpec(d);
- case Scanner.TYPE: P.ParseTypeSpec(d);
- case Scanner.VAR: P.ParseVarSpec(d);
+ case Scanner.IMPORT: P.ParseImportSpec(d); kind = AST.PACKAGE;
+ case Scanner.CONST: P.ParseConstSpec(d); kind = AST.CONST;
+ case Scanner.TYPE: P.ParseTypeSpec(d); kind = AST.TYPE;
+ case Scanner.VAR: P.ParseVarSpec(d); kind = AST.VAR;
default: unreachable();
}
-
+
// semantic checks
if d.Tok == Scanner.IMPORT {
- // TODO
- } else {
- if d.Typ != nil {
- // apply type to all variables
+ if d.Ident != nil {
+ P.Declare(d.Ident, kind, nil);
}
+ } else {
+ P.Declare(d.Ident, kind, d.Typ);
if d.Val != nil {
// initialization/assignment
llen := d.Ident.Len();