1
0
mirror of https://github.com/golang/go synced 2024-11-22 10:44:41 -07:00

- 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
This commit is contained in:
Robert Griesemer 2009-01-09 16:28:09 -08:00
parent 0c32430534
commit c620dd9759
8 changed files with 361 additions and 144 deletions

View 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) $<

View 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;

View 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;

View 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;

View 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);

View File

@ -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
}

View File

@ -8,9 +8,6 @@ import (
AST "ast";
Scanner "scanner";
Universe "universe";
Globals "globals";
Object "object";
Type "type";
)

View File

@ -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();
}