compilation.6: platform.6 scanner.6 parser.6 ast.6 typechecker.6
-ast.6: scanner.6
+typechecker.6: ast.6 scanner.6
scanner.6: utils.6
-parser.6: scanner.6 ast.6
+ast.6: scanner.6 symboltable.6
-platform.6: utils.6
+symboltable.6:
-printer.6: scanner.6 ast.6 utils.6
+parser.6: scanner.6 ast.6 symboltable.6
-typechecker.6: ast.6 universe.6
+platform.6: utils.6
-universe.6: ast.6
+printer.6: utils.6 scanner.6 ast.6 symboltable.6
%.6: %.go
$(G) $(F) $<
import (
"array";
- "utf8";
- "unicode";
Scanner "scanner";
+ SymbolTable "symboltable";
)
type (
- Object struct;
- Type struct;
-
Block struct;
Expr interface;
Decl struct;
}
-// ----------------------------------------------------------------------------
-// Objects
-
-// Object represents a language object, such as a constant, variable, type, etc.
-
-const /* kind */ (
- BADOBJ = iota; // error handling
- NONE; // kind unknown
- CONST; TYPE; VAR; FIELD; FUNC; BUILTIN; PACKAGE; LABEL;
- END; // end of scope (import/export only)
-)
-
-
-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>";
-}
-
-
-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
- Body *Block; // function body
-}
-
-
-func (obj *Object) IsExported() bool {
- switch obj.Kind {
- case NONE /* FUNC for now */, CONST, TYPE, VAR, FUNC:
- ch, size := utf8.DecodeRuneInString(obj.Ident, 0);
- return unicode.IsUpper(ch);
- }
- return false;
-}
-
-
-func (obj* Object) String() string {
- if obj != nil {
- return
- "Object(" +
- KindStr(obj.Kind) + ", " +
- obj.Ident +
- ")";
- }
- return "nil";
-}
-
-
-var Universe_void_typ *Type // initialized by Universe to Universe.void_typ
-var objectId int;
-
-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; // TODO would it be better to use nil instead?
- obj.Pnolev = 0;
-
- return obj;
-}
-
-
// ----------------------------------------------------------------------------
// All nodes have a source position and a token.
}
-// ----------------------------------------------------------------------------
-// Scopes
-
-type Scope struct {
- Parent *Scope;
- entries map[string] *Object;
-}
-
-
-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");
-}
-
-
// ----------------------------------------------------------------------------
// Types
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;
+ BADTYPE = iota;
// A type name
TYPENAME;
- // basic types
- BOOL; UINT; INT; FLOAT; STRING; INTEGER;
-
// composite types
- ALIAS; ARRAY; STRUCT; INTERFACE; MAP; CHANNEL; FUNCTION; METHOD; POINTER;
+ ARRAY; STRUCT; INTERFACE; MAP; CHANNEL; FUNCTION; POINTER;
// open-ended parameter type
ELLIPSIS
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";
}
type Type struct {
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 nil
- Scope *Scope; // locals, fields & methods
+ Scope *SymbolTable.Scope; // locals, fields & methods
// syntactic components
Pos int; // source position (< 0 if unknown position)
typ.Id = typeId;
typeId++;
- typ.Ref = -1; // not yet exported
typ.Pos = pos;
typ.Form = form;
Ident struct {
Pos_ int;
- Obj *Object;
+ Obj *SymbolTable.Object;
};
BinaryExpr struct {
import (
"array";
"utf8";
- OS "os";
+ "fmt";
+ "os";
Platform "platform";
Scanner "scanner";
Parser "parser";
Deps bool;
Columns bool;
Testmode bool;
- Tokenchan bool;
}
var scanner Scanner.Scanner;
scanner.Init(&err, src, true, flags.Testmode);
- var tstream <-chan *Scanner.Token;
- if flags.Tokenchan {
- tstream = scanner.TokenStream();
- }
-
var parser Parser.Parser;
- parser.Open(flags.Verbose, flags.Sixg, flags.Deps, &scanner, tstream);
+ parser.Open(flags.Verbose, flags.Sixg, flags.Deps, &scanner);
prog := parser.ParseProgram();
func fileExists(name string) bool {
- fd, err := OS.Open(name, OS.O_RDONLY, 0);
- if err == nil {
- fd.Close();
- return true;
+ fd, err := os.Open(name, os.O_RDONLY, 0);
+ defer fd.Close();
+ return err == nil;
+}
+
+
+func printDep(localset map [string] bool, wset *array.Array, decl *AST.Decl) {
+ src := decl.Val.(*AST.BasicLit).Val;
+ src = src[1 : len(src) - 1]; // strip "'s
+
+ // ignore files when they are seen a 2nd time
+ dummy, found := localset[src];
+ if !found {
+ localset[src] = true;
+ if fileExists(src + ".go") {
+ wset.Push(src);
+ fmt.Printf(" %s.6", src);
+ } else if
+ fileExists(Platform.GOROOT + "/pkg/" + src + ".6") ||
+ fileExists(Platform.GOROOT + "/pkg/" + src + ".a") {
+
+ } else {
+ // TODO should collect these and print later
+ //print("missing file: ", src, "\n");
+ }
}
- return false;
}
func addDeps(globalset map [string] bool, wset *array.Array, src_file string, flags *Flags) {
- panic();
- /*
dummy, found := globalset[src_file];
if !found {
globalset[src_file] = true;
nimports := prog.Decls.Len();
if nimports > 0 {
- print(src_file, ".6:\t");
+ fmt.Printf("%s.6:\t", src_file);
localset := make(map [string] bool);
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.Obj.Ident;
- src = src[1 : len(src) - 1]; // strip "'s
-
- // ignore files when they are seen a 2nd time
- dummy, found := localset[src];
- if !found {
- localset[src] = true;
- if fileExists(src + ".go") {
- wset.Push(src);
- print(" ", src, ".6");
- } else if
- fileExists(Platform.GOROOT + "/pkg/" + src + ".6") ||
- fileExists(Platform.GOROOT + "/pkg/" + src + ".a") {
-
- } else {
- // TODO should collect these and print later
- //print("missing file: ", src, "\n");
+ assert(decl.Tok == Scanner.IMPORT);
+ if decl.List == nil {
+ printDep(localset, wset, decl);
+ } else {
+ for j := 0; j < decl.List.Len(); j++ {
+ printDep(localset, wset, decl.List.At(j).(*AST.Decl));
}
}
}
print("\n\n");
}
}
- */
}
func ComputeDeps(src_file string, flags *Flags) {
+ // string ".go" extension, if any
+ { n := len(src_file);
+ if src_file[n-3 : n] == ".go" {
+ src_file = src_file[0 : n-3];
+ }
+ }
+ // compute deps
globalset := make(map [string] bool);
wset := array.New(0);
wset.Push(src_file);
"array";
Scanner "scanner";
AST "ast";
+ SymbolTable "symboltable";
)
// Scanner
scanner *Scanner.Scanner;
- tokchan <-chan *Scanner.Token;
comments *array.Array;
// Scanner.Token
scope_lev int; // 0 = global scope, 1 = function scope of global functions, etc.
// Scopes
- top_scope *AST.Scope;
+ top_scope *SymbolTable.Scope;
};
func (P *Parser) printIndent() {
i := P.indent;
- // reduce tracing time by a factor of 2
+ // reduce printing time by a factor of 2 or more
for ; i > 10; i -= 10 {
fmt.Printf(". . . . . . . . . . ");
}
func (P *Parser) next0() {
- if P.tokchan == nil {
- P.pos, P.tok, P.val = P.scanner.Scan();
- } else {
- t := <-P.tokchan;
- P.tok, P.pos, P.val = t.Tok, t.Pos, t.Val;
- }
+ P.pos, P.tok, P.val = P.scanner.Scan();
P.opt_semi = false;
if P.trace {
}
-func (P *Parser) Open(trace, sixg, deps bool, scanner *Scanner.Scanner, tokchan <-chan *Scanner.Token) {
+func (P *Parser) Open(trace, sixg, deps bool, scanner *Scanner.Scanner) {
P.trace = trace;
P.sixg = sixg;
P.deps = deps;
P.indent = 0;
P.scanner = scanner;
- P.tokchan = tokchan;
P.comments = array.New(0);
P.next();
// Scopes
func (P *Parser) openScope() {
- P.top_scope = AST.NewScope(P.top_scope);
+ P.top_scope = SymbolTable.NewScope(P.top_scope);
}
}
-func (P *Parser) declareInScope(scope *AST.Scope, x AST.Expr, kind int, typ *AST.Type) {
+func (P *Parser) declareInScope(scope *SymbolTable.Scope, x AST.Expr, kind int, typ *AST.Type) {
if P.scope_lev < 0 {
panic("cannot declare objects in other packages");
}
if ident, ok := x.(*AST.Ident); ok { // ignore bad exprs
obj := ident.Obj;
obj.Kind = kind;
- obj.Typ = typ;
+ //TODO fix typ setup!
+ //obj.Typ = typ;
obj.Pnolev = P.scope_lev;
switch {
case scope.LookupLocal(obj.Ident) == nil:
scope.Insert(obj);
- case kind == AST.TYPE:
+ case kind == SymbolTable.TYPE:
// possibly a forward declaration
- case kind == AST.FUNC:
+ case kind == SymbolTable.FUNC:
// possibly a forward declaration
default:
P.error(obj.Pos, `"` + obj.Ident + `" is declared already`);
// If scope != nil, lookup identifier in scope. Otherwise create one.
-func (P *Parser) parseIdent(scope *AST.Scope) *AST.Ident {
+func (P *Parser) parseIdent(scope *SymbolTable.Scope) *AST.Ident {
if P.trace {
defer un(trace(P, "Ident"));
}
if P.tok == Scanner.IDENT {
- var obj *AST.Object;
+ var obj *SymbolTable.Object;
if scope != nil {
obj = scope.Lookup(P.val);
}
if obj == nil {
- obj = AST.NewObject(P.pos, AST.NONE, P.val);
+ obj = SymbolTable.NewObject(P.pos, SymbolTable.NONE, P.val);
} else {
- assert(obj.Kind != AST.NONE);
+ assert(obj.Kind != SymbolTable.NONE);
}
x := &AST.Ident{P.pos, obj};
P.next();
P.next();
t.List = array.New(0);
- t.Scope = AST.NewScope(nil);
+ t.Scope = SymbolTable.NewScope(nil);
for P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
P.parseVarList(t.List, false);
if P.tok == Scanner.STRING {
// enter fields into struct scope
for i, n := 0, t.List.Len(); i < n; i++ {
if x, ok := t.List.At(i).(*AST.Ident); ok {
- P.declareInScope(t.Scope, x, AST.FIELD, nil);
+ P.declareInScope(t.Scope, x, SymbolTable.FIELD, nil);
}
}
}
if ftyp.List != nil {
for i, n := 0, ftyp.List.Len(); i < n; i++ {
if x, ok := ftyp.List.At(i).(*AST.Ident); ok {
- P.declareInScope(P.top_scope, x, AST.VAR, nil);
+ P.declareInScope(P.top_scope, x, SymbolTable.VAR, nil);
}
}
}
func (P *Parser) parseSpec(d *AST.Decl) {
- kind := AST.NONE;
+ kind := SymbolTable.NONE;
switch d.Tok {
- case Scanner.IMPORT: P.parseImportSpec(d); kind = AST.PACKAGE;
- case Scanner.CONST: P.parseConstSpec(d); kind = AST.CONST;
- case Scanner.TYPE: P.parseTypeSpec(d); kind = AST.TYPE;
- case Scanner.VAR: P.parseVarSpec(d); kind = AST.VAR;
+ case Scanner.IMPORT: P.parseImportSpec(d); kind = SymbolTable.PACKAGE;
+ case Scanner.CONST: P.parseConstSpec(d); kind = SymbolTable.CONST;
+ case Scanner.TYPE: P.parseTypeSpec(d); kind = SymbolTable.TYPE;
+ case Scanner.VAR: P.parseVarSpec(d); kind = SymbolTable.VAR;
default: unreachable();
}
func init() {
Flag.BoolVar(&flags.Verbose, "v", false, "verbose mode: trace parsing");
Flag.BoolVar(&flags.Sixg, "6g", true, "6g compatibility mode");
- //TODO fix this code again
- //Flag.BoolVar(&flags.Deps, "d", false, "print dependency information only");
+ Flag.BoolVar(&flags.Deps, "d", false, "print dependency information only");
Flag.BoolVar(&flags.Columns, "columns", Platform.USER == "gri", "print column info in error messages");
Flag.BoolVar(&flags.Testmode, "t", false, "test mode: interprets /* ERROR */ and /* SYNC */ comments");
- Flag.BoolVar(&flags.Tokenchan, "token_chan", false, "use token channel for scanner-parser connection");
}
for i := 0; i < Flag.NArg(); i++ {
src_file := Flag.Arg(i);
- if false /* DISABLED flags.deps */ {
+ if flags.Deps {
Compilation.ComputeDeps(src_file, &flags);
} else {
Utils "utils";
Scanner "scanner";
AST "ast";
+ SymbolTable "symboltable";
)
var (
func (P *Printer) HtmlIdentifier(x *AST.Ident) {
obj := x.Obj;
- if *html && obj.Kind != AST.NONE {
+ if *html && obj.Kind != SymbolTable.NONE {
// depending on whether we have a declaration or use, generate different html
// - no need to htmlEscape ident
id := Utils.IntToString(obj.Id, 10);
TYPE;
VAR;
keywords_end;
-
- // AST use only
- EXPRSTAT;
)
case SWITCH: return "switch";
case TYPE: return "type";
case VAR: return "var";
-
- case EXPRSTAT: return "EXPRSTAT";
}
return "token(" + Utils.IntToString(tok, 10) + ")";
return pos, tok, val;
}
-
-
-type Token struct {
- Pos int;
- Tok int;
- Val string;
-}
-
-
-func (S *Scanner) TokenStream() <-chan *Token {
- ch := make(chan *Token, 100);
- go func(S *Scanner, ch chan <- *Token) {
- for {
- t := new(Token);
- t.Pos, t.Tok, t.Val = S.Scan();
- ch <- t;
- if t.Tok == EOF {
- break;
- }
- }
- }(S, ch);
- return ch;
-}
--- /dev/null
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package SymbolTable
+
+import (
+ "utf8";
+ "unicode";
+ "array";
+)
+
+
+type Type struct;
+
+
+// ----------------------------------------------------------------------------
+// Support
+
+func assert(pred bool) {
+ if !pred {
+ panic("assertion failed");
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// Objects
+
+// Object represents a language object, such as a constant, variable, type, etc.
+
+const /* kind */ (
+ BADOBJ = iota; // error handling
+ NONE; // kind unknown
+ CONST; TYPE; VAR; FIELD; FUNC; BUILTIN; PACKAGE; LABEL;
+ END; // end of scope (import/export only)
+)
+
+
+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>";
+}
+
+
+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
+}
+
+
+func (obj *Object) IsExported() bool {
+ switch obj.Kind {
+ case NONE /* FUNC for now */, CONST, TYPE, VAR, FUNC:
+ ch, size := utf8.DecodeRuneInString(obj.Ident, 0);
+ return unicode.IsUpper(ch);
+ }
+ return false;
+}
+
+
+func (obj* Object) String() string {
+ if obj != nil {
+ return
+ "Object(" +
+ KindStr(obj.Kind) + ", " +
+ obj.Ident +
+ ")";
+ }
+ return "nil";
+}
+
+
+var Universe_void_typ *Type // initialized by Universe to Universe.void_typ
+var objectId int;
+
+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; // TODO would it be better to use nil instead?
+ obj.Pnolev = 0;
+
+ return obj;
+}
+
+
+// ----------------------------------------------------------------------------
+// Scopes
+
+type Scope struct {
+ Parent *Scope;
+ entries map[string] *Object;
+}
+
+
+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");
+}
+
+
+// ----------------------------------------------------------------------------
+// Types
+
+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
+)
+
+
+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>";
+}
+
+
+const /* channel mode */ (
+ FULL = iota;
+ SEND;
+ RECV;
+)
+
+
+type Type struct {
+ 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 nil
+ Scope *Scope; // locals, fields & methods
+
+ // syntactic components
+ Pos int; // source position (< 0 if unknown position)
+ Len int; // array length
+ Mode int; // channel mode
+ Key *Type; // receiver type or map key
+ Elt *Type; // type name 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;
+
+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 (typ* Type) String() string {
+ if typ != nil {
+ return
+ "Type(" +
+ FormStr(typ.Form) +
+ ")";
+ }
+ return "nil";
+}
+
+
+// ----------------------------------------------------------------------------
+// Universe scope
+
+var (
+ Universe *Scope;
+ PredeclaredTypes array.Array;
+
+ // internal types
+ Void_typ,
+ Bad_typ,
+ Nil_typ,
+
+ // basic types
+ Bool_typ,
+ Uint8_typ,
+ Uint16_typ,
+ Uint32_typ,
+ Uint64_typ,
+ Int8_typ,
+ Int16_typ,
+ Int32_typ,
+ Int64_typ,
+ Float32_typ,
+ Float64_typ,
+ Float80_typ,
+ String_typ,
+ Integer_typ,
+
+ // convenience types
+ Byte_typ,
+ Uint_typ,
+ Int_typ,
+ Float_typ,
+ Uintptr_typ *Type;
+
+ True_obj,
+ False_obj,
+ Iota_obj,
+ Nil_obj *Object;
+)
+
+
+func declObj(kind int, ident string, typ *Type) *Object {
+ obj := NewObject(-1 /* no source pos */, kind, ident);
+ obj.Typ = typ;
+ if kind == TYPE && typ.Obj == nil {
+ typ.Obj = obj; // set primary type object
+ }
+ Universe.Insert(obj);
+ return obj
+}
+
+
+func declType(form int, ident string, size int) *Type {
+ typ := NewType(-1 /* no source pos */, form);
+ typ.Size = size;
+ return declObj(TYPE, ident, typ).Typ;
+}
+
+
+func register(typ *Type) *Type {
+ typ.Ref = PredeclaredTypes.Len();
+ PredeclaredTypes.Push(typ);
+ return typ;
+}
+
+
+func init() {
+ Universe = NewScope(nil); // universe has no parent
+ PredeclaredTypes.Init(32);
+
+ // Interal types
+ Void_typ = NewType(-1 /* no source pos */, VOID);
+ Universe_void_typ = Void_typ;
+ Bad_typ = NewType(-1 /* no source pos */, BADTYPE);
+ Nil_typ = NewType(-1 /* no source pos */, NIL);
+
+ // Basic types
+ Bool_typ = register(declType(BOOL, "bool", 1));
+ Uint8_typ = register(declType(UINT, "uint8", 1));
+ Uint16_typ = register(declType(UINT, "uint16", 2));
+ Uint32_typ = register(declType(UINT, "uint32", 4));
+ Uint64_typ = register(declType(UINT, "uint64", 8));
+ Int8_typ = register(declType(INT, "int8", 1));
+ Int16_typ = register(declType(INT, "int16", 2));
+ Int32_typ = register(declType(INT, "int32", 4));
+ Int64_typ = register(declType(INT, "int64", 8));
+ Float32_typ = register(declType(FLOAT, "float32", 4));
+ Float64_typ = register(declType(FLOAT, "float64", 8));
+ Float80_typ = register(declType(FLOAT, "float80", 10));
+ String_typ = register(declType(STRING, "string", 8));
+ Integer_typ = register(declType(INTEGER, "integer", 8));
+
+ // All but 'byte' should be platform-dependent, eventually.
+ Byte_typ = register(declType(UINT, "byte", 1));
+ Uint_typ = register(declType(UINT, "uint", 4));
+ Int_typ = register(declType(INT, "int", 4));
+ Float_typ = register(declType(FLOAT, "float", 4));
+ Uintptr_typ = register(declType(UINT, "uintptr", 8));
+
+ // Predeclared constants
+ True_obj = declObj(CONST, "true", Bool_typ);
+ False_obj = declObj(CONST, "false", Bool_typ);
+ Iota_obj = declObj(CONST, "iota", Int_typ);
+ Nil_obj = declObj(CONST, "nil", Nil_typ);
+
+ // Builtin functions
+ declObj(BUILTIN, "len", Void_typ);
+ declObj(BUILTIN, "new", Void_typ);
+ declObj(BUILTIN, "panic", Void_typ);
+ declObj(BUILTIN, "print", Void_typ);
+
+ // scope.Print();
+}
import (
AST "ast";
Scanner "scanner";
- Universe "universe";
)
+++ /dev/null
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package Universe
-
-import (
- "array";
- AST "ast";
-)
-
-
-var (
- Scope *AST.Scope;
- Types array.Array;
-
- // internal types
- Void_typ,
- Bad_typ,
- Nil_typ,
-
- // basic types
- Bool_typ,
- Uint8_typ,
- Uint16_typ,
- Uint32_typ,
- Uint64_typ,
- Int8_typ,
- Int16_typ,
- Int32_typ,
- Int64_typ,
- Float32_typ,
- Float64_typ,
- Float80_typ,
- String_typ,
- Integer_typ,
-
- // convenience types
- Byte_typ,
- Uint_typ,
- Int_typ,
- Float_typ,
- Uintptr_typ *AST.Type;
-
- True_obj,
- False_obj,
- Iota_obj,
- Nil_obj *AST.Object;
-)
-
-
-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 == AST.TYPE && typ.Obj == nil {
- typ.Obj = obj; // set primary type object
- }
- Scope.Insert(obj);
- return obj
-}
-
-
-func declType(form int, ident string, size int) *AST.Type {
- typ := AST.NewType(-1 /* no source pos */, form);
- typ.Size = size;
- return declObj(AST.TYPE, ident, typ).Typ;
-}
-
-
-func register(typ *AST.Type) *AST.Type {
- typ.Ref = Types.Len();
- Types.Push(typ);
- return typ;
-}
-
-
-func init() {
- Scope = AST.NewScope(nil); // universe has no parent
- Types.Init(32);
-
- // Interal types
- 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(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(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(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(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();
-}