]> Cypherpunks repositories - gostls13.git/commitdiff
- preparation to add type info to ast
authorRobert Griesemer <gri@golang.org>
Sat, 10 Jan 2009 00:28:09 +0000 (16:28 -0800)
committerRobert Griesemer <gri@golang.org>
Sat, 10 Jan 2009 00:28:09 +0000 (16:28 -0800)
- 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
usr/gri/pretty/ast.go
usr/gri/pretty/parser.go
usr/gri/pretty/printer.go
usr/gri/pretty/scanner.go
usr/gri/pretty/test.sh
usr/gri/pretty/typechecker.go
usr/gri/pretty/universe.go

index 82a25b03fbe4d46687998381375b4f640873db68..2b5883a87460ac931a4b3cfb4c410dda8e4fb0ca 100644 (file)
@@ -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) $<
index ad1edaeb236b8b2794b7553755d0146466afcc56..0f0dd6a1f542ca9ac1e8501d69852a75c1872df1 100644 (file)
@@ -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 "<unknown Object kind>";
+}
+
+
+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 "<unknown Type form>";
+}
+
+
 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;
index 7831ca8ec6d7206dcce72bd362b1995e13ff7571..6b1bb43398b10b4559f40b3acd72d87502aca4d0 100644 (file)
@@ -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;
index 2afc95cedf9c263705fff4a3e1d33efadf9ef0bb..8da1a847b5fcf814f9ce2ef3421e33b4973894c0 100644 (file)
@@ -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;
index 87f67133a58cd11eceba66061929fd4b0c596f2a..9b56e329b1dc1cb066fe6c77cd8c75e6869efd1b 100644 (file)
@@ -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);
index b248616ff3e1a22e9af75a9139162494c6eb93a3..44d99946d0591c0291a876dc9f25823f9541b2aa 100755 (executable)
@@ -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
 }
index b2e6ae6f3de9a9da8a2ca20fa6635369f755e3e4..c48588b5c26dd53701aed9ee1c173b958d2648f1 100644 (file)
@@ -8,9 +8,6 @@ import (
        AST "ast";
        Scanner "scanner";
        Universe "universe";
-       Globals "globals";
-       Object "object";
-       Type "type";
 )
 
 
index ed767c2f451ef93f2936c51520b8c501c49aa6e1..e5a53a9f8585b2e47935b4e224d29235635a78fc 100755 (executable)
@@ -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();
 }