diff --git a/usr/gri/pretty/Makefile b/usr/gri/pretty/Makefile index cfc2bb132c7..1386c0cd582 100644 --- a/usr/gri/pretty/Makefile +++ b/usr/gri/pretty/Makefile @@ -29,15 +29,15 @@ pretty.6: platform.6 printer.6 compilation.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 -parser.6: scanner.6 ast.6 +parser.6: scanner.6 ast.6 globals.6 object.6 type.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 diff --git a/usr/gri/pretty/ast.go b/usr/gri/pretty/ast.go index 5e40a61cc93..ad1edaeb236 100644 --- a/usr/gri/pretty/ast.go +++ b/usr/gri/pretty/ast.go @@ -6,12 +6,13 @@ package AST import ( "array"; + Globals "globals"; + Object "object"; Scanner "scanner"; ) type ( - Object struct; Type struct; Expr 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 export type Expr struct { Node; x, y *Expr; // binary (x, y) and unary (y) expressions - obj *Object; - - // TODO find a more space efficient way to hold these - s string; // identifiers and literals + obj *Globals.Object; + + // TODO this one should go as well 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.pos, e.tok, e.s = pos, tok, s; + e.pos, e.tok, e.obj = pos, tok, obj; return e; } diff --git a/usr/gri/pretty/compilation.go b/usr/gri/pretty/compilation.go index ce1923aa0b6..491b41c33ce 100644 --- a/usr/gri/pretty/compilation.go +++ b/usr/gri/pretty/compilation.go @@ -171,7 +171,7 @@ func AddDeps(globalset map [string] bool, wset *array.Array, src_file string, fl for i := 0; i < nimports; i++ { decl := prog.decls.At(i).(*AST.Decl); 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 // ignore files when they are seen a 2nd time diff --git a/usr/gri/pretty/globals.go b/usr/gri/pretty/globals.go index 25a8702f15b..199a8c91e23 100644 --- a/usr/gri/pretty/globals.go +++ b/usr/gri/pretty/globals.go @@ -5,6 +5,8 @@ package Globals +import "array" + // The following types should really be in their respective files // (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 @@ -29,6 +31,9 @@ export type Object struct { ident string; typ *Type; // nil for packages 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 } diff --git a/usr/gri/pretty/object.go b/usr/gri/pretty/object.go index 220f4c8d8b4..b09e563d442 100755 --- a/usr/gri/pretty/object.go +++ b/usr/gri/pretty/object.go @@ -9,6 +9,7 @@ import Globals "globals" export const /* kind */ ( BAD = iota; // error handling + NONE; // kind unknown CONST; TYPE; VAR; FIELD; FUNC; BUILTIN; PACKAGE; LABEL; END; // end of scope (import/export only) ) @@ -22,6 +23,7 @@ export const /* kind */ ( export func KindStr(kind int) string { switch kind { case BAD: return "BAD"; + case NONE: return "NONE"; case CONST: return "CONST"; case TYPE: return "TYPE"; case VAR: return "VAR"; diff --git a/usr/gri/pretty/parser.go b/usr/gri/pretty/parser.go index 0bca27867d6..b77de1493e9 100644 --- a/usr/gri/pretty/parser.go +++ b/usr/gri/pretty/parser.go @@ -5,6 +5,8 @@ package Parser import "array" +import Globals "globals" +import Object "object" import Scanner "scanner" import AST "ast" @@ -148,7 +150,8 @@ func ExprType(x *AST.Expr) *AST.Type { 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 = AST.NewLit(x.pos, Scanner.INT, ""); + val := Globals.NewObject(x.pos, Object.NONE, "0"); + x = AST.NewLit(x.pos, Scanner.INT, val); } return x; } @@ -173,10 +176,11 @@ func (P *Parser) ParseIdent() *AST.Expr { x := AST.BadExpr; 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 { P.PrintIndent(); - print("Ident = \"", x.s, "\"\n"); + print("Ident = \"", x.obj.ident, "\"\n"); } P.Next(); } else { @@ -658,12 +662,13 @@ func (P *Parser) ParseExpressionList() *AST.Expr { func (P *Parser) ParseFunctionLit() *AST.Expr { 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); x.t = P.ParseFunctionType(); P.expr_lev++; P.scope_lev++; - x.block, x.end = P.ParseBlock(); + val.block, val.end = P.ParseBlock(); P.scope_lev--; P.expr_lev--; @@ -712,11 +717,14 @@ func (P *Parser) ParseOperand() *AST.Expr { P.Expect(Scanner.RPAREN); 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(); if x.tok == Scanner.STRING { + // TODO should remember the list instead of + // concatenate the strings here 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 { P.expr_lev++; 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 t = P.TryType(); } @@ -1367,7 +1375,8 @@ func (P *Parser) ParseImportSpec(pos int) *AST.Decl { if P.tok == Scanner.STRING { // 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(); } else { P.Expect(Scanner.STRING); // use Expect() error handling diff --git a/usr/gri/pretty/pretty.go b/usr/gri/pretty/pretty.go index 80edbfcc49a..4d36bbe4f1b 100644 --- a/usr/gri/pretty/pretty.go +++ b/usr/gri/pretty/pretty.go @@ -4,10 +4,12 @@ package main -import Flag "flag" -import Platform "platform" -import Printer "printer" -import Compilation "compilation" +import ( + Flag "flag"; + Platform "platform"; + Printer "printer"; + Compilation "compilation"; +) var ( @@ -15,7 +17,8 @@ var ( silent = Flag.Bool("s", false, nil, "silent mode: no pretty print output"); verbose = Flag.Bool("v", false, &flags.verbose, "verbose mode: trace parsing"); 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"); 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"); @@ -40,7 +43,7 @@ func main() { for i := 0; i < Flag.NArg(); i++ { src_file := Flag.Arg(i); - if flags.deps { + if false /* DISABLED flags.deps */ { Compilation.ComputeDeps(src_file, &flags); } else { diff --git a/usr/gri/pretty/printer.go b/usr/gri/pretty/printer.go index cbfdc5fc80a..10dc45d3d80 100644 --- a/usr/gri/pretty/printer.go +++ b/usr/gri/pretty/printer.go @@ -11,6 +11,8 @@ import ( "tabwriter"; "flag"; "fmt"; + Globals "globals"; + Object "object"; Scanner "scanner"; 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() { // no need to HtmlEscape ident - P.TaggedString(pos, ``, ident, ``); + P.TaggedString(pos, ``, obj.ident, ``); } 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); case Scanner.IDENT: - P.HtmlIdentifier(x.pos, x.s); + P.HtmlIdentifier(x.pos, x.obj); case Scanner.INT, Scanner.STRING, Scanner.FLOAT: // literal - P.String(x.pos, x.s); + P.String(x.pos, x.obj.ident); case Scanner.FUNC: // function literal P.String(x.pos, "func"); 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; case Scanner.COMMA: diff --git a/usr/gri/pretty/typechecker.go b/usr/gri/pretty/typechecker.go index 4b0c6e48a02..1b27942dcee 100644 --- a/usr/gri/pretty/typechecker.go +++ b/usr/gri/pretty/typechecker.go @@ -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 switch ident.tok { case Scanner.IDENT: - obj := Globals.NewObject(ident.pos, kind, ident.s); + obj := Globals.NewObject(ident.pos, kind, ident.obj.ident); s.Declare(obj); case Scanner.COMMA: s.DeclareIdent(ident.x, kind, typ); @@ -149,7 +149,7 @@ func (s *State) CheckDeclaration(d *AST.Decl) { case Scanner.TYPE: assert(d.ident.tok == Scanner.IDENT); // types may be forward-declared - obj := s.Lookup(d.ident.s); + obj := s.Lookup(d.ident.obj.ident); if obj != nil { // TODO check if proper forward-declaration @@ -164,7 +164,7 @@ func (s *State) CheckDeclaration(d *AST.Decl) { // TODO } else { // functions may be forward-declared - obj := s.Lookup(d.ident.s); + obj := s.Lookup(d.ident.obj.ident); if obj != nil { // TODO check if proper forward-declaration