Commit c620dd97 authored by Robert Griesemer's avatar Robert Griesemer

- 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
parent 0c324305
...@@ -29,23 +29,19 @@ pretty.6: platform.6 printer.6 compilation.6 ...@@ -29,23 +29,19 @@ pretty.6: platform.6 printer.6 compilation.6
compilation.6: platform.6 scanner.6 parser.6 ast.6 typechecker.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 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 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 universe.6: ast.6
object.6: globals.6
type.6: globals.6 object.6
%.6: %.go %.6: %.go
$(G) $(F) $< $(G) $(F) $<
...@@ -6,20 +6,154 @@ package AST ...@@ -6,20 +6,154 @@ package AST
import ( import (
"array"; "array";
Globals "globals";
Object "object";
Scanner "scanner"; Scanner "scanner";
) )
type ( type (
Object struct;
Type struct; Type struct;
Expr struct; Expr struct;
Stat struct; Stat struct;
Decl 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. // All nodes have a source position and and token.
...@@ -35,7 +169,7 @@ export type Node struct { ...@@ -35,7 +169,7 @@ export type Node struct {
export type Expr struct { export type Expr struct {
Node; Node;
x, y *Expr; // binary (x, y) and unary (y) expressions x, y *Expr; // binary (x, y) and unary (y) expressions
obj *Globals.Object; obj *Object;
// TODO this one should go as well // TODO this one should go as well
t *Type; // type expressions, function literal types t *Type; // type expressions, function literal types
...@@ -64,7 +198,7 @@ export func NewExpr(pos, tok int, x, y *Expr) *Expr { ...@@ -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 := new(Expr);
e.pos, e.tok, e.obj = pos, tok, obj; e.pos, e.tok, e.obj = pos, tok, obj;
return e; return e;
...@@ -77,6 +211,74 @@ export var BadExpr = NewExpr(0, Scanner.ILLEGAL, nil, nil); ...@@ -77,6 +211,74 @@ export var BadExpr = NewExpr(0, Scanner.ILLEGAL, nil, nil);
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Types // 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 */ ( export const /* channel mode */ (
FULL = iota; FULL = iota;
SEND; SEND;
...@@ -85,15 +287,39 @@ export const /* channel mode */ ( ...@@ -85,15 +287,39 @@ export const /* channel mode */ (
export type Type struct { 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 expr *Expr; // type name, array length
mode int; // channel mode mode int; // channel mode
key *Type; // receiver type, map key key *Type; // receiver type or map key
elt *Type; // array element, map or channel value, or pointer base type, result type elt *Type; // array, map, channel or pointer element type, function result type
list *array.Array; end int; // struct fields, interface methods, function parameters 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 { func (t *Type) nfields() int {
if t.list == nil { if t.list == nil {
return 0; return 0;
...@@ -113,14 +339,7 @@ func (t *Type) nfields() int { ...@@ -113,14 +339,7 @@ func (t *Type) nfields() int {
} }
export func NewType(pos, tok int) *Type { // requires complete Type.pos access
t := new(Type);
t.pos, t.tok = pos, tok;
return t;
}
// requires complete Type type
export func NewTypeExpr(t *Type) *Expr { export func NewTypeExpr(t *Type) *Expr {
e := new(Expr); e := new(Expr);
e.pos, e.tok, e.t = t.pos, Scanner.TYPE, t; e.pos, e.tok, e.t = t.pos, Scanner.TYPE, t;
......
...@@ -4,11 +4,11 @@ ...@@ -4,11 +4,11 @@
package Parser package Parser
import "array" import (
import Globals "globals" "array";
import Object "object" Scanner "scanner";
import Scanner "scanner" AST "ast";
import AST "ast" )
export type Parser struct { export type Parser struct {
...@@ -34,7 +34,7 @@ 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. scope_lev int; // 0 = global scope, 1 = function scope of global functions, etc.
// Scopes // Scopes
top_scope *Globals.Scope; top_scope *AST.Scope;
}; };
...@@ -154,7 +154,7 @@ func (P *Parser) OptSemicolon() { ...@@ -154,7 +154,7 @@ func (P *Parser) OptSemicolon() {
// Scopes // Scopes
func (P *Parser) OpenScope() { 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() { ...@@ -163,27 +163,15 @@ func (P *Parser) CloseScope() {
} }
func Lookup(scope *Globals.Scope, ident string) *Globals.Object { func (P *Parser) DeclareInScope(scope *AST.Scope, x *AST.Expr, kind int) {
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) {
if P.scope_lev < 0 { if P.scope_lev < 0 {
panic("cannot declare objects in other packages"); panic("cannot declare objects in other packages");
} }
obj := x.obj; 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.kind = kind;
obj.pnolev = P.scope_lev; 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`); P.Error(obj.pos, `"` + obj.ident + `" is declared already`);
return; // don't insert it into the scope return; // don't insert it into the scope
} }
...@@ -210,11 +198,11 @@ func ExprType(x *AST.Expr) *AST.Type { ...@@ -210,11 +198,11 @@ func ExprType(x *AST.Expr) *AST.Type {
t = x.t; t = x.t;
} else if x.tok == Scanner.IDENT { } else if x.tok == Scanner.IDENT {
// assume a type name // assume a type name
t = AST.NewType(x.pos, Scanner.IDENT); t = AST.NewType(x.pos, AST.TYPENAME);
t.expr = x; t.expr = x;
} else if x.tok == Scanner.PERIOD && x.y != nil && ExprType(x.x) != nil { } else if x.tok == Scanner.PERIOD && x.y != nil && ExprType(x.x) != nil {
// possibly a qualified (type) identifier // possibly a qualified (type) identifier
t = AST.NewType(x.pos, Scanner.IDENT); t = AST.NewType(x.pos, AST.TYPENAME);
t.expr = x; t.expr = x;
} }
return t; return t;
...@@ -224,7 +212,7 @@ func ExprType(x *AST.Expr) *AST.Type { ...@@ -224,7 +212,7 @@ func ExprType(x *AST.Expr) *AST.Type {
func (P *Parser) NoType(x *AST.Expr) *AST.Expr { func (P *Parser) NoType(x *AST.Expr) *AST.Expr {
if x != nil && x.tok == Scanner.TYPE { if x != nil && x.tok == Scanner.TYPE {
P.Error(x.pos, "expected expression, found 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); x = AST.NewLit(x.pos, Scanner.INT, val);
} }
return x; return x;
...@@ -246,19 +234,19 @@ func (P *Parser) ParseDeclaration() *AST.Decl; ...@@ -246,19 +234,19 @@ func (P *Parser) ParseDeclaration() *AST.Decl;
// If scope != nil, lookup identifier in scope. Otherwise create one. // 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"); P.Trace("Ident");
x := AST.BadExpr; x := AST.BadExpr;
if P.tok == Scanner.IDENT { if P.tok == Scanner.IDENT {
var obj *Globals.Object; var obj *AST.Object;
if scope != nil { if scope != nil {
obj = Lookup(scope, P.val); obj = scope.Lookup(P.val);
} }
if obj == nil { if obj == nil {
obj = Globals.NewObject(P.pos, Object.NONE, P.val); obj = AST.NewObject(P.pos, AST.NONE, P.val);
} else { } else {
assert(obj.kind != Object.NONE); assert(obj.kind != AST.NONE);
} }
x = AST.NewLit(P.pos, Scanner.IDENT, obj); x = AST.NewLit(P.pos, Scanner.IDENT, obj);
if P.verbose { if P.verbose {
...@@ -344,7 +332,7 @@ func (P *Parser) ParseQualifiedIdent() *AST.Expr { ...@@ -344,7 +332,7 @@ func (P *Parser) ParseQualifiedIdent() *AST.Expr {
func (P *Parser) ParseTypeName() *AST.Type { func (P *Parser) ParseTypeName() *AST.Type {
P.Trace("TypeName"); P.Trace("TypeName");
t := AST.NewType(P.pos, P.tok); t := AST.NewType(P.pos, AST.TYPENAME);
t.expr = P.ParseQualifiedIdent(); t.expr = P.ParseQualifiedIdent();
P.Ecart(); P.Ecart();
...@@ -355,7 +343,7 @@ func (P *Parser) ParseTypeName() *AST.Type { ...@@ -355,7 +343,7 @@ func (P *Parser) ParseTypeName() *AST.Type {
func (P *Parser) ParseArrayType() *AST.Type { func (P *Parser) ParseArrayType() *AST.Type {
P.Trace("ArrayType"); P.Trace("ArrayType");
t := AST.NewType(P.pos, Scanner.LBRACK); t := AST.NewType(P.pos, AST.ARRAY);
P.Expect(Scanner.LBRACK); P.Expect(Scanner.LBRACK);
if P.tok == Scanner.ELLIPSIS { if P.tok == Scanner.ELLIPSIS {
t.expr = P.NewExpr(P.pos, Scanner.ELLIPSIS, nil, nil); t.expr = P.NewExpr(P.pos, Scanner.ELLIPSIS, nil, nil);
...@@ -374,7 +362,7 @@ func (P *Parser) ParseArrayType() *AST.Type { ...@@ -374,7 +362,7 @@ func (P *Parser) ParseArrayType() *AST.Type {
func (P *Parser) ParseChannelType() *AST.Type { func (P *Parser) ParseChannelType() *AST.Type {
P.Trace("ChannelType"); P.Trace("ChannelType");
t := AST.NewType(P.pos, Scanner.CHAN); t := AST.NewType(P.pos, AST.CHANNEL);
t.mode = AST.FULL; t.mode = AST.FULL;
if P.tok == Scanner.CHAN { if P.tok == Scanner.CHAN {
P.Next(); P.Next();
...@@ -401,10 +389,10 @@ func (P *Parser) ParseVarDecl(expect_ident bool) *AST.Type { ...@@ -401,10 +389,10 @@ func (P *Parser) ParseVarDecl(expect_ident bool) *AST.Type {
t := AST.BadType; t := AST.BadType;
if expect_ident { if expect_ident {
x := P.ParseIdent(nil); x := P.ParseIdent(nil);
t = AST.NewType(x.pos, Scanner.IDENT); t = AST.NewType(x.pos, AST.TYPENAME);
t.expr = x; t.expr = x;
} else if P.tok == Scanner.ELLIPSIS { } else if P.tok == Scanner.ELLIPSIS {
t = AST.NewType(P.pos, Scanner.ELLIPSIS); t = AST.NewType(P.pos, AST.ELLIPSIS);
P.Next(); P.Next();
} else { } else {
t = P.ParseType(); t = P.ParseType();
...@@ -429,7 +417,7 @@ func (P *Parser) ParseVarDeclList(list *array.Array, ellipsis_ok bool) { ...@@ -429,7 +417,7 @@ func (P *Parser) ParseVarDeclList(list *array.Array, ellipsis_ok bool) {
typ := P.TryType(); typ := P.TryType();
if typ == nil && P.tok == Scanner.ELLIPSIS { if typ == nil && P.tok == Scanner.ELLIPSIS {
typ = AST.NewType(P.pos, Scanner.ELLIPSIS); typ = AST.NewType(P.pos, AST.ELLIPSIS);
P.Next(); P.Next();
} }
...@@ -445,7 +433,7 @@ func (P *Parser) ParseVarDeclList(list *array.Array, ellipsis_ok bool) { ...@@ -445,7 +433,7 @@ func (P *Parser) ParseVarDeclList(list *array.Array, ellipsis_ok bool) {
// convert the type entries into identifiers // convert the type entries into identifiers
for i, n := i0, list.Len(); i < n; i++ { for i, n := i0, list.Len(); i < n; i++ {
t := list.At(i).(*AST.Type); 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); list.Set(i, t.expr);
} else { } else {
list.Set(i, AST.BadExpr); list.Set(i, AST.BadExpr);
...@@ -486,7 +474,7 @@ func (P *Parser) ParseParameterList(ellipsis_ok bool) *array.Array { ...@@ -486,7 +474,7 @@ func (P *Parser) ParseParameterList(ellipsis_ok bool) *array.Array {
func (P *Parser) ParseParameters(ellipsis_ok bool) *AST.Type { func (P *Parser) ParseParameters(ellipsis_ok bool) *AST.Type {
P.Trace("Parameters"); P.Trace("Parameters");
t := AST.NewType(P.pos, Scanner.STRUCT); t := AST.NewType(P.pos, AST.STRUCT);
P.Expect(Scanner.LPAREN); P.Expect(Scanner.LPAREN);
if P.tok != Scanner.RPAREN { if P.tok != Scanner.RPAREN {
t.list = P.ParseParameterList(ellipsis_ok); t.list = P.ParseParameterList(ellipsis_ok);
...@@ -524,7 +512,7 @@ func (P *Parser) ParseResult() *AST.Type { ...@@ -524,7 +512,7 @@ func (P *Parser) ParseResult() *AST.Type {
} else { } else {
typ := P.TryType(); typ := P.TryType();
if typ != nil { if typ != nil {
t = AST.NewType(P.pos, Scanner.STRUCT); t = AST.NewType(P.pos, AST.STRUCT);
t.list = array.New(0); t.list = array.New(0);
t.list.Push(AST.NewTypeExpr(typ)); t.list.Push(AST.NewTypeExpr(typ));
t.end = P.pos; t.end = P.pos;
...@@ -548,7 +536,7 @@ func (P *Parser) ParseFunctionType() *AST.Type { ...@@ -548,7 +536,7 @@ func (P *Parser) ParseFunctionType() *AST.Type {
P.OpenScope(); P.OpenScope();
P.scope_lev++; 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.list = P.ParseParameters(true).list; // TODO find better solution
t.end = P.pos; t.end = P.pos;
t.elt = P.ParseResult(); t.elt = P.ParseResult();
...@@ -580,7 +568,7 @@ func (P *Parser) ParseMethodSpec(list *array.Array) { ...@@ -580,7 +568,7 @@ func (P *Parser) ParseMethodSpec(list *array.Array) {
func (P *Parser) ParseInterfaceType() *AST.Type { func (P *Parser) ParseInterfaceType() *AST.Type {
P.Trace("InterfaceType"); P.Trace("InterfaceType");
t := AST.NewType(P.pos, Scanner.INTERFACE); t := AST.NewType(P.pos, AST.INTERFACE);
P.Expect(Scanner.INTERFACE); P.Expect(Scanner.INTERFACE);
if P.tok == Scanner.LBRACE { if P.tok == Scanner.LBRACE {
P.Next(); P.Next();
...@@ -609,7 +597,7 @@ func (P *Parser) ParseInterfaceType() *AST.Type { ...@@ -609,7 +597,7 @@ func (P *Parser) ParseInterfaceType() *AST.Type {
func (P *Parser) ParseMapType() *AST.Type { func (P *Parser) ParseMapType() *AST.Type {
P.Trace("MapType"); P.Trace("MapType");
t := AST.NewType(P.pos, Scanner.MAP); t := AST.NewType(P.pos, AST.MAP);
P.Expect(Scanner.MAP); P.Expect(Scanner.MAP);
P.Expect(Scanner.LBRACK); P.Expect(Scanner.LBRACK);
t.key = P.ParseVarType(); t.key = P.ParseVarType();
...@@ -626,7 +614,7 @@ func (P *Parser) ParseOperand() *AST.Expr ...@@ -626,7 +614,7 @@ func (P *Parser) ParseOperand() *AST.Expr
func (P *Parser) ParseStructType() *AST.Type { func (P *Parser) ParseStructType() *AST.Type {
P.Trace("StructType"); P.Trace("StructType");
t := AST.NewType(P.pos, Scanner.STRUCT); t := AST.NewType(P.pos, AST.STRUCT);
P.Expect(Scanner.STRUCT); P.Expect(Scanner.STRUCT);
if P.tok == Scanner.LBRACE { if P.tok == Scanner.LBRACE {
P.Next(); P.Next();
...@@ -662,7 +650,7 @@ func (P *Parser) ParseStructType() *AST.Type { ...@@ -662,7 +650,7 @@ func (P *Parser) ParseStructType() *AST.Type {
func (P *Parser) ParsePointerType() *AST.Type { func (P *Parser) ParsePointerType() *AST.Type {
P.Trace("PointerType"); P.Trace("PointerType");
t := AST.NewType(P.pos, Scanner.MUL); t := AST.NewType(P.pos, AST.POINTER);
P.Expect(Scanner.MUL); P.Expect(Scanner.MUL);
t.elt = P.ParseType(); t.elt = P.ParseType();
...@@ -769,7 +757,7 @@ func (P *Parser) ParseExpressionList() *AST.Expr { ...@@ -769,7 +757,7 @@ func (P *Parser) ParseExpressionList() *AST.Expr {
func (P *Parser) ParseFunctionLit() *AST.Expr { func (P *Parser) ParseFunctionLit() *AST.Expr {
P.Trace("FunctionLit"); 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); x := AST.NewLit(P.pos, Scanner.FUNC, val);
P.Expect(Scanner.FUNC); P.Expect(Scanner.FUNC);
x.t = P.ParseFunctionType(); x.t = P.ParseFunctionType();
...@@ -824,7 +812,7 @@ func (P *Parser) ParseOperand() *AST.Expr { ...@@ -824,7 +812,7 @@ func (P *Parser) ParseOperand() *AST.Expr {
P.Expect(Scanner.RPAREN); P.Expect(Scanner.RPAREN);
case Scanner.INT, Scanner.FLOAT, Scanner.STRING: 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); x = AST.NewLit(P.pos, P.tok, val);
P.Next(); P.Next();
if x.tok == Scanner.STRING { if x.tok == Scanner.STRING {
...@@ -1033,7 +1021,7 @@ func (P *Parser) ParseUnaryExpr() *AST.Expr { ...@@ -1033,7 +1021,7 @@ func (P *Parser) ParseUnaryExpr() *AST.Expr {
y := P.ParseUnaryExpr(); y := P.ParseUnaryExpr();
if tok == Scanner.MUL && y.tok == Scanner.TYPE { if tok == Scanner.MUL && y.tok == Scanner.TYPE {
// pointer type // pointer type
t := AST.NewType(pos, Scanner.MUL); t := AST.NewType(pos, AST.POINTER);
t.elt = y.t; t.elt = y.t;
x = AST.NewTypeExpr(t); x = AST.NewTypeExpr(t);
} else { } else {
...@@ -1491,7 +1479,7 @@ func (P *Parser) ParseImportSpec(pos int) *AST.Decl { ...@@ -1491,7 +1479,7 @@ func (P *Parser) ParseImportSpec(pos int) *AST.Decl {
if P.tok == Scanner.STRING { if P.tok == Scanner.STRING {
// TODO eventually the scanner should strip the quotes // 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); d.val = AST.NewLit(P.pos, Scanner.STRING, val);
P.Next(); P.Next();
} else { } else {
...@@ -1499,7 +1487,7 @@ func (P *Parser) ParseImportSpec(pos int) *AST.Decl { ...@@ -1499,7 +1487,7 @@ func (P *Parser) ParseImportSpec(pos int) *AST.Decl {
} }
if d.ident != nil { if d.ident != nil {
P.Declare(d.ident, Object.PACKAGE); P.Declare(d.ident, AST.PACKAGE);
} }
P.Ecart(); P.Ecart();
...@@ -1518,7 +1506,7 @@ func (P *Parser) ParseConstSpec(exported bool, pos int) *AST.Decl { ...@@ -1518,7 +1506,7 @@ func (P *Parser) ParseConstSpec(exported bool, pos int) *AST.Decl {
d.val = P.ParseExpressionList(); d.val = P.ParseExpressionList();
} }
P.Declare(d.ident, Object.CONST); P.Declare(d.ident, AST.CONST);
P.Ecart(); P.Ecart();
return d; return d;
...@@ -1554,7 +1542,7 @@ func (P *Parser) ParseVarSpec(exported bool, pos int) *AST.Decl { ...@@ -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(); P.Ecart();
return d; return d;
......
...@@ -12,8 +12,6 @@ import ( ...@@ -12,8 +12,6 @@ import (
"flag"; "flag";
"fmt"; "fmt";
Utils "utils"; Utils "utils";
Globals "globals";
Object "object";
Scanner "scanner"; Scanner "scanner";
AST "ast"; AST "ast";
) )
...@@ -127,6 +125,23 @@ func HtmlEscape(s string) string { ...@@ -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 ...) { func (P *Printer) Printf(format string, s ...) {
n, err := fmt.fprintf(P.text, format, s); n, err := fmt.fprintf(P.text, format, s);
if err != nil { if err != nil {
...@@ -246,7 +261,9 @@ func (P *Printer) TaggedString(pos int, tag, s, endtag string) { ...@@ -246,7 +261,9 @@ func (P *Printer) TaggedString(pos int, tag, s, endtag string) {
if *debug { if *debug {
P.Printf("[%d]", P.cpos); 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] == '/' { if ctext[1] == '/' {
//-style comments must end in newline //-style comments must end in newline
...@@ -371,7 +388,7 @@ func (P *Printer) HtmlIdentifier(x *AST.Expr) { ...@@ -371,7 +388,7 @@ func (P *Printer) HtmlIdentifier(x *AST.Expr) {
panic(); panic();
} }
obj := x.obj; 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 // depending on whether we have a declaration or use, generate different html
// - no need to HtmlEscape ident // - no need to HtmlEscape ident
id := Utils.IntToString(obj.id, 10); id := Utils.IntToString(obj.id, 10);
...@@ -450,11 +467,11 @@ func (P *Printer) Fields(list *array.Array, end int) { ...@@ -450,11 +467,11 @@ func (P *Printer) Fields(list *array.Array, end int) {
func (P *Printer) Type(t *AST.Type) int { func (P *Printer) Type(t *AST.Type) int {
separator := semicolon; separator := semicolon;
switch t.tok { switch t.form {
case Scanner.IDENT: case AST.TYPENAME:
P.Expr(t.expr); P.Expr(t.expr);
case Scanner.LBRACK: case AST.ARRAY:
P.String(t.pos, "["); P.String(t.pos, "[");
if t.expr != nil { if t.expr != nil {
P.Expr(t.expr); P.Expr(t.expr);
...@@ -462,21 +479,24 @@ func (P *Printer) Type(t *AST.Type) int { ...@@ -462,21 +479,24 @@ func (P *Printer) Type(t *AST.Type) int {
P.String(0, "]"); P.String(0, "]");
separator = P.Type(t.elt); separator = P.Type(t.elt);
case Scanner.STRUCT, Scanner.INTERFACE: case AST.STRUCT, AST.INTERFACE:
P.Token(t.pos, t.tok); switch t.form {
case AST.STRUCT: P.String(t.pos, "struct");
case AST.INTERFACE: P.String(t.pos, "interface");
}
if t.list != nil { if t.list != nil {
P.separator = blank; P.separator = blank;
P.Fields(t.list, t.end); P.Fields(t.list, t.end);
} }
separator = none; separator = none;
case Scanner.MAP: case AST.MAP:
P.String(t.pos, "map ["); P.String(t.pos, "map [");
P.Type(t.key); P.Type(t.key);
P.String(0, "]"); P.String(0, "]");
separator = P.Type(t.elt); separator = P.Type(t.elt);
case Scanner.CHAN: case AST.CHANNEL:
var m string; var m string;
switch t.mode { switch t.mode {
case AST.FULL: m = "chan "; case AST.FULL: m = "chan ";
...@@ -486,11 +506,11 @@ func (P *Printer) Type(t *AST.Type) int { ...@@ -486,11 +506,11 @@ func (P *Printer) Type(t *AST.Type) int {
P.String(t.pos, m); P.String(t.pos, m);
separator = P.Type(t.elt); separator = P.Type(t.elt);
case Scanner.MUL: case AST.POINTER:
P.String(t.pos, "*"); P.String(t.pos, "*");
separator = P.Type(t.elt); separator = P.Type(t.elt);
case Scanner.LPAREN: case AST.FUNCTION:
P.Parameters(t.pos, t.list); P.Parameters(t.pos, t.list);
if t.elt != nil { if t.elt != nil {
P.separator = blank; P.separator = blank;
...@@ -503,11 +523,11 @@ func (P *Printer) Type(t *AST.Type) int { ...@@ -503,11 +523,11 @@ func (P *Printer) Type(t *AST.Type) int {
} }
} }
case Scanner.ELLIPSIS: case AST.ELLIPSIS:
P.String(t.pos, "..."); P.String(t.pos, "...");
default: default:
P.Error(t.pos, t.tok, "type"); P.Error(t.pos, t.form, "type");
} }
return separator; return separator;
......
...@@ -679,7 +679,8 @@ func (S *Scanner) Select4(tok0, tok1, ch2, tok2, tok3 int) int { ...@@ -679,7 +679,8 @@ func (S *Scanner) Select4(tok0, tok1, ch2, tok2, tok3 int) int {
func (S *Scanner) Scan() (pos, tok int, val string) { func (S *Scanner) Scan() (pos, tok int, val string) {
L: S.SkipWhitespace(); loop:
S.SkipWhitespace();
pos, tok = S.chpos, ILLEGAL; pos, tok = S.chpos, ILLEGAL;
...@@ -722,7 +723,7 @@ L: S.SkipWhitespace(); ...@@ -722,7 +723,7 @@ L: S.SkipWhitespace();
if S.ch == '/' || S.ch == '*' { if S.ch == '/' || S.ch == '*' {
tok, val = COMMENT, S.ScanComment(); tok, val = COMMENT, S.ScanComment();
if !S.scan_comments { if !S.scan_comments {
goto L; goto loop;
} }
} else { } else {
tok = S.Select2(QUO, QUO_ASSIGN); tok = S.Select2(QUO, QUO_ASSIGN);
......
...@@ -22,11 +22,9 @@ count() { ...@@ -22,11 +22,9 @@ count() {
apply1() { apply1() {
#echo $1 $2 #echo $1 $2
case `basename $F` in case `basename $F` in
# these files don't pass the idempotency test yet # files with errors (skip them)
log.go | type.go | types_amd64_darwin.go | \
\
method1.go | selftest1.go | func3.go | bug014.go | bug029.go | bug032.go | bug050.go | \ 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 ;; * ) $1 $2; count ;;
esac esac
} }
......
...@@ -8,9 +8,6 @@ import ( ...@@ -8,9 +8,6 @@ import (
AST "ast"; AST "ast";
Scanner "scanner"; Scanner "scanner";
Universe "universe"; Universe "universe";
Globals "globals";
Object "object";
Type "type";
) )
......
...@@ -6,14 +6,12 @@ package Universe ...@@ -6,14 +6,12 @@ package Universe
import ( import (
"array"; "array";
Globals "globals"; AST "ast";
Object "object";
Type "type";
) )
export var ( export var (
scope *Globals.Scope; scope *AST.Scope;
types array.Array; types array.Array;
// internal types // internal types
...@@ -42,19 +40,19 @@ export var ( ...@@ -42,19 +40,19 @@ export var (
uint_typ, uint_typ,
int_typ, int_typ,
float_typ, float_typ,
uintptr_typ *Globals.Type; uintptr_typ *AST.Type;
true_obj, true_obj,
false_obj, false_obj,
iota_obj, iota_obj,
nil_obj *Globals.Object; nil_obj *AST.Object;
) )
func DeclObj(kind int, ident string, typ *Globals.Type) *Globals.Object { func DeclObj(kind int, ident string, typ *AST.Type) *AST.Object {
obj := Globals.NewObject(-1 /* no source pos */, kind, ident); obj := AST.NewObject(-1 /* no source pos */, kind, ident);
obj.typ = typ; obj.typ = typ;
if kind == Object.TYPE && typ.obj == nil { if kind == AST.TYPE && typ.obj == nil {
typ.obj = obj; // set primary type object typ.obj = obj; // set primary type object
} }
scope.Insert(obj); scope.Insert(obj);
...@@ -62,14 +60,14 @@ func DeclObj(kind int, ident string, typ *Globals.Type) *Globals.Object { ...@@ -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 { func DeclType(form int, ident string, size int) *AST.Type {
typ := Globals.NewType(form); typ := AST.NewType(-1 /* no source pos */, form);
typ.size = size; 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(); typ.ref = types.Len();
types.Push(typ); types.Push(typ);
return typ; return typ;
...@@ -77,49 +75,49 @@ func Register(typ *Globals.Type) *Globals.Type { ...@@ -77,49 +75,49 @@ func Register(typ *Globals.Type) *Globals.Type {
func init() { func init() {
scope = Globals.NewScope(nil); // universe has no parent scope = AST.NewScope(nil); // universe has no parent
types.Init(32); types.Init(32);
// Interal types // Interal types
void_typ = Globals.NewType(Type.VOID); void_typ = AST.NewType(-1 /* no source pos */, AST.VOID);
Globals.Universe_void_typ = void_typ; AST.Universe_void_typ = void_typ;
bad_typ = Globals.NewType(Type.BAD); bad_typ = AST.NewType(-1 /* no source pos */, AST.BADTYPE);
nil_typ = Globals.NewType(Type.NIL); nil_typ = AST.NewType(-1 /* no source pos */, AST.NIL);
// Basic types // Basic types
bool_typ = Register(DeclType(Type.BOOL, "bool", 1)); bool_typ = Register(DeclType(AST.BOOL, "bool", 1));
uint8_typ = Register(DeclType(Type.UINT, "uint8", 1)); uint8_typ = Register(DeclType(AST.UINT, "uint8", 1));
uint16_typ = Register(DeclType(Type.UINT, "uint16", 2)); uint16_typ = Register(DeclType(AST.UINT, "uint16", 2));
uint32_typ = Register(DeclType(Type.UINT, "uint32", 4)); uint32_typ = Register(DeclType(AST.UINT, "uint32", 4));
uint64_typ = Register(DeclType(Type.UINT, "uint64", 8)); uint64_typ = Register(DeclType(AST.UINT, "uint64", 8));
int8_typ = Register(DeclType(Type.INT, "int8", 1)); int8_typ = Register(DeclType(AST.INT, "int8", 1));
int16_typ = Register(DeclType(Type.INT, "int16", 2)); int16_typ = Register(DeclType(AST.INT, "int16", 2));
int32_typ = Register(DeclType(Type.INT, "int32", 4)); int32_typ = Register(DeclType(AST.INT, "int32", 4));
int64_typ = Register(DeclType(Type.INT, "int64", 8)); int64_typ = Register(DeclType(AST.INT, "int64", 8));
float32_typ = Register(DeclType(Type.FLOAT, "float32", 4)); float32_typ = Register(DeclType(AST.FLOAT, "float32", 4));
float64_typ = Register(DeclType(Type.FLOAT, "float64", 8)); float64_typ = Register(DeclType(AST.FLOAT, "float64", 8));
float80_typ = Register(DeclType(Type.FLOAT, "float80", 10)); float80_typ = Register(DeclType(AST.FLOAT, "float80", 10));
string_typ = Register(DeclType(Type.STRING, "string", 8)); string_typ = Register(DeclType(AST.STRING, "string", 8));
integer_typ = Register(DeclType(Type.INTEGER, "integer", 8)); integer_typ = Register(DeclType(AST.INTEGER, "integer", 8));
// All but 'byte' should be platform-dependent, eventually. // All but 'byte' should be platform-dependent, eventually.
byte_typ = Register(DeclType(Type.UINT, "byte", 1)); byte_typ = Register(DeclType(AST.UINT, "byte", 1));
uint_typ = Register(DeclType(Type.UINT, "uint", 4)); uint_typ = Register(DeclType(AST.UINT, "uint", 4));
int_typ = Register(DeclType(Type.INT, "int", 4)); int_typ = Register(DeclType(AST.INT, "int", 4));
float_typ = Register(DeclType(Type.FLOAT, "float", 4)); float_typ = Register(DeclType(AST.FLOAT, "float", 4));
uintptr_typ = Register(DeclType(Type.UINT, "uintptr", 8)); uintptr_typ = Register(DeclType(AST.UINT, "uintptr", 8));
// Predeclared constants // Predeclared constants
true_obj = DeclObj(Object.CONST, "true", bool_typ); true_obj = DeclObj(AST.CONST, "true", bool_typ);
false_obj = DeclObj(Object.CONST, "false", bool_typ); false_obj = DeclObj(AST.CONST, "false", bool_typ);
iota_obj = DeclObj(Object.CONST, "iota", int_typ); iota_obj = DeclObj(AST.CONST, "iota", int_typ);
nil_obj = DeclObj(Object.CONST, "nil", nil_typ); nil_obj = DeclObj(AST.CONST, "nil", nil_typ);
// Builtin functions // Builtin functions
DeclObj(Object.BUILTIN, "len", void_typ); DeclObj(AST.BUILTIN, "len", void_typ);
DeclObj(Object.BUILTIN, "new", void_typ); DeclObj(AST.BUILTIN, "new", void_typ);
DeclObj(Object.BUILTIN, "panic", void_typ); DeclObj(AST.BUILTIN, "panic", void_typ);
DeclObj(Object.BUILTIN, "print", void_typ); DeclObj(AST.BUILTIN, "print", void_typ);
// scope.Print(); // scope.Print();
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment