From c620dd9759f0fe06bf88a0c25a29f510250ab96d Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Fri, 9 Jan 2009 16:28:09 -0800 Subject: [PATCH] - preparation to add type info to ast - consolidation of files, cleanup - more success producing idempotent output for some files with comments containing tabs - snapshot of the day R=r OCL=22474 CL=22474 --- usr/gri/pretty/Makefile | 14 +- usr/gri/pretty/ast.go | 249 ++++++++++++++++++++++++++++++++-- usr/gri/pretty/parser.go | 90 ++++++------ usr/gri/pretty/printer.go | 50 +++++-- usr/gri/pretty/scanner.go | 5 +- usr/gri/pretty/test.sh | 6 +- usr/gri/pretty/typechecker.go | 3 - usr/gri/pretty/universe.go | 88 ++++++------ 8 files changed, 361 insertions(+), 144 deletions(-) diff --git a/usr/gri/pretty/Makefile b/usr/gri/pretty/Makefile index 82a25b03fbe..2b5883a8746 100644 --- a/usr/gri/pretty/Makefile +++ b/usr/gri/pretty/Makefile @@ -29,23 +29,19 @@ pretty.6: platform.6 printer.6 compilation.6 compilation.6: platform.6 scanner.6 parser.6 ast.6 typechecker.6 -ast.6: scanner.6 globals.6 type.6 +ast.6: scanner.6 scanner.6: utils.6 -parser.6: scanner.6 ast.6 globals.6 object.6 type.6 +parser.6: scanner.6 ast.6 platform.6: utils.6 -printer.6: scanner.6 ast.6 globals.6 object.6 type.6 utils.6 +printer.6: scanner.6 ast.6 utils.6 -typechecker.6: ast.6 universe.6 globals.6 type.6 +typechecker.6: ast.6 universe.6 -universe.6: globals.6 object.6 type.6 - -object.6: globals.6 - -type.6: globals.6 object.6 +universe.6: ast.6 %.6: %.go $(G) $(F) $< diff --git a/usr/gri/pretty/ast.go b/usr/gri/pretty/ast.go index ad1edaeb236..0f0dd6a1f54 100644 --- a/usr/gri/pretty/ast.go +++ b/usr/gri/pretty/ast.go @@ -6,20 +6,154 @@ package AST import ( "array"; - Globals "globals"; - Object "object"; Scanner "scanner"; ) type ( + Object struct; Type struct; + Expr struct; Stat struct; Decl struct; ) +// ---------------------------------------------------------------------------- +// Objects + +// Object represents a language object, such as a constant, variable, type, etc. + +export const /* kind */ ( + BADOBJ = iota; // error handling + NONE; // kind unknown + CONST; TYPE; VAR; FIELD; FUNC; BUILTIN; PACKAGE; LABEL; + END; // end of scope (import/export only) +) + + +export func KindStr(kind int) string { + switch kind { + case BADOBJ: return "BADOBJ"; + case NONE: return "NONE"; + case CONST: return "CONST"; + case TYPE: return "TYPE"; + case VAR: return "VAR"; + case FIELD: return "FIELD"; + case FUNC: return "FUNC"; + case BUILTIN: return "BUILTIN"; + case PACKAGE: return "PACKAGE"; + case LABEL: return "LABEL"; + case END: return "END"; + } + return ""; +} + + +export type Object struct { + id int; // unique id + + pos int; // source position (< 0 if unknown position) + kind int; // object kind + 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 +} + + + +export var Universe_void_typ *Type // initialized by Universe to Universe.void_typ +var ObjectId int; + +export func NewObject(pos, kind int, ident string) *Object { + obj := new(Object); + obj.id = ObjectId; + ObjectId++; + + obj.pos = pos; + obj.kind = kind; + obj.ident = ident; + obj.typ = Universe_void_typ; + obj.pnolev = 0; + + return obj; +} + + +// ---------------------------------------------------------------------------- +// Scopes + +export type Scope struct { + parent *Scope; + entries map[string] *Object; +} + + +export func NewScope(parent *Scope) *Scope { + scope := new(Scope); + scope.parent = parent; + scope.entries = make(map[string]*Object, 8); + return scope; +} + + +func (scope *Scope) LookupLocal(ident string) *Object { + obj, found := scope.entries[ident]; + if found { + return obj; + } + return nil; +} + + +func (scope *Scope) Lookup(ident string) *Object { + for scope != nil { + obj := scope.LookupLocal(ident); + if obj != nil { + return obj; + } + scope = scope.parent; + } + return nil; +} + + +func (scope *Scope) Add(obj* Object) { + scope.entries[obj.ident] = obj; +} + + +func (scope *Scope) Insert(obj *Object) { + if scope.LookupLocal(obj.ident) != nil { + panic("obj already inserted"); + } + scope.Add(obj); +} + + +func (scope *Scope) InsertImport(obj *Object) *Object { + p := scope.LookupLocal(obj.ident); + if p == nil { + scope.Add(obj); + p = obj; + } + return p; +} + + +func (scope *Scope) Print() { + print("scope {"); + for key := range scope.entries { + print("\n ", key); + } + print("\n}\n"); +} + + // ---------------------------------------------------------------------------- // All nodes have a source position and and token. @@ -35,7 +169,7 @@ export type Node struct { export type Expr struct { Node; x, y *Expr; // binary (x, y) and unary (y) expressions - obj *Globals.Object; + obj *Object; // TODO this one should go as well t *Type; // type expressions, function literal types @@ -64,7 +198,7 @@ export func NewExpr(pos, tok int, x, y *Expr) *Expr { } -export func NewLit(pos, tok int, obj *Globals.Object) *Expr { +export func NewLit(pos, tok int, obj *Object) *Expr { e := new(Expr); e.pos, e.tok, e.obj = pos, tok, obj; return e; @@ -77,6 +211,74 @@ export var BadExpr = NewExpr(0, Scanner.ILLEGAL, nil, nil); // ---------------------------------------------------------------------------- // Types +export const /* form */ ( + // internal types + // We should never see one of these. + UNDEF = iota; + + // VOID types are used when we don't have a type. Never exported. + // (exported type forms must be > 0) + VOID; + + // BADTYPE types are compatible with any type and don't cause further errors. + // They are introduced only as a result of an error in the source code. A + // correct program cannot have BAD types. + BADTYPE; + + // FORWARD types are forward-declared (incomplete) types. They can only + // be used as element types of pointer types and must be resolved before + // their internals are accessible. + FORWARD; + + // TUPLE types represent multi-valued result types of functions and + // methods. + TUPLE; + + // The type of nil. + NIL; + + // A type name + TYPENAME; + + // basic types + BOOL; UINT; INT; FLOAT; STRING; INTEGER; + + // composite types + ALIAS; ARRAY; STRUCT; INTERFACE; MAP; CHANNEL; FUNCTION; METHOD; POINTER; + + // open-ended parameter type + ELLIPSIS +) + + +export func FormStr(form int) string { + switch form { + case VOID: return "VOID"; + case BADTYPE: return "BADTYPE"; + case FORWARD: return "FORWARD"; + case TUPLE: return "TUPLE"; + case NIL: return "NIL"; + case TYPENAME: return "TYPENAME"; + case BOOL: return "BOOL"; + case UINT: return "UINT"; + case INT: return "INT"; + case FLOAT: return "FLOAT"; + case STRING: return "STRING"; + case ALIAS: return "ALIAS"; + case ARRAY: return "ARRAY"; + case STRUCT: return "STRUCT"; + case INTERFACE: return "INTERFACE"; + case MAP: return "MAP"; + case CHANNEL: return "CHANNEL"; + case FUNCTION: return "FUNCTION"; + case METHOD: return "METHOD"; + case POINTER: return "POINTER"; + case ELLIPSIS: return "ELLIPSIS"; + } + return ""; +} + + export const /* channel mode */ ( FULL = iota; SEND; @@ -85,15 +287,39 @@ export const /* channel mode */ ( export type Type struct { - Node; + id int; // unique id + + ref int; // for exporting only: >= 0 means already exported + form int; // type form + size int; // size in bytes + obj *Object; // primary type object or NULL + scope *Scope; // forwards, structs, interfaces, functions + + // syntactic components + pos int; // source position (< 0 if unknown position) expr *Expr; // type name, array length mode int; // channel mode - key *Type; // receiver type, map key - elt *Type; // array element, map or channel value, or pointer base type, result type + key *Type; // receiver type or map key + elt *Type; // array, map, channel or pointer element type, function result type list *array.Array; end int; // struct fields, interface methods, function parameters } +var TypeId int; + +export func NewType(pos, form int) *Type { + typ := new(Type); + typ.id = TypeId; + TypeId++; + + typ.ref = -1; // not yet exported + typ.pos = pos; + typ.form = form; + + return typ; +} + + func (t *Type) nfields() int { if t.list == nil { return 0; @@ -113,14 +339,7 @@ func (t *Type) nfields() int { } -export func NewType(pos, tok int) *Type { - t := new(Type); - t.pos, t.tok = pos, tok; - return t; -} - - -// requires complete Type type +// requires complete Type.pos access export func NewTypeExpr(t *Type) *Expr { e := new(Expr); e.pos, e.tok, e.t = t.pos, Scanner.TYPE, t; diff --git a/usr/gri/pretty/parser.go b/usr/gri/pretty/parser.go index 7831ca8ec6d..6b1bb43398b 100644 --- a/usr/gri/pretty/parser.go +++ b/usr/gri/pretty/parser.go @@ -4,11 +4,11 @@ package Parser -import "array" -import Globals "globals" -import Object "object" -import Scanner "scanner" -import AST "ast" +import ( + "array"; + Scanner "scanner"; + AST "ast"; +) export type Parser struct { @@ -34,7 +34,7 @@ export type Parser struct { scope_lev int; // 0 = global scope, 1 = function scope of global functions, etc. // Scopes - top_scope *Globals.Scope; + top_scope *AST.Scope; }; @@ -154,7 +154,7 @@ func (P *Parser) OptSemicolon() { // Scopes func (P *Parser) OpenScope() { - P.top_scope = Globals.NewScope(P.top_scope); + P.top_scope = AST.NewScope(P.top_scope); } @@ -163,27 +163,15 @@ func (P *Parser) CloseScope() { } -func Lookup(scope *Globals.Scope, ident string) *Globals.Object { - for scope != nil { - obj := scope.Lookup(ident); - if obj != nil { - return obj; - } - scope = scope.parent; - } - return nil; -} - - -func (P *Parser) DeclareInScope(scope *Globals.Scope, x *AST.Expr, kind int) { +func (P *Parser) DeclareInScope(scope *AST.Scope, x *AST.Expr, kind int) { if P.scope_lev < 0 { panic("cannot declare objects in other packages"); } obj := x.obj; - assert(x.tok == Scanner.IDENT && obj.kind == Object.NONE); + assert(x.tok == Scanner.IDENT && obj.kind == AST.NONE); obj.kind = kind; obj.pnolev = P.scope_lev; - if scope.Lookup(obj.ident) != nil { + if scope.LookupLocal(obj.ident) != nil { P.Error(obj.pos, `"` + obj.ident + `" is declared already`); return; // don't insert it into the scope } @@ -210,11 +198,11 @@ func ExprType(x *AST.Expr) *AST.Type { t = x.t; } else if x.tok == Scanner.IDENT { // assume a type name - t = AST.NewType(x.pos, Scanner.IDENT); + t = AST.NewType(x.pos, AST.TYPENAME); t.expr = x; } else if x.tok == Scanner.PERIOD && x.y != nil && ExprType(x.x) != nil { // possibly a qualified (type) identifier - t = AST.NewType(x.pos, Scanner.IDENT); + t = AST.NewType(x.pos, AST.TYPENAME); t.expr = x; } return t; @@ -224,7 +212,7 @@ 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"); - val := Globals.NewObject(x.pos, Object.NONE, "0"); + val := AST.NewObject(x.pos, AST.NONE, "0"); x = AST.NewLit(x.pos, Scanner.INT, val); } return x; @@ -246,19 +234,19 @@ func (P *Parser) ParseDeclaration() *AST.Decl; // If scope != nil, lookup identifier in scope. Otherwise create one. -func (P *Parser) ParseIdent(scope *Globals.Scope) *AST.Expr { +func (P *Parser) ParseIdent(scope *AST.Scope) *AST.Expr { P.Trace("Ident"); x := AST.BadExpr; if P.tok == Scanner.IDENT { - var obj *Globals.Object; + var obj *AST.Object; if scope != nil { - obj = Lookup(scope, P.val); + obj = scope.Lookup(P.val); } if obj == nil { - obj = Globals.NewObject(P.pos, Object.NONE, P.val); + obj = AST.NewObject(P.pos, AST.NONE, P.val); } else { - assert(obj.kind != Object.NONE); + assert(obj.kind != AST.NONE); } x = AST.NewLit(P.pos, Scanner.IDENT, obj); if P.verbose { @@ -344,7 +332,7 @@ func (P *Parser) ParseQualifiedIdent() *AST.Expr { func (P *Parser) ParseTypeName() *AST.Type { P.Trace("TypeName"); - t := AST.NewType(P.pos, P.tok); + t := AST.NewType(P.pos, AST.TYPENAME); t.expr = P.ParseQualifiedIdent(); P.Ecart(); @@ -355,7 +343,7 @@ func (P *Parser) ParseTypeName() *AST.Type { func (P *Parser) ParseArrayType() *AST.Type { P.Trace("ArrayType"); - t := AST.NewType(P.pos, Scanner.LBRACK); + t := AST.NewType(P.pos, AST.ARRAY); P.Expect(Scanner.LBRACK); if P.tok == Scanner.ELLIPSIS { t.expr = P.NewExpr(P.pos, Scanner.ELLIPSIS, nil, nil); @@ -374,7 +362,7 @@ func (P *Parser) ParseArrayType() *AST.Type { func (P *Parser) ParseChannelType() *AST.Type { P.Trace("ChannelType"); - t := AST.NewType(P.pos, Scanner.CHAN); + t := AST.NewType(P.pos, AST.CHANNEL); t.mode = AST.FULL; if P.tok == Scanner.CHAN { P.Next(); @@ -401,10 +389,10 @@ func (P *Parser) ParseVarDecl(expect_ident bool) *AST.Type { t := AST.BadType; if expect_ident { x := P.ParseIdent(nil); - t = AST.NewType(x.pos, Scanner.IDENT); + t = AST.NewType(x.pos, AST.TYPENAME); t.expr = x; } else if P.tok == Scanner.ELLIPSIS { - t = AST.NewType(P.pos, Scanner.ELLIPSIS); + t = AST.NewType(P.pos, AST.ELLIPSIS); P.Next(); } else { t = P.ParseType(); @@ -429,7 +417,7 @@ func (P *Parser) ParseVarDeclList(list *array.Array, ellipsis_ok bool) { typ := P.TryType(); if typ == nil && P.tok == Scanner.ELLIPSIS { - typ = AST.NewType(P.pos, Scanner.ELLIPSIS); + typ = AST.NewType(P.pos, AST.ELLIPSIS); P.Next(); } @@ -445,7 +433,7 @@ func (P *Parser) ParseVarDeclList(list *array.Array, ellipsis_ok bool) { // convert the type entries into identifiers for i, n := i0, list.Len(); i < n; i++ { t := list.At(i).(*AST.Type); - if t.tok == Scanner.IDENT && t.expr.tok == Scanner.IDENT { + if t.form == AST.TYPENAME && t.expr.tok == Scanner.IDENT { list.Set(i, t.expr); } else { list.Set(i, AST.BadExpr); @@ -486,7 +474,7 @@ func (P *Parser) ParseParameterList(ellipsis_ok bool) *array.Array { func (P *Parser) ParseParameters(ellipsis_ok bool) *AST.Type { P.Trace("Parameters"); - t := AST.NewType(P.pos, Scanner.STRUCT); + t := AST.NewType(P.pos, AST.STRUCT); P.Expect(Scanner.LPAREN); if P.tok != Scanner.RPAREN { t.list = P.ParseParameterList(ellipsis_ok); @@ -524,7 +512,7 @@ func (P *Parser) ParseResult() *AST.Type { } else { typ := P.TryType(); if typ != nil { - t = AST.NewType(P.pos, Scanner.STRUCT); + t = AST.NewType(P.pos, AST.STRUCT); t.list = array.New(0); t.list.Push(AST.NewTypeExpr(typ)); t.end = P.pos; @@ -548,7 +536,7 @@ func (P *Parser) ParseFunctionType() *AST.Type { P.OpenScope(); P.scope_lev++; - t := AST.NewType(P.pos, Scanner.LPAREN); + t := AST.NewType(P.pos, AST.FUNCTION); t.list = P.ParseParameters(true).list; // TODO find better solution t.end = P.pos; t.elt = P.ParseResult(); @@ -580,7 +568,7 @@ func (P *Parser) ParseMethodSpec(list *array.Array) { func (P *Parser) ParseInterfaceType() *AST.Type { P.Trace("InterfaceType"); - t := AST.NewType(P.pos, Scanner.INTERFACE); + t := AST.NewType(P.pos, AST.INTERFACE); P.Expect(Scanner.INTERFACE); if P.tok == Scanner.LBRACE { P.Next(); @@ -609,7 +597,7 @@ func (P *Parser) ParseInterfaceType() *AST.Type { func (P *Parser) ParseMapType() *AST.Type { P.Trace("MapType"); - t := AST.NewType(P.pos, Scanner.MAP); + t := AST.NewType(P.pos, AST.MAP); P.Expect(Scanner.MAP); P.Expect(Scanner.LBRACK); t.key = P.ParseVarType(); @@ -626,7 +614,7 @@ func (P *Parser) ParseOperand() *AST.Expr func (P *Parser) ParseStructType() *AST.Type { P.Trace("StructType"); - t := AST.NewType(P.pos, Scanner.STRUCT); + t := AST.NewType(P.pos, AST.STRUCT); P.Expect(Scanner.STRUCT); if P.tok == Scanner.LBRACE { P.Next(); @@ -662,7 +650,7 @@ func (P *Parser) ParseStructType() *AST.Type { func (P *Parser) ParsePointerType() *AST.Type { P.Trace("PointerType"); - t := AST.NewType(P.pos, Scanner.MUL); + t := AST.NewType(P.pos, AST.POINTER); P.Expect(Scanner.MUL); t.elt = P.ParseType(); @@ -769,7 +757,7 @@ func (P *Parser) ParseExpressionList() *AST.Expr { func (P *Parser) ParseFunctionLit() *AST.Expr { P.Trace("FunctionLit"); - val := Globals.NewObject(P.pos, Object.NONE, ""); + val := AST.NewObject(P.pos, AST.NONE, ""); x := AST.NewLit(P.pos, Scanner.FUNC, val); P.Expect(Scanner.FUNC); x.t = P.ParseFunctionType(); @@ -824,7 +812,7 @@ func (P *Parser) ParseOperand() *AST.Expr { P.Expect(Scanner.RPAREN); case Scanner.INT, Scanner.FLOAT, Scanner.STRING: - val := Globals.NewObject(P.pos, Object.NONE, P.val); + val := AST.NewObject(P.pos, AST.NONE, P.val); x = AST.NewLit(P.pos, P.tok, val); P.Next(); if x.tok == Scanner.STRING { @@ -1033,7 +1021,7 @@ func (P *Parser) ParseUnaryExpr() *AST.Expr { y := P.ParseUnaryExpr(); if tok == Scanner.MUL && y.tok == Scanner.TYPE { // pointer type - t := AST.NewType(pos, Scanner.MUL); + t := AST.NewType(pos, AST.POINTER); t.elt = y.t; x = AST.NewTypeExpr(t); } else { @@ -1491,7 +1479,7 @@ func (P *Parser) ParseImportSpec(pos int) *AST.Decl { if P.tok == Scanner.STRING { // TODO eventually the scanner should strip the quotes - val := Globals.NewObject(P.pos, Object.NONE, P.val); + val := AST.NewObject(P.pos, AST.NONE, P.val); d.val = AST.NewLit(P.pos, Scanner.STRING, val); P.Next(); } else { @@ -1499,7 +1487,7 @@ func (P *Parser) ParseImportSpec(pos int) *AST.Decl { } if d.ident != nil { - P.Declare(d.ident, Object.PACKAGE); + P.Declare(d.ident, AST.PACKAGE); } P.Ecart(); @@ -1518,7 +1506,7 @@ func (P *Parser) ParseConstSpec(exported bool, pos int) *AST.Decl { d.val = P.ParseExpressionList(); } - P.Declare(d.ident, Object.CONST); + P.Declare(d.ident, AST.CONST); P.Ecart(); return d; @@ -1554,7 +1542,7 @@ func (P *Parser) ParseVarSpec(exported bool, pos int) *AST.Decl { } } - P.Declare(d.ident, Object.VAR); + P.Declare(d.ident, AST.VAR); P.Ecart(); return d; diff --git a/usr/gri/pretty/printer.go b/usr/gri/pretty/printer.go index 2afc95cedf9..8da1a847b5f 100644 --- a/usr/gri/pretty/printer.go +++ b/usr/gri/pretty/printer.go @@ -12,8 +12,6 @@ import ( "flag"; "fmt"; Utils "utils"; - Globals "globals"; - Object "object"; Scanner "scanner"; AST "ast"; ) @@ -127,6 +125,23 @@ func HtmlEscape(s string) string { } +// Reduce contiguous sequences of '\t' in a string to a single '\t'. +func Untabify(s string) string { + for i := 0; i < len(s); i++ { + if s[i] == '\t' { + j := i; + for j < len(s) && s[j] == '\t' { + j++; + } + if j-i > 1 { // more then one tab + return s[0 : i+1] + Untabify(s[j : len(s)]); + } + } + } + return s; +} + + func (P *Printer) Printf(format string, s ...) { n, err := fmt.fprintf(P.text, format, s); if err != nil { @@ -246,7 +261,9 @@ func (P *Printer) TaggedString(pos int, tag, s, endtag string) { if *debug { P.Printf("[%d]", P.cpos); } - P.Printf("%s", HtmlEscape(ctext)); + // calling Untabify increases the change for idempotent output + // since tabs in comments are also interpreted by tabwriter + P.Printf("%s", HtmlEscape(Untabify(ctext))); if ctext[1] == '/' { //-style comments must end in newline @@ -371,7 +388,7 @@ func (P *Printer) HtmlIdentifier(x *AST.Expr) { panic(); } obj := x.obj; - if *html && obj.kind != Object.NONE { + if *html && obj.kind != AST.NONE { // depending on whether we have a declaration or use, generate different html // - no need to HtmlEscape ident id := Utils.IntToString(obj.id, 10); @@ -450,11 +467,11 @@ func (P *Printer) Fields(list *array.Array, end int) { func (P *Printer) Type(t *AST.Type) int { separator := semicolon; - switch t.tok { - case Scanner.IDENT: + switch t.form { + case AST.TYPENAME: P.Expr(t.expr); - case Scanner.LBRACK: + case AST.ARRAY: P.String(t.pos, "["); if t.expr != nil { P.Expr(t.expr); @@ -462,21 +479,24 @@ func (P *Printer) Type(t *AST.Type) int { P.String(0, "]"); separator = P.Type(t.elt); - case Scanner.STRUCT, Scanner.INTERFACE: - P.Token(t.pos, t.tok); + case AST.STRUCT, AST.INTERFACE: + switch t.form { + case AST.STRUCT: P.String(t.pos, "struct"); + case AST.INTERFACE: P.String(t.pos, "interface"); + } if t.list != nil { P.separator = blank; P.Fields(t.list, t.end); } separator = none; - case Scanner.MAP: + case AST.MAP: P.String(t.pos, "map ["); P.Type(t.key); P.String(0, "]"); separator = P.Type(t.elt); - case Scanner.CHAN: + case AST.CHANNEL: var m string; switch t.mode { case AST.FULL: m = "chan "; @@ -486,11 +506,11 @@ func (P *Printer) Type(t *AST.Type) int { P.String(t.pos, m); separator = P.Type(t.elt); - case Scanner.MUL: + case AST.POINTER: P.String(t.pos, "*"); separator = P.Type(t.elt); - case Scanner.LPAREN: + case AST.FUNCTION: P.Parameters(t.pos, t.list); if t.elt != nil { P.separator = blank; @@ -503,11 +523,11 @@ func (P *Printer) Type(t *AST.Type) int { } } - case Scanner.ELLIPSIS: + case AST.ELLIPSIS: P.String(t.pos, "..."); default: - P.Error(t.pos, t.tok, "type"); + P.Error(t.pos, t.form, "type"); } return separator; diff --git a/usr/gri/pretty/scanner.go b/usr/gri/pretty/scanner.go index 87f67133a58..9b56e329b1d 100644 --- a/usr/gri/pretty/scanner.go +++ b/usr/gri/pretty/scanner.go @@ -679,7 +679,8 @@ func (S *Scanner) Select4(tok0, tok1, ch2, tok2, tok3 int) int { func (S *Scanner) Scan() (pos, tok int, val string) { -L: S.SkipWhitespace(); +loop: + S.SkipWhitespace(); pos, tok = S.chpos, ILLEGAL; @@ -722,7 +723,7 @@ L: S.SkipWhitespace(); if S.ch == '/' || S.ch == '*' { tok, val = COMMENT, S.ScanComment(); if !S.scan_comments { - goto L; + goto loop; } } else { tok = S.Select2(QUO, QUO_ASSIGN); diff --git a/usr/gri/pretty/test.sh b/usr/gri/pretty/test.sh index b248616ff3e..44d99946d05 100755 --- a/usr/gri/pretty/test.sh +++ b/usr/gri/pretty/test.sh @@ -22,11 +22,9 @@ count() { apply1() { #echo $1 $2 case `basename $F` in - # these files don't pass the idempotency test yet - log.go | type.go | types_amd64_darwin.go | \ - \ + # files with errors (skip them) method1.go | selftest1.go | func3.go | bug014.go | bug029.go | bug032.go | bug050.go | \ - bug068.go | bug088.go | bug083.go | bug106.go | bug125.go | bug126.go ) ;; # skip - files contain errors + bug068.go | bug088.go | bug083.go | bug106.go | bug125.go | bug126.go ) ;; * ) $1 $2; count ;; esac } diff --git a/usr/gri/pretty/typechecker.go b/usr/gri/pretty/typechecker.go index b2e6ae6f3de..c48588b5c26 100644 --- a/usr/gri/pretty/typechecker.go +++ b/usr/gri/pretty/typechecker.go @@ -8,9 +8,6 @@ import ( AST "ast"; Scanner "scanner"; Universe "universe"; - Globals "globals"; - Object "object"; - Type "type"; ) diff --git a/usr/gri/pretty/universe.go b/usr/gri/pretty/universe.go index ed767c2f451..e5a53a9f858 100755 --- a/usr/gri/pretty/universe.go +++ b/usr/gri/pretty/universe.go @@ -6,14 +6,12 @@ package Universe import ( "array"; - Globals "globals"; - Object "object"; - Type "type"; + AST "ast"; ) export var ( - scope *Globals.Scope; + scope *AST.Scope; types array.Array; // internal types @@ -42,19 +40,19 @@ export var ( uint_typ, int_typ, float_typ, - uintptr_typ *Globals.Type; + uintptr_typ *AST.Type; true_obj, false_obj, iota_obj, - nil_obj *Globals.Object; + nil_obj *AST.Object; ) -func DeclObj(kind int, ident string, typ *Globals.Type) *Globals.Object { - obj := Globals.NewObject(-1 /* no source pos */, kind, ident); +func DeclObj(kind int, ident string, typ *AST.Type) *AST.Object { + obj := AST.NewObject(-1 /* no source pos */, kind, ident); obj.typ = typ; - if kind == Object.TYPE && typ.obj == nil { + if kind == AST.TYPE && typ.obj == nil { typ.obj = obj; // set primary type object } scope.Insert(obj); @@ -62,14 +60,14 @@ func DeclObj(kind int, ident string, typ *Globals.Type) *Globals.Object { } -func DeclType(form int, ident string, size int) *Globals.Type { - typ := Globals.NewType(form); +func DeclType(form int, ident string, size int) *AST.Type { + typ := AST.NewType(-1 /* no source pos */, form); typ.size = size; - return DeclObj(Object.TYPE, ident, typ).typ; + return DeclObj(AST.TYPE, ident, typ).typ; } -func Register(typ *Globals.Type) *Globals.Type { +func Register(typ *AST.Type) *AST.Type { typ.ref = types.Len(); types.Push(typ); return typ; @@ -77,49 +75,49 @@ func Register(typ *Globals.Type) *Globals.Type { func init() { - scope = Globals.NewScope(nil); // universe has no parent + scope = AST.NewScope(nil); // universe has no parent types.Init(32); // Interal types - void_typ = Globals.NewType(Type.VOID); - Globals.Universe_void_typ = void_typ; - bad_typ = Globals.NewType(Type.BAD); - nil_typ = Globals.NewType(Type.NIL); + void_typ = AST.NewType(-1 /* no source pos */, AST.VOID); + AST.Universe_void_typ = void_typ; + bad_typ = AST.NewType(-1 /* no source pos */, AST.BADTYPE); + nil_typ = AST.NewType(-1 /* no source pos */, AST.NIL); // Basic types - bool_typ = Register(DeclType(Type.BOOL, "bool", 1)); - uint8_typ = Register(DeclType(Type.UINT, "uint8", 1)); - uint16_typ = Register(DeclType(Type.UINT, "uint16", 2)); - uint32_typ = Register(DeclType(Type.UINT, "uint32", 4)); - uint64_typ = Register(DeclType(Type.UINT, "uint64", 8)); - int8_typ = Register(DeclType(Type.INT, "int8", 1)); - int16_typ = Register(DeclType(Type.INT, "int16", 2)); - int32_typ = Register(DeclType(Type.INT, "int32", 4)); - int64_typ = Register(DeclType(Type.INT, "int64", 8)); - float32_typ = Register(DeclType(Type.FLOAT, "float32", 4)); - float64_typ = Register(DeclType(Type.FLOAT, "float64", 8)); - float80_typ = Register(DeclType(Type.FLOAT, "float80", 10)); - string_typ = Register(DeclType(Type.STRING, "string", 8)); - integer_typ = Register(DeclType(Type.INTEGER, "integer", 8)); + bool_typ = Register(DeclType(AST.BOOL, "bool", 1)); + uint8_typ = Register(DeclType(AST.UINT, "uint8", 1)); + uint16_typ = Register(DeclType(AST.UINT, "uint16", 2)); + uint32_typ = Register(DeclType(AST.UINT, "uint32", 4)); + uint64_typ = Register(DeclType(AST.UINT, "uint64", 8)); + int8_typ = Register(DeclType(AST.INT, "int8", 1)); + int16_typ = Register(DeclType(AST.INT, "int16", 2)); + int32_typ = Register(DeclType(AST.INT, "int32", 4)); + int64_typ = Register(DeclType(AST.INT, "int64", 8)); + float32_typ = Register(DeclType(AST.FLOAT, "float32", 4)); + float64_typ = Register(DeclType(AST.FLOAT, "float64", 8)); + float80_typ = Register(DeclType(AST.FLOAT, "float80", 10)); + string_typ = Register(DeclType(AST.STRING, "string", 8)); + integer_typ = Register(DeclType(AST.INTEGER, "integer", 8)); // All but 'byte' should be platform-dependent, eventually. - byte_typ = Register(DeclType(Type.UINT, "byte", 1)); - uint_typ = Register(DeclType(Type.UINT, "uint", 4)); - int_typ = Register(DeclType(Type.INT, "int", 4)); - float_typ = Register(DeclType(Type.FLOAT, "float", 4)); - uintptr_typ = Register(DeclType(Type.UINT, "uintptr", 8)); + byte_typ = Register(DeclType(AST.UINT, "byte", 1)); + uint_typ = Register(DeclType(AST.UINT, "uint", 4)); + int_typ = Register(DeclType(AST.INT, "int", 4)); + float_typ = Register(DeclType(AST.FLOAT, "float", 4)); + uintptr_typ = Register(DeclType(AST.UINT, "uintptr", 8)); // Predeclared constants - true_obj = DeclObj(Object.CONST, "true", bool_typ); - false_obj = DeclObj(Object.CONST, "false", bool_typ); - iota_obj = DeclObj(Object.CONST, "iota", int_typ); - nil_obj = DeclObj(Object.CONST, "nil", nil_typ); + true_obj = DeclObj(AST.CONST, "true", bool_typ); + false_obj = DeclObj(AST.CONST, "false", bool_typ); + iota_obj = DeclObj(AST.CONST, "iota", int_typ); + nil_obj = DeclObj(AST.CONST, "nil", nil_typ); // Builtin functions - DeclObj(Object.BUILTIN, "len", void_typ); - DeclObj(Object.BUILTIN, "new", void_typ); - DeclObj(Object.BUILTIN, "panic", void_typ); - DeclObj(Object.BUILTIN, "print", void_typ); + DeclObj(AST.BUILTIN, "len", void_typ); + DeclObj(AST.BUILTIN, "new", void_typ); + DeclObj(AST.BUILTIN, "panic", void_typ); + DeclObj(AST.BUILTIN, "print", void_typ); // scope.Print(); }