1
0
mirror of https://github.com/golang/go synced 2024-11-22 20:24:47 -07:00

- more steps towards tracking idents in scopes

- snapshot of today

R=r
OCL=22247
CL=22247
This commit is contained in:
Robert Griesemer 2009-01-07 16:54:03 -08:00
parent 289ff7d0e4
commit cb13c4d552
9 changed files with 56 additions and 57 deletions

View File

@ -29,15 +29,15 @@ pretty.6: platform.6 printer.6 compilation.6
compilation.6: platform.6 scanner.6 parser.6 ast.6 typechecker.6 compilation.6: platform.6 scanner.6 parser.6 ast.6 typechecker.6
ast.6: scanner.6 ast.6: scanner.6 globals.6 type.6
scanner.6: utils.6 scanner.6: utils.6
parser.6: scanner.6 ast.6 parser.6: scanner.6 ast.6 globals.6 object.6 type.6
platform.6: utils.6 platform.6: utils.6
printer.6: scanner.6 ast.6 printer.6: scanner.6 ast.6 globals.6 object.6 type.6
typechecker.6: ast.6 universe.6 globals.6 type.6 typechecker.6: ast.6 universe.6 globals.6 type.6

View File

@ -6,12 +6,13 @@ package AST
import ( import (
"array"; "array";
Globals "globals";
Object "object";
Scanner "scanner"; Scanner "scanner";
) )
type ( type (
Object struct;
Type struct; Type struct;
Expr struct; Expr struct;
Stat struct; Stat struct;
@ -28,39 +29,16 @@ export type Node struct {
} }
// ----------------------------------------------------------------------------
// Objects represent declared language objects, such as a const, type, var;
// but also anonymous objects such as type and other literals.
export type Object struct {
Node;
lit string; // identifiers and literals
typ *Type;
val *Expr;
}
export func NewObject(pos, tok int, lit string) *Object {
obj := new(Object);
obj.pos, obj.tok = pos, tok;
obj.lit = lit;
obj.typ = nil; // Universe::void_typ
return obj;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Expressions // Expressions
export type Expr struct { export type Expr struct {
Node; Node;
x, y *Expr; // binary (x, y) and unary (y) expressions x, y *Expr; // binary (x, y) and unary (y) expressions
obj *Object; obj *Globals.Object;
// TODO find a more space efficient way to hold these // TODO this one should go as well
s string; // identifiers and literals
t *Type; // type expressions, function literal types t *Type; // type expressions, function literal types
block *array.Array; end int; // stats for function literals
} }
@ -86,9 +64,9 @@ export func NewExpr(pos, tok int, x, y *Expr) *Expr {
} }
export func NewLit(pos, tok int, s string) *Expr { export func NewLit(pos, tok int, obj *Globals.Object) *Expr {
e := new(Expr); e := new(Expr);
e.pos, e.tok, e.s = pos, tok, s; e.pos, e.tok, e.obj = pos, tok, obj;
return e; return e;
} }

View File

@ -171,7 +171,7 @@ func AddDeps(globalset map [string] bool, wset *array.Array, src_file string, fl
for i := 0; i < nimports; i++ { for i := 0; i < nimports; i++ {
decl := prog.decls.At(i).(*AST.Decl); decl := prog.decls.At(i).(*AST.Decl);
assert(decl.tok == Scanner.IMPORT && decl.val.tok == Scanner.STRING); assert(decl.tok == Scanner.IMPORT && decl.val.tok == Scanner.STRING);
src := decl.val.s; src := decl.val.obj.ident;
src = src[1 : len(src) - 1]; // strip "'s src = src[1 : len(src) - 1]; // strip "'s
// ignore files when they are seen a 2nd time // ignore files when they are seen a 2nd time

View File

@ -5,6 +5,8 @@
package Globals package Globals
import "array"
// The following types should really be in their respective files // The following types should really be in their respective files
// (object.go, type.go, scope.go, package.go, compilation.go, etc.) but // (object.go, type.go, scope.go, package.go, compilation.go, etc.) but
// they refer to each other and we don't know how to handle forward // they refer to each other and we don't know how to handle forward
@ -29,6 +31,9 @@ export type Object struct {
ident string; ident string;
typ *Type; // nil for packages typ *Type; // nil for packages
pnolev int; // >= 0: package no., <= 0: function nesting level, 0: global level pnolev int; // >= 0: package no., <= 0: function nesting level, 0: global level
// attached values
block *array.Array; end int; // stats for function literals; end of block pos
} }

View File

@ -9,6 +9,7 @@ import Globals "globals"
export const /* kind */ ( export const /* kind */ (
BAD = iota; // error handling BAD = iota; // error handling
NONE; // kind unknown
CONST; TYPE; VAR; FIELD; FUNC; BUILTIN; PACKAGE; LABEL; CONST; TYPE; VAR; FIELD; FUNC; BUILTIN; PACKAGE; LABEL;
END; // end of scope (import/export only) END; // end of scope (import/export only)
) )
@ -22,6 +23,7 @@ export const /* kind */ (
export func KindStr(kind int) string { export func KindStr(kind int) string {
switch kind { switch kind {
case BAD: return "BAD"; case BAD: return "BAD";
case NONE: return "NONE";
case CONST: return "CONST"; case CONST: return "CONST";
case TYPE: return "TYPE"; case TYPE: return "TYPE";
case VAR: return "VAR"; case VAR: return "VAR";

View File

@ -5,6 +5,8 @@
package Parser package Parser
import "array" import "array"
import Globals "globals"
import Object "object"
import Scanner "scanner" import Scanner "scanner"
import AST "ast" import AST "ast"
@ -148,7 +150,8 @@ func ExprType(x *AST.Expr) *AST.Type {
func (P *Parser) NoType(x *AST.Expr) *AST.Expr { func (P *Parser) NoType(x *AST.Expr) *AST.Expr {
if x != nil && x.tok == Scanner.TYPE { if x != nil && x.tok == Scanner.TYPE {
P.Error(x.pos, "expected expression, found type"); P.Error(x.pos, "expected expression, found type");
x = AST.NewLit(x.pos, Scanner.INT, ""); val := Globals.NewObject(x.pos, Object.NONE, "0");
x = AST.NewLit(x.pos, Scanner.INT, val);
} }
return x; return x;
} }
@ -173,10 +176,11 @@ func (P *Parser) ParseIdent() *AST.Expr {
x := AST.BadExpr; x := AST.BadExpr;
if P.tok == Scanner.IDENT { if P.tok == Scanner.IDENT {
x = AST.NewLit(P.pos, Scanner.IDENT, P.val); obj := Globals.NewObject(P.pos, Object.NONE, P.val);
x = AST.NewLit(P.pos, Scanner.IDENT, obj);
if P.verbose { if P.verbose {
P.PrintIndent(); P.PrintIndent();
print("Ident = \"", x.s, "\"\n"); print("Ident = \"", x.obj.ident, "\"\n");
} }
P.Next(); P.Next();
} else { } else {
@ -658,12 +662,13 @@ func (P *Parser) ParseExpressionList() *AST.Expr {
func (P *Parser) ParseFunctionLit() *AST.Expr { func (P *Parser) ParseFunctionLit() *AST.Expr {
P.Trace("FunctionLit"); P.Trace("FunctionLit");
x := AST.NewLit(P.pos, Scanner.FUNC, ""); val := Globals.NewObject(P.pos, Object.NONE, "");
x := AST.NewLit(P.pos, Scanner.FUNC, val);
P.Expect(Scanner.FUNC); P.Expect(Scanner.FUNC);
x.t = P.ParseFunctionType(); x.t = P.ParseFunctionType();
P.expr_lev++; P.expr_lev++;
P.scope_lev++; P.scope_lev++;
x.block, x.end = P.ParseBlock(); val.block, val.end = P.ParseBlock();
P.scope_lev--; P.scope_lev--;
P.expr_lev--; P.expr_lev--;
@ -712,11 +717,14 @@ func (P *Parser) ParseOperand() *AST.Expr {
P.Expect(Scanner.RPAREN); P.Expect(Scanner.RPAREN);
case Scanner.INT, Scanner.FLOAT, Scanner.STRING: case Scanner.INT, Scanner.FLOAT, Scanner.STRING:
x = AST.NewLit(P.pos, P.tok, P.val); val := Globals.NewObject(P.pos, Object.NONE, P.val);
x = AST.NewLit(P.pos, P.tok, val);
P.Next(); P.Next();
if x.tok == Scanner.STRING { if x.tok == Scanner.STRING {
// TODO should remember the list instead of
// concatenate the strings here
for ; P.tok == Scanner.STRING; P.Next() { for ; P.tok == Scanner.STRING; P.Next() {
x.s += P.val; x.obj.ident += P.val;
} }
} }
@ -783,7 +791,7 @@ func (P *Parser) ParseCall(x0 *AST.Expr) *AST.Expr {
if P.tok != Scanner.RPAREN { if P.tok != Scanner.RPAREN {
P.expr_lev++; P.expr_lev++;
var t *AST.Type; var t *AST.Type;
if x0.tok == Scanner.IDENT && (x0.s == "new" || x0.s == "make") { if x0.tok == Scanner.IDENT && (x0.obj.ident == "new" || x0.obj.ident == "make") {
// heuristic: assume it's a new(T) or make(T, ...) call, try to parse a type // heuristic: assume it's a new(T) or make(T, ...) call, try to parse a type
t = P.TryType(); t = P.TryType();
} }
@ -1367,7 +1375,8 @@ func (P *Parser) ParseImportSpec(pos int) *AST.Decl {
if P.tok == Scanner.STRING { if P.tok == Scanner.STRING {
// TODO eventually the scanner should strip the quotes // TODO eventually the scanner should strip the quotes
d.val = AST.NewLit(P.pos, Scanner.STRING, P.val); val := Globals.NewObject(P.pos, Object.NONE, P.val);
d.val = AST.NewLit(P.pos, Scanner.STRING, val);
P.Next(); P.Next();
} else { } else {
P.Expect(Scanner.STRING); // use Expect() error handling P.Expect(Scanner.STRING); // use Expect() error handling

View File

@ -4,10 +4,12 @@
package main package main
import Flag "flag" import (
import Platform "platform" Flag "flag";
import Printer "printer" Platform "platform";
import Compilation "compilation" Printer "printer";
Compilation "compilation";
)
var ( var (
@ -15,7 +17,8 @@ var (
silent = Flag.Bool("s", false, nil, "silent mode: no pretty print output"); silent = Flag.Bool("s", false, nil, "silent mode: no pretty print output");
verbose = Flag.Bool("v", false, &flags.verbose, "verbose mode: trace parsing"); verbose = Flag.Bool("v", false, &flags.verbose, "verbose mode: trace parsing");
sixg = Flag.Bool("6g", true, &flags.sixg, "6g compatibility mode"); sixg = Flag.Bool("6g", true, &flags.sixg, "6g compatibility mode");
deps = Flag.Bool("d", false, &flags.deps, "print dependency information only"); //TODO fix this code again
//deps = Flag.Bool("d", false, &flags.deps, "print dependency information only");
columns = Flag.Bool("columns", Platform.USER == "gri", &flags.columns, "print column info in error messages"); columns = Flag.Bool("columns", Platform.USER == "gri", &flags.columns, "print column info in error messages");
testmode = Flag.Bool("t", false, &flags.testmode, "test mode: interprets /* ERROR */ and /* SYNC */ comments"); testmode = Flag.Bool("t", false, &flags.testmode, "test mode: interprets /* ERROR */ and /* SYNC */ comments");
tokenchan = Flag.Bool("token_chan", false, &flags.tokenchan, "use token channel for scanner-parser connection"); tokenchan = Flag.Bool("token_chan", false, &flags.tokenchan, "use token channel for scanner-parser connection");
@ -40,7 +43,7 @@ func main() {
for i := 0; i < Flag.NArg(); i++ { for i := 0; i < Flag.NArg(); i++ {
src_file := Flag.Arg(i); src_file := Flag.Arg(i);
if flags.deps { if false /* DISABLED flags.deps */ {
Compilation.ComputeDeps(src_file, &flags); Compilation.ComputeDeps(src_file, &flags);
} else { } else {

View File

@ -11,6 +11,8 @@ import (
"tabwriter"; "tabwriter";
"flag"; "flag";
"fmt"; "fmt";
Globals "globals";
Object "object";
Scanner "scanner"; Scanner "scanner";
AST "ast"; AST "ast";
) )
@ -363,12 +365,12 @@ func (P *Printer) HtmlEpilogue() {
} }
func (P *Printer) HtmlIdentifier(pos int, ident string) { func (P *Printer) HtmlIdentifier(pos int, obj *Globals.Object) {
if html.BVal() { if html.BVal() {
// no need to HtmlEscape ident // no need to HtmlEscape ident
P.TaggedString(pos, `<a href="#` + ident + `">`, ident, `</a>`); P.TaggedString(pos, `<a href="#` + obj.ident + `">`, obj.ident, `</a>`);
} else { } else {
P.String(pos, ident); P.String(pos, obj.ident);
} }
} }
@ -515,17 +517,17 @@ func (P *Printer) Expr1(x *AST.Expr, prec1 int) {
P.Type(x.t); P.Type(x.t);
case Scanner.IDENT: case Scanner.IDENT:
P.HtmlIdentifier(x.pos, x.s); P.HtmlIdentifier(x.pos, x.obj);
case Scanner.INT, Scanner.STRING, Scanner.FLOAT: case Scanner.INT, Scanner.STRING, Scanner.FLOAT:
// literal // literal
P.String(x.pos, x.s); P.String(x.pos, x.obj.ident);
case Scanner.FUNC: case Scanner.FUNC:
// function literal // function literal
P.String(x.pos, "func"); P.String(x.pos, "func");
P.Type(x.t); P.Type(x.t);
P.Block(0, x.block, x.end, true); P.Block(0, x.obj.block, x.obj.end, true);
P.newlines = 0; P.newlines = 0;
case Scanner.COMMA: case Scanner.COMMA:

View File

@ -103,7 +103,7 @@ func (s *State) DeclareIdent(ident *AST.Expr, kind int, typ *AST.Type) {
// ident is either a comma-separated list or a single ident // ident is either a comma-separated list or a single ident
switch ident.tok { switch ident.tok {
case Scanner.IDENT: case Scanner.IDENT:
obj := Globals.NewObject(ident.pos, kind, ident.s); obj := Globals.NewObject(ident.pos, kind, ident.obj.ident);
s.Declare(obj); s.Declare(obj);
case Scanner.COMMA: case Scanner.COMMA:
s.DeclareIdent(ident.x, kind, typ); s.DeclareIdent(ident.x, kind, typ);
@ -149,7 +149,7 @@ func (s *State) CheckDeclaration(d *AST.Decl) {
case Scanner.TYPE: case Scanner.TYPE:
assert(d.ident.tok == Scanner.IDENT); assert(d.ident.tok == Scanner.IDENT);
// types may be forward-declared // types may be forward-declared
obj := s.Lookup(d.ident.s); obj := s.Lookup(d.ident.obj.ident);
if obj != nil { if obj != nil {
// TODO check if proper forward-declaration // TODO check if proper forward-declaration
@ -164,7 +164,7 @@ func (s *State) CheckDeclaration(d *AST.Decl) {
// TODO // TODO
} else { } else {
// functions may be forward-declared // functions may be forward-declared
obj := s.Lookup(d.ident.s); obj := s.Lookup(d.ident.obj.ident);
if obj != nil { if obj != nil {
// TODO check if proper forward-declaration // TODO check if proper forward-declaration