]> Cypherpunks repositories - gostls13.git/commitdiff
- added more semantic checks - more to come
authorRobert Griesemer <gri@golang.org>
Wed, 6 Aug 2008 01:52:37 +0000 (18:52 -0700)
committerRobert Griesemer <gri@golang.org>
Wed, 6 Aug 2008 01:52:37 +0000 (18:52 -0700)
- distinguish float/int literals syntactically
- fixed a tracing bug

R=r
OCL=13906
CL=13906

usr/gri/gosrc/ast.go
usr/gri/gosrc/globals.go
usr/gri/gosrc/parser.go
usr/gri/gosrc/scanner.go
usr/gri/gosrc/test_scanner.go
usr/gri/gosrc/type.go
usr/gri/gosrc/universe.go

index 8b565e581666d58d3d4d49ad51952821f4729318..4fe91fa1b1920b9aa9aa932df36255b67c9b97b7 100644 (file)
@@ -11,6 +11,61 @@ import Universe "universe"
 // ----------------------------------------------------------------------------
 // Expressions
 
+
+export type Literal struct {
+       typ_ *Globals.Type;
+       b bool;
+       i int;
+       f float;
+       s string;
+}
+
+
+func (x *Literal) typ() *Globals.Type {
+       return x.typ_;
+}
+
+
+export func NewLiteral(typ *Globals.Type) *Literal {
+       x := new(Literal);
+       x.typ_ = typ;
+       return x;
+}
+
+
+export var Bad, True, False, Nil *Literal;
+
+
+// NOTE We could use Globals.Object directly if we'd added a typ()
+// method to its interface. However, this would require renaming the
+// typ field everywhere... - Need to think about accessors again.
+export type Object struct {
+       obj *Globals.Object;
+}
+
+
+func (x *Object) typ() *Globals.Type {
+       return x.obj.typ;
+}
+
+
+export func NewObject(obj* Globals.Object) *Object {
+       x := new(Object);
+       x.obj = obj;
+       return x;
+}
+
+
+export type Selector struct {
+       typ_ *Globals.Type;
+}
+
+
+func (x *Selector) typ() *Globals.Type {
+       return x.typ_;
+}
+
+
 export type BinaryExpr struct {
        typ_ *Globals.Type;
        op int;
@@ -18,7 +73,6 @@ export type BinaryExpr struct {
 }
 
 
-
 func (x *BinaryExpr) typ() *Globals.Type {
        return x.typ_;
 }
@@ -37,3 +91,14 @@ export type IfStat struct {
        then_ Globals.Stat;
        else_ Globals.Stat;
 }
+
+
+// ----------------------------------------------------------------------------
+// Initialization
+
+func init() {
+       Bad = NewLiteral(Universe.bad_t);
+       True = NewLiteral(Universe.bool_t);  True.b = true;
+       False = NewLiteral(Universe.bool_t);  False.b = false;
+       Nil = NewLiteral(Universe.nil_t);
+}
index 3624ede13a6b7363cb64238219c8e662f67e8311..a6695daccd1f193ff812bb9726ddad21a64ef354 100644 (file)
@@ -45,18 +45,6 @@ export type Package struct {
 }
 
 
-// TODO This is hideous! We need to have a decent way to do lists.
-// Ideally open arrays that allow '+'.
-
-type Elem struct {
-       next *Elem;
-       val int;
-       str string;
-       obj *Object;
-       typ *Type;
-}
-
-
 export type List struct {
        len_ int;
        first, last *Elem;
@@ -98,6 +86,19 @@ export type Stat interface {
 }
 
 
+// TODO This is hideous! We need to have a decent way to do lists.
+// Ideally open arrays that allow '+'.
+
+type Elem struct {
+       next *Elem;
+       val int;
+       str string;
+       obj *Object;
+       typ *Type;
+       expr Expr
+}
+
+
 // ----------------------------------------------------------------------------
 // Creation
 
@@ -249,6 +250,11 @@ func (L *List) AddTyp(typ *Type) {
 }
 
 
+func (L *List) AddExpr(expr Expr) {
+       L.Add().expr = expr;
+}
+
+
 // ----------------------------------------------------------------------------
 // Scope methods
 
index 503a4cf51ec638de9d281b66281dad9412163db4..b5a57501a71470e5803677d0fe7a3720465604ba 100644 (file)
@@ -47,14 +47,14 @@ func (P *Parser) Trace(msg string) {
        if P.verbose > 0 {
                P.PrintIndent();
                print msg, " {\n";
-               P.indent++;
        }
+       P.indent++;
 }
 
 
 func (P *Parser) Ecart() {
+       P.indent--;
        if P.verbose > 0 {
-               P.indent--;
                P.PrintIndent();
                print "}\n";
        }
@@ -132,6 +132,9 @@ func (P *Parser) DeclareInScope(scope *Globals.Scope, obj *Globals.Object) {
        if !P.semantic_checks {
                return;
        }
+       if P.level > 0 {
+               panic "cannot declare objects in other packages";
+       }
        obj.pnolev = P.level;
        if scope.Lookup(obj.ident) != nil {
                P.Error(obj.pos, `"` + obj.ident + `" is declared already`);
@@ -200,26 +203,25 @@ func (P *Parser) DeclareFunc(ident string, typ *Globals.Type) *Globals.Object {
                return obj;
        }
 
-       // obj != NULL: possibly a forward declaration.
+       // obj != NULL: possibly a forward declaration
        if obj.kind != Object.FUNC {
                P.Error(-1, `"` + ident + `" is declared already`);
-               // Continue but do not insert this function into the scope.
+               // continue but do not insert this function into the scope
                obj = Globals.NewObject(-1, Object.FUNC, ident);
                obj.typ = typ;
                // TODO do we need to set the primary type? probably...
                return obj;
        }
 
-       // We have a function with the same name.
-       /*
-       if !EqualTypes(type, obj->type()) {
-               this->Error("type of \"%s\" does not match its forward declaration", name.cstr());
-               // Continue but do not insert this function into the scope.
-               NewObject(Object::FUNC, name);
-               obj->set_type(type);
+       // we have a function with the same name
+       if !Type.Equal(typ, obj.typ) {
+               P.Error(-1, `type of "` + ident + `" does not match its forward declaration`);
+               // continue but do not insert this function into the scope
+               obj = Globals.NewObject(-1, Object.FUNC, ident);
+               obj.typ = typ;
+               // TODO do we need to set the primary type? probably...
                return obj;    
        }
-       */
 
        // We have a matching forward declaration. Use it.
        return obj;
@@ -826,12 +828,10 @@ func (P *Parser) ParseExpressionList() *Globals.List {
        P.Trace("ExpressionList");
        
        list := Globals.NewList();
-       P.ParseExpression();
-       list.AddInt(0);  // TODO fix this - add correct list element
+       list.AddExpr(P.ParseExpression());
        for P.tok == Scanner.COMMA {
                P.Next();
-               P.ParseExpression();
-               list.AddInt(0);  // TODO fix this - add correct list element
+               list.AddExpr(P.ParseExpression());
        }
        
        P.Ecart();
@@ -867,23 +867,36 @@ func (P *Parser) ParseFunctionLit() Globals.Expr {
 }
 
 
-func (P *Parser) ParseExpressionPair() {
+func (P *Parser) ParseSingleExpressionList(list *Globals.List) {
+       P.Trace("SingleExpressionList");
+       
+       list.AddExpr(P.ParseExpression());
+       for P.tok == Scanner.COMMA {
+               P.Next();
+               list.AddExpr(P.ParseExpression());
+       }
+       
+       P.Ecart();
+}
+
+
+func (P *Parser) ParseExpressionPair(list *Globals.List) {
        P.Trace("ExpressionPair");
 
-       P.ParseExpression();
+       list.AddExpr(P.ParseExpression());
        P.Expect(Scanner.COLON);
-       P.ParseExpression();
+       list.AddExpr(P.ParseExpression());
        
        P.Ecart();
 }
 
 
-func (P *Parser) ParseExpressionPairList() {
+func (P *Parser) ParseExpressionPairList(list *Globals.List) {
        P.Trace("ExpressionPairList");
 
-       P.ParseExpressionPair();
+       P.ParseExpressionPair(list);
        for (P.tok == Scanner.COMMA) {
-               P.ParseExpressionPair();
+               P.ParseExpressionPair(list);
        }
        
        P.Ecart();
@@ -916,20 +929,21 @@ func (P *Parser) ParseCompositeLit(typ *Globals.Type) Globals.Expr {
        }
        
        // TODO: should allow trailing ','
+       list := Globals.NewList();
        if P.tok != paren {
-               P.ParseExpression();
+               list.AddExpr(P.ParseExpression());
                if P.tok == Scanner.COMMA {
                        P.Next();
                        if P.tok != paren {
-                               P.ParseExpressionList();
+                               P.ParseSingleExpressionList(list);
                        }
                } else if P.tok == Scanner.COLON {
                        P.Next();
-                       P.ParseExpression();
+                       list.AddExpr(P.ParseExpression());
                        if P.tok == Scanner.COMMA {
                                P.Next();
                                if P.tok != paren {
-                                       P.ParseExpressionPairList();
+                                       P.ParseExpressionPairList(list);
                                }
                        }
                }
@@ -951,64 +965,110 @@ func (P *Parser) ParseOperand(pos int, ident string) Globals.Expr {
                ident = P.val;
                P.Next();
        }
-       
+
+       var res Globals.Expr = AST.Bad;
+
        if pos >= 0 {
                // TODO set these up properly in the Universe
                if ident == "panic" || ident == "print" {
-                       P.ParseBuiltinCall();
-                       goto exit;
+                       res = P.ParseBuiltinCall();
+                       
+               } else {
+                       obj := P.ParseQualifiedIdent(pos, ident);
+                       if P.semantic_checks {
+                               if obj.kind == Object.TYPE {
+                                       res = P.ParseCompositeLit(obj.typ);
+                               } else {
+                                       res = AST.NewObject(obj);
+                               }
+                       }
                }
+
+       } else {
        
-               P.ParseQualifiedIdent(pos, ident);
-               // TODO enable code below
-               /*
-               if obj.kind == Object.TYPE {
-                       P.ParseCompositeLit(obj.typ);
+               switch P.tok {
+               case Scanner.IDENT:
+                       panic "UNREACHABLE";
+                       
+               case Scanner.LPAREN:
+                       P.Next();
+                       res = P.ParseExpression();
+                       P.Expect(Scanner.RPAREN);
+                       
+               case Scanner.INT:
+                       x := AST.NewLiteral(Universe.int_t);
+                       x.i = 42;  // TODO set the right value
+                       res = x;
+                       P.Next();
+
+               case Scanner.FLOAT:
+                       x := AST.NewLiteral(Universe.float_t);
+                       x.f = 42.0;  // TODO set the right value
+                       res = x;
+                       P.Next();
+
+               case Scanner.STRING:
+                       x := AST.NewLiteral(Universe.string_t);
+                       x.s = P.val;  // TODO need to strip quotes, interpret string properly
+                       res = x;
+                       P.Next();
+
+               case Scanner.NIL:
+                       P.Next();
+                       res = AST.Nil;
+                       
+               case Scanner.IOTA:
+                       x := AST.NewLiteral(Universe.int_t);
+                       x.i = 42;  // TODO set the right value
+                       res = x;
+                       P.Next();
+
+               case Scanner.TRUE:
+                       P.Next();
+                       res = AST.True;
+
+               case Scanner.FALSE:
+                       P.Next();
+                       res = AST.False;
+                       
+               case Scanner.FUNC:
+                       res = P.ParseFunctionLit();
+                       
+               case Scanner.NEW:
+                       res = P.ParseNew();
+                       
+               default:
+                       typ := P.TryType();
+                       if typ != nil {
+                               res = P.ParseCompositeLit(typ);
+                       } else {
+                               P.Error(P.pos, "operand expected");
+                               P.Next();  // make progress
+                       }
                }
-               */
-               goto exit;
-       }
        
-       switch P.tok {
-       case Scanner.IDENT:
-               panic "UNREACHABLE";
-       case Scanner.LPAREN:
-               P.Next();
-               P.ParseExpression();
-               P.Expect(Scanner.RPAREN);
-       case Scanner.STRING: fallthrough;
-       case Scanner.NUMBER: fallthrough;
-       case Scanner.NIL: fallthrough;
-       case Scanner.IOTA: fallthrough;
-       case Scanner.TRUE: fallthrough;
-       case Scanner.FALSE:
-               P.Next();
-       case Scanner.FUNC:
-               P.ParseFunctionLit();
-       case Scanner.NEW:
-               P.ParseNew();
-       default:
-               typ := P.TryType();
-               if typ != nil {
-                       P.ParseCompositeLit(typ);
-               } else {
-                       P.Error(P.pos, "operand expected");
-                       P.Next();  // make progress
-               }
        }
-       
-exit:
+
        P.Ecart();
-       return nil;
+       return res;
 }
 
 
-func (P *Parser) ParseSelectorOrTypeAssertion() Globals.Expr {
+func (P *Parser) ParseSelectorOrTypeAssertion(x Globals.Expr) Globals.Expr {
        P.Trace("SelectorOrTypeAssertion");
-       
+
+       pos := P.pos;
        P.Expect(Scanner.PERIOD);
+       if P.semantic_checks {
+               typ := x.typ();
+               if typ.form != Type.STRUCT || typ.form != Type.INTERFACE {
+                       P.Error(pos, `"." cannot be applied to this operand`);
+               }
+       }
+       
        if P.tok == Scanner.IDENT {
-               P.ParseIdent();
+               ident := P.ParseIdent();
+               
        } else {
                P.Expect(Scanner.LPAREN);
                P.ParseType();
@@ -1016,11 +1076,11 @@ func (P *Parser) ParseSelectorOrTypeAssertion() Globals.Expr {
        }
        
        P.Ecart();
-       return nil;
+       return x;
 }
 
 
-func (P *Parser) ParseIndexOrSlice() Globals.Expr {
+func (P *Parser) ParseIndexOrSlice(x Globals.Expr) Globals.Expr {
        P.Trace("IndexOrSlice");
        
        P.Expect(Scanner.LBRACK);
@@ -1032,11 +1092,11 @@ func (P *Parser) ParseIndexOrSlice() Globals.Expr {
        P.Expect(Scanner.RBRACK);
        
        P.Ecart();
-       return nil;
+       return x;
 }
 
 
-func (P *Parser) ParseCall() Globals.Expr {
+func (P *Parser) ParseCall(x Globals.Expr) Globals.Expr {
        P.Trace("Call");
        
        P.Expect(Scanner.LPAREN);
@@ -1046,30 +1106,26 @@ func (P *Parser) ParseCall() Globals.Expr {
        P.Expect(Scanner.RPAREN);
        
        P.Ecart();
-       return nil;
+       return x;
 }
 
 
 func (P *Parser) ParsePrimaryExpr(pos int, ident string) Globals.Expr {
        P.Trace("PrimaryExpr");
        
-       P.ParseOperand(pos, ident);
+       x := P.ParseOperand(pos, ident);
        for {
                switch P.tok {
-               case Scanner.PERIOD:
-                       P.ParseSelectorOrTypeAssertion();
-               case Scanner.LBRACK:
-                       P.ParseIndexOrSlice();
-               case Scanner.LPAREN:
-                       P.ParseCall();
-               default:
-                       P.Ecart();
-                       return nil;
+               case Scanner.PERIOD: x = P.ParseSelectorOrTypeAssertion(x);
+               case Scanner.LBRACK: x = P.ParseIndexOrSlice(x);
+               case Scanner.LPAREN: x = P.ParseCall(x);
+               default: goto exit;
                }
        }
-       
+
+exit:
        P.Ecart();
-       return nil;
+       return x;
 }
 
 
@@ -1944,10 +2000,10 @@ func (P *Parser) ParseProgram() {
        obj := P.ParseIdentDecl(Object.PACKAGE);
        P.Optional(Scanner.SEMICOLON);
        
-       {       if P.level != 0 {
+       {       P.OpenScope();
+               if P.level != 0 {
                        panic "incorrect scope level";
                }
-               P.OpenScope();
                
                P.comp.Insert(Globals.NewPackage(P.S.filename, obj, P.top_scope));
                if P.comp.pkg_ref != 1 {
@@ -1966,10 +2022,11 @@ func (P *Parser) ParseProgram() {
                
                P.ResolveUndefTypes();
                P.MarkExports();
-               P.CloseScope();
+               
                if P.level != 0 {
                        panic "incorrect scope level";
                }
+               P.CloseScope();
        }
        
        P.CloseScope();
index 8298b8b340dfac42c404f1d061dee55cf2e1078b..add320e4af8d930dfb9dadb8f838d5c7f3bb362a 100644 (file)
@@ -10,8 +10,9 @@ export const (
        ILLEGAL = iota;
        EOF;
        IDENT;
+       INT;
+       FLOAT;
        STRING;
-       NUMBER;
 
        COMMA;
        COLON;
@@ -116,8 +117,9 @@ export func TokenName(tok int) string {
        case ILLEGAL: return "illegal";
        case EOF: return "eof";
        case IDENT: return "ident";
+       case INT: return "int";
+       case FLOAT: return "float";
        case STRING: return "string";
-       case NUMBER: return "number";
 
        case COMMA: return ",";
        case COLON: return ":";
@@ -537,10 +539,12 @@ func (S *Scanner) ScanMantissa(base int) {
 }
 
 
-func (S *Scanner) ScanNumber(seen_decimal_point bool) string {
+func (S *Scanner) ScanNumber(seen_decimal_point bool) (tok int, val string) {
        pos := S.chpos;
+       tok = INT;
        
        if seen_decimal_point {
+               tok = FLOAT;
                pos--;  // '.' is one byte
                S.ScanMantissa(10);
                goto exponent;
@@ -558,6 +562,7 @@ func (S *Scanner) ScanNumber(seen_decimal_point bool) string {
                        S.ScanMantissa(8);
                        if digit_val(S.ch) < 10 || S.ch == '.' || S.ch == 'e' || S.ch == 'E' {
                                // float
+                               tok = FLOAT;
                                goto mantissa;
                        }
                        // octal int
@@ -571,6 +576,7 @@ mantissa:
        
        if S.ch == '.' {
                // float
+               tok = FLOAT;
                S.Next();
                S.ScanMantissa(10)
        }
@@ -578,6 +584,7 @@ mantissa:
 exponent:
        if S.ch == 'e' || S.ch == 'E' {
                // float
+               tok = FLOAT;
                S.Next();
                if S.ch == '-' || S.ch == '+' {
                        S.Next();
@@ -586,7 +593,7 @@ exponent:
        }
        
 exit:
-       return S.src[pos : S.chpos];
+       return tok, S.src[pos : S.chpos];
 }
 
 
@@ -735,18 +742,18 @@ func (S *Scanner) Scan() (tok, pos int, val string) {
        
        switch {
        case is_letter(ch): tok, val = S.ScanIdentifier();
-       case digit_val(ch) < 10: tok, val = NUMBER, S.ScanNumber(false);
+       case digit_val(ch) < 10: tok, val = S.ScanNumber(false);
        default:
                S.Next();  // always make progress
                switch ch {
                case -1: tok = EOF;
                case '"': tok, val = STRING, S.ScanString();
-               case '\'': tok, val = NUMBER, S.ScanChar();
+               case '\'': tok, val = INT, S.ScanChar();
                case '`': tok, val = STRING, S.ScanRawString();
                case ':': tok = S.Select2(COLON, DEFINE);
                case '.':
                        if digit_val(S.ch) < 10 {
-                               tok, val = NUMBER, S.ScanNumber(true);
+                               tok, val = S.ScanNumber(true);
                        } else {
                                tok = PERIOD;
                        }
index 931adb9bc68c6a72c86f07839900cb6132e2456a..2ce097fd1990e33462838beeb06ba2d884d6860b 100644 (file)
@@ -13,7 +13,7 @@ func Scan(filename, src string) {
        for {
                tok, pos, val := S.Scan();
                print pos, ": ", Scanner.TokenName(tok);
-               if tok == Scanner.IDENT || tok == Scanner.NUMBER || tok == Scanner.STRING {
+               if tok == Scanner.IDENT || tok == Scanner.INT || tok == Scanner.FLOAT || tok == Scanner.STRING {
                        print " ", val;
                }
                print "\n";
index 1f8a0b1d2e709b0aa463af8f1c837f7d1ea3afcd..b872a1cda645f0748b2a300f2e9c3e3701d17fdd 100644 (file)
@@ -4,11 +4,15 @@
 
 package Type
 
+import Globals "globals"
+import Object "object"
+
+
 export const /* form */ (
        // internal types
-       UNDEF = iota; BAD; NIL;
+       UNDEF = iota; VOID; BAD; NIL;
        // basic types
-       BOOL; UINT; INT; FLOAT; STRING;
+       BOOL; UINT; INT; FLOAT; STRING; INTEGER;
        // 'any' type
        ANY;
        // composite types
@@ -30,6 +34,7 @@ export const /* flag */ (
 export func FormStr(form int) string {
        switch form {
        case UNDEF: return "UNDEF";
+       case VOID: return "VOID";
        case BAD: return "BAD";
        case NIL: return "NIL";
        case BOOL: return "BOOL";
@@ -50,3 +55,111 @@ export func FormStr(form int) string {
        }
        return "<unknown Type form>";
 }
+
+
+export func Equal(x, y *Globals.Type) bool;
+
+func Equal0(x, y *Globals.Type) bool {
+       if x == y {
+               return true;  // identical types are equal
+       }
+
+       if x.form == BAD || y.form == BAD {
+               return true;  // bad types are always equal (avoid excess error messages)
+       }
+
+       // TODO where to check for *T == nil ?  
+       if x.form != y.form {
+               return false;  // types of different forms are not equal
+       }
+
+       switch x.form {
+       case UNDEF, BAD:
+               break;
+
+       case NIL, BOOL, STRING, ANY:
+               return true;
+
+       case UINT, INT, FLOAT:
+               return x.size == y.size;
+
+       case ARRAY:
+               return
+                       x.len_ == y.len_ &&
+                       Equal(x.elt, y.elt);
+
+       case MAP:
+               return
+                       Equal(x.aux, y.aux) &&
+                       Equal(x.elt, y.elt);
+
+       case CHANNEL:
+               return
+                       x.flags == y.flags &&
+                       Equal(x.elt, y.elt);
+
+       case FUNCTION:
+               {       xp := x.scope.entries;
+                       yp := x.scope.entries;
+                       if      x.flags != y.flags &&  // function or method
+                               x.len_ != y.len_ &&  // number of parameters
+                               xp.len_ != yp.len_  // recv + parameters + results
+                       {
+                               return false;
+                       }
+                       for p, q := xp.first, yp.first; p != nil; p, q = p.next, q.next {
+                               xf := p.obj;
+                               yf := q.obj;
+                               if xf.kind != Object.VAR || yf.kind != Object.VAR {
+                                       panic "parameters must be vars";
+                               }
+                               if !Equal(xf.typ, yf.typ) {
+                                       return false;
+                               }
+                       }
+               }
+               return true;
+
+       case STRUCT:
+               /*
+               {       ObjList* xl = &x.scope.list;
+                       ObjList* yl = &y.scope.list;
+                       if xl.len() != yl.len() {
+                               return false;  // scopes of different sizes are not equal
+                       }
+                       for int i = xl.len(); i-- > 0; {
+                               Object* xf = (*xl)[i];
+                               Object* yf = (*yl)[i];
+                               ASSERT(xf.kind == Object.VAR && yf.kind == Object.VAR);
+                               if xf.name != yf.name) || ! EqualTypes(xf.type(), yf.type() {
+                                       return false;
+                               }
+                       }
+               }
+               return true;
+               */
+               // Scopes must be identical for them to be equal.
+               // If we reach here, they weren't.
+               return false;
+
+       case INTERFACE:
+               panic "UNIMPLEMENTED";
+               return false;
+
+       case POINTER, REFERENCE:
+               return Equal(x.elt, y.elt);
+       }
+
+       panic "UNREACHABLE";
+       return false;
+}
+
+
+export func Equal(x, y *Globals.Type) bool {
+       res := Equal0(x, y);
+       // TODO should do the check below only in debug mode
+       if Equal0(y, x) != res {
+               panic "type equality must be symmetric";
+       }
+       return res;
+}
index c167e67d07abbd0f7495c4d54d3e5334e404781e..9d9944288415a969da9860442faa26f13e3a26d9 100755 (executable)
@@ -32,6 +32,7 @@ export var (
        float64_t,
        float80_t,
        string_t,
+       integer_t,
        any_t,
        
        // alias types
@@ -111,6 +112,7 @@ func init() {
        float64_t = Register(DeclType(Type.FLOAT, "float64", 8));
        float80_t = Register(DeclType(Type.FLOAT, "float80", 10));
        string_t = Register(DeclType(Type.STRING, "string", 8));
+       integer_t = Register(DeclType(Type.INTEGER, "integer", 8));
        any_t = Register(DeclType(Type.ANY, "any", 8));
 
        // All but 'byte' should be platform-dependent, eventually.