Commit 88da39fe authored by Robert Griesemer's avatar Robert Griesemer

- snapshot before making larger change

R=r
OCL=23403
CL=23403
parent 1b3299ed
...@@ -17,6 +17,7 @@ type ( ...@@ -17,6 +17,7 @@ type (
Type struct; Type struct;
Block struct; Block struct;
Lit struct;
Expr struct; Expr struct;
Stat struct; Stat struct;
Decl struct; Decl struct;
...@@ -88,6 +89,18 @@ func (obj *Object) IsExported() bool { ...@@ -88,6 +89,18 @@ func (obj *Object) IsExported() bool {
} }
func (obj* Object) String() string {
if obj != nil {
return
"Object(" +
KindStr(obj.Kind) + ", " +
obj.Ident +
")";
}
return "nil";
}
var Universe_void_typ *Type // initialized by Universe to Universe.void_typ var Universe_void_typ *Type // initialized by Universe to Universe.void_typ
var objectId int; var objectId int;
...@@ -99,13 +112,42 @@ func NewObject(pos, kind int, ident string) *Object { ...@@ -99,13 +112,42 @@ func NewObject(pos, kind int, ident string) *Object {
obj.Pos = pos; obj.Pos = pos;
obj.Kind = kind; obj.Kind = kind;
obj.Ident = ident; obj.Ident = ident;
obj.Typ = Universe_void_typ; obj.Typ = Universe_void_typ; // TODO would it be better to use nil instead?
obj.Pnolev = 0; obj.Pnolev = 0;
return obj; return obj;
} }
// ----------------------------------------------------------------------------
// All nodes have a source position and a token.
type Node struct {
Pos int; // source position (< 0 => unknown position)
Tok int; // identifying token
}
// ----------------------------------------------------------------------------
// Literals
type Lit struct {
Node;
// Identifiers
Obj *Object;
// Constant literals
// Type literals
Len *Expr; // array length
Dir int; // channel direction
Key *Type; // receiver or map key type
Elt *Type; // array, map, channel, pointer element, or function result type
List *array.Array; End int; // struct fields, interface methods, function parameters
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Scopes // Scopes
...@@ -176,15 +218,6 @@ func (scope *Scope) Print() { ...@@ -176,15 +218,6 @@ func (scope *Scope) Print() {
} }
// ----------------------------------------------------------------------------
// All nodes have a source position and and token.
type Node struct {
Pos int; // source position (< 0 => unknown position)
Tok int; // identifying token
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Blocks // Blocks
// //
...@@ -258,7 +291,7 @@ func NewExpr(pos, tok int, x, y *Expr) *Expr { ...@@ -258,7 +291,7 @@ func NewExpr(pos, tok int, x, y *Expr) *Expr {
// TODO probably don't need the tok parameter eventually // TODO probably don't need the tok parameter eventually
func NewLit(tok int, obj *Object) *Expr { func NewLit(tok int, obj *Object) *Expr {
e := new(Expr); e := new(Expr);
e.Pos, e.Tok, e.Obj = obj.Pos, tok, obj; e.Pos, e.Tok, e.Obj, e.Typ = obj.Pos, tok, obj, obj.Typ;
return e; return e;
} }
...@@ -350,7 +383,7 @@ type Type struct { ...@@ -350,7 +383,7 @@ type Type struct {
Ref int; // for exporting only: >= 0 means already exported Ref int; // for exporting only: >= 0 means already exported
Form int; // type form Form int; // type form
Size int; // size in bytes Size int; // size in bytes
Obj *Object; // primary type object or NULL Obj *Object; // primary type object or nil
Scope *Scope; // locals, fields & methods Scope *Scope; // locals, fields & methods
// syntactic components // syntactic components
...@@ -358,7 +391,7 @@ type Type struct { ...@@ -358,7 +391,7 @@ type Type struct {
Expr *Expr; // type name, array length Expr *Expr; // type name, array length
Mode int; // channel mode Mode int; // channel mode
Key *Type; // receiver type or map key Key *Type; // receiver type or map key
Elt *Type; // array, map, channel or pointer element type, function result type Elt *Type; // type name type, array, map, channel or pointer element type, function result type
List *array.Array; End int; // struct fields, interface methods, function parameters List *array.Array; End int; // struct fields, interface methods, function parameters
} }
...@@ -397,6 +430,17 @@ func (t *Type) Nfields() int { ...@@ -397,6 +430,17 @@ func (t *Type) Nfields() int {
} }
func (typ* Type) String() string {
if typ != nil {
return
"Type(" +
FormStr(typ.Form) +
")";
}
return "nil";
}
// requires complete Type.Pos access // requires complete Type.Pos access
func NewTypeExpr(typ *Type) *Expr { func NewTypeExpr(typ *Type) *Expr {
e := new(Expr); e := new(Expr);
...@@ -405,6 +449,22 @@ func NewTypeExpr(typ *Type) *Expr { ...@@ -405,6 +449,22 @@ func NewTypeExpr(typ *Type) *Expr {
} }
// requires complete Type.String access
func (x *Expr) String() string {
if x != nil {
return
"Expr(" +
Scanner.TokenString(x.Tok) + ", " +
x.X.String() + ", " +
x.Y.String() + ", " +
x.Obj.String() + ", " +
x.Typ.String() +
")";
}
return "nil";
}
var BadType = NewType(0, Scanner.ILLEGAL); var BadType = NewType(0, Scanner.ILLEGAL);
...@@ -416,7 +476,7 @@ type Stat struct { ...@@ -416,7 +476,7 @@ type Stat struct {
Init, Post *Stat; Init, Post *Stat;
Expr *Expr; Expr *Expr;
Body *Block; // composite statement body Body *Block; // composite statement body
Decl *Decl; Decl *Decl; // declaration statement
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package Parser package Parser
import ( import (
"fmt";
"array"; "array";
Scanner "scanner"; Scanner "scanner";
AST "ast"; AST "ast";
...@@ -170,7 +171,7 @@ func (P *Parser) CloseScope() { ...@@ -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 { if P.scope_lev < 0 {
panic("cannot declare objects in other packages"); panic("cannot declare objects in other packages");
} }
...@@ -178,10 +179,16 @@ func (P *Parser) DeclareInScope(scope *AST.Scope, x *AST.Expr, kind int) { ...@@ -178,10 +179,16 @@ func (P *Parser) DeclareInScope(scope *AST.Scope, x *AST.Expr, kind int) {
assert(x.Tok == Scanner.IDENT); assert(x.Tok == Scanner.IDENT);
obj := x.Obj; obj := x.Obj;
obj.Kind = kind; obj.Kind = kind;
obj.Typ = typ;
obj.Pnolev = P.scope_lev; obj.Pnolev = P.scope_lev;
if scope.LookupLocal(obj.Ident) == nil { switch {
case scope.LookupLocal(obj.Ident) == nil:
scope.Insert(obj); 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`); 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) { ...@@ -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. // 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 { 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 = 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 { ...@@ -344,6 +351,7 @@ func (P *Parser) ParseTypeName() *AST.Type {
t := AST.NewType(P.pos, AST.TYPENAME); t := AST.NewType(P.pos, AST.TYPENAME);
t.Expr = P.ParseQualifiedIdent(); t.Expr = P.ParseQualifiedIdent();
t.Elt = t.Expr.Typ;
P.Ecart(); P.Ecart();
return t; return t;
...@@ -652,7 +660,7 @@ func (P *Parser) ParseStructType() *AST.Type { ...@@ -652,7 +660,7 @@ func (P *Parser) ParseStructType() *AST.Type {
for i, n := 0, t.List.Len(); i < n; i++ { for i, n := 0, t.List.Len(); i < n; i++ {
x := t.List.At(i).(*AST.Expr); x := t.List.At(i).(*AST.Expr);
if x.Tok == Scanner.IDENT { 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 { ...@@ -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++ { for i, n := 0, ftyp.List.Len(); i < n; i++ {
x := ftyp.List.At(i).(*AST.Expr); x := ftyp.List.At(i).(*AST.Expr);
if x.Tok == Scanner.IDENT { 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 { ...@@ -858,8 +866,8 @@ func (P *Parser) ParseSelectorOrTypeGuard(x *AST.Expr) *AST.Expr {
if P.tok == Scanner.IDENT { if P.tok == Scanner.IDENT {
// TODO should always guarantee x.Typ != nil // TODO should always guarantee x.Typ != nil
var scope *AST.Scope; var scope *AST.Scope;
if x.Typ != nil { if x.X.Typ != nil {
scope = x.Typ.Scope; scope = x.X.Typ.Scope;
} }
x.Y = P.ParseIdent(scope); x.Y = P.ParseIdent(scope);
x.Typ = x.Y.Obj.Typ; x.Typ = x.Y.Obj.Typ;
...@@ -1478,10 +1486,6 @@ func (P *Parser) ParseImportSpec(d *AST.Decl) { ...@@ -1478,10 +1486,6 @@ func (P *Parser) ParseImportSpec(d *AST.Decl) {
P.Expect(Scanner.STRING); // use Expect() error handling P.Expect(Scanner.STRING); // use Expect() error handling
} }
if d.Ident != nil {
P.Declare(d.Ident, AST.PACKAGE);
}
P.Ecart(); P.Ecart();
} }
...@@ -1496,8 +1500,6 @@ func (P *Parser) ParseConstSpec(d *AST.Decl) { ...@@ -1496,8 +1500,6 @@ func (P *Parser) ParseConstSpec(d *AST.Decl) {
d.Val = P.ParseExpressionList(); d.Val = P.ParseExpressionList();
} }
P.Declare(d.Ident, AST.CONST);
P.Ecart(); P.Ecart();
} }
...@@ -1528,28 +1530,28 @@ func (P *Parser) ParseVarSpec(d *AST.Decl) { ...@@ -1528,28 +1530,28 @@ func (P *Parser) ParseVarSpec(d *AST.Decl) {
} }
} }
P.Declare(d.Ident, AST.VAR);
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParseSpec(d *AST.Decl) { func (P *Parser) ParseSpec(d *AST.Decl) {
kind := AST.NONE;
switch d.Tok { switch d.Tok {
case Scanner.IMPORT: P.ParseImportSpec(d); case Scanner.IMPORT: P.ParseImportSpec(d); kind = AST.PACKAGE;
case Scanner.CONST: P.ParseConstSpec(d); case Scanner.CONST: P.ParseConstSpec(d); kind = AST.CONST;
case Scanner.TYPE: P.ParseTypeSpec(d); case Scanner.TYPE: P.ParseTypeSpec(d); kind = AST.TYPE;
case Scanner.VAR: P.ParseVarSpec(d); case Scanner.VAR: P.ParseVarSpec(d); kind = AST.VAR;
default: unreachable(); default: unreachable();
} }
// semantic checks // semantic checks
if d.Tok == Scanner.IMPORT { if d.Tok == Scanner.IMPORT {
// TODO if d.Ident != nil {
} else { P.Declare(d.Ident, kind, nil);
if d.Typ != nil {
// apply type to all variables
} }
} else {
P.Declare(d.Ident, kind, d.Typ);
if d.Val != nil { if d.Val != nil {
// initialization/assignment // initialization/assignment
llen := d.Ident.Len(); llen := d.Ident.Len();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment