export type Object struct {
- id int; // unique id
+ 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
+ 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
+ Block *array.Array; End int; // stats for function literals; end of block pos
}
func (obj *Object) IsExported() bool {
- switch obj.kind {
+ switch obj.Kind {
case NONE /* FUNC for now */, CONST, TYPE, VAR, FUNC:
- ch, size := utf8.DecodeRuneInString(obj.ident, 0);
+ ch, size := utf8.DecodeRuneInString(obj.Ident, 0);
return unicode.IsUpper(ch);
}
return false;
export var Universe_void_typ *Type // initialized by Universe to Universe.void_typ
-var ObjectId int;
+var objectId int;
export func NewObject(pos, kind int, ident string) *Object {
obj := new(Object);
- obj.id = ObjectId;
- ObjectId++;
+ obj.Id = objectId;
+ objectId++;
- obj.pos = pos;
- obj.kind = kind;
- obj.ident = ident;
- obj.typ = Universe_void_typ;
- obj.pnolev = 0;
+ obj.Pos = pos;
+ obj.Kind = kind;
+ obj.Ident = ident;
+ obj.Typ = Universe_void_typ;
+ obj.Pnolev = 0;
return obj;
}
}
-func (scope *Scope) Add(obj* Object) {
- scope.entries[obj.ident] = obj;
+func (scope *Scope) add(obj* Object) {
+ scope.entries[obj.Ident] = obj;
}
func (scope *Scope) Insert(obj *Object) {
- if scope.LookupLocal(obj.ident) != nil {
+ if scope.LookupLocal(obj.Ident) != nil {
panic("obj already inserted");
}
- scope.Add(obj);
+ scope.add(obj);
}
func (scope *Scope) InsertImport(obj *Object) *Object {
- p := scope.LookupLocal(obj.ident);
+ p := scope.LookupLocal(obj.Ident);
if p == nil {
- scope.Add(obj);
+ scope.add(obj);
p = obj;
}
return p;
// All nodes have a source position and and token.
export type Node struct {
- pos int; // source position (< 0 => unknown position)
- tok int; // identifying token
+ Pos int; // source position (< 0 => unknown position)
+ Tok int; // identifying token
}
export type Expr struct {
Node;
- x, y *Expr; // binary (x, y) and unary (y) expressions
- obj *Object;
+ X, Y *Expr; // binary (X, Y) and unary (Y) expressions
+ Obj *Object;
}
return 0;
}
n := 1;
- for ; x.tok == Scanner.COMMA; x = x.y {
+ for ; x.Tok == Scanner.COMMA; x = x.Y {
n++;
}
return n;
export func NewExpr(pos, tok int, x, y *Expr) *Expr {
- if x != nil && x.tok == Scanner.TYPE || y != nil && y.tok == Scanner.TYPE {
+ if x != nil && x.Tok == Scanner.TYPE || y != nil && y.Tok == Scanner.TYPE {
panic("no type expression allowed");
}
e := new(Expr);
- e.pos, e.tok, e.x, e.y = pos, tok, x, y;
+ e.Pos, e.Tok, e.X, e.Y = pos, tok, x, y;
return e;
}
// TODO probably don't need the tok parameter eventually
export func NewLit(tok int, obj *Object) *Expr {
e := new(Expr);
- e.pos, e.tok, e.obj = obj.pos, tok, obj;
+ e.Pos, e.Tok, e.Obj = obj.Pos, tok, obj;
return e;
}
export type Type struct {
- id int; // unique id
+ 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
+ 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 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
- scope *Scope; // struct fields, methods
+ Pos int; // source position (< 0 if unknown position)
+ Expr *Expr; // type name, array length
+ Mode int; // channel mode
+ 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
+ Scope *Scope; // struct fields, methods
}
-var TypeId int;
+var typeId int;
export func NewType(pos, form int) *Type {
typ := new(Type);
- typ.id = TypeId;
- TypeId++;
+ typ.Id = typeId;
+ typeId++;
- typ.ref = -1; // not yet exported
- typ.pos = pos;
- typ.form = form;
+ typ.Ref = -1; // not yet exported
+ typ.Pos = pos;
+ typ.Form = form;
return typ;
}
-func (t *Type) nfields() int {
- if t.list == nil {
+func (t *Type) Nfields() int {
+ if t.List == nil {
return 0;
}
nx, nt := 0, 0;
- for i, n := 0, t.list.Len(); i < n; i++ {
- if t.list.At(i).(*Expr).tok == Scanner.TYPE {
+ for i, n := 0, t.List.Len(); i < n; i++ {
+ if t.List.At(i).(*Expr).Tok == Scanner.TYPE {
nt++;
} else {
nx++;
}
-// requires complete Type.pos access
+// requires complete Type.Pos access
export func NewTypeExpr(typ *Type) *Expr {
- obj := NewObject(typ.pos, TYPE, "");
- obj.typ = typ;
+ obj := NewObject(typ.Pos, TYPE, "");
+ obj.Typ = typ;
return NewLit(Scanner.TYPE, obj);
}
export type Stat struct {
Node;
- init, post *Stat;
- expr *Expr;
- block *array.Array; end int; // block end position
- decl *Decl;
+ Init, Post *Stat;
+ Expr *Expr;
+ Block *array.Array; End int; // block end position
+ Decl *Decl;
}
export func NewStat(pos, tok int) *Stat {
s := new(Stat);
- s.pos, s.tok = pos, tok;
+ s.Pos, s.Tok = pos, tok;
return s;
}
export type Decl struct {
Node;
- exported bool;
- ident *Expr; // nil for ()-style declarations
- typ *Type;
- val *Expr;
+ Exported bool;
+ Ident *Expr; // nil for ()-style declarations
+ Typ *Type;
+ Val *Expr;
// list of *Decl for ()-style declarations
// list of *Stat for func declarations (or nil for forward decl)
- list *array.Array; end int;
+ List *array.Array; End int;
}
export func NewDecl(pos, tok int, exported bool) *Decl {
d := new(Decl);
- d.pos, d.tok, d.exported = pos, tok, exported;
+ d.Pos, d.Tok, d.Exported = pos, tok, exported;
return d;
}
// Program
export type Comment struct {
- pos int;
- text string;
+ Pos int;
+ Text string;
}
export func NewComment(pos int, text string) *Comment {
c := new(Comment);
- c.pos, c.text = pos, text;
+ c.Pos, c.Text = pos, text;
return c;
}
export type Program struct {
- pos int; // tok is Scanner.PACKAGE
- ident *Expr;
- decls *array.Array;
- comments *array.Array;
+ Pos int; // tok is Scanner.PACKAGE
+ Ident *Expr;
+ Decls *array.Array;
+ Comments *array.Array;
}
export func NewProgram(pos int) *Program {
p := new(Program);
- p.pos = pos;
+ p.Pos = pos;
return p;
}
}
-type ErrorHandler struct {
+type errorHandler struct {
filename string;
src string;
nerrors int;
}
-func (h *ErrorHandler) Init(filename, src string, columns bool) {
+func (h *errorHandler) Init(filename, src string, columns bool) {
h.filename = filename;
h.src = src;
h.nerrors = 0;
// Compute (line, column) information for a given source position.
-func (h *ErrorHandler) LineCol(pos int) (line, col int) {
+func (h *errorHandler) LineCol(pos int) (line, col int) {
line = 1;
lpos := 0;
}
-func (h *ErrorHandler) ErrorMsg(pos int, msg string) {
+func (h *errorHandler) ErrorMsg(pos int, msg string) {
print(h.filename, ":");
if pos >= 0 {
// print position
}
-func (h *ErrorHandler) Error(pos int, msg string) {
+func (h *errorHandler) Error(pos int, msg string) {
// only report errors that are sufficiently far away from the previous error
// in the hope to avoid most follow-up errors
const errdist = 20;
}
-func (h *ErrorHandler) Warning(pos int, msg string) {
+func (h *errorHandler) Warning(pos int, msg string) {
panic("UNIMPLEMENTED");
}
return nil, 1;
}
- var err ErrorHandler;
+ var err errorHandler;
err.Init(src_file, src, flags.columns);
var scanner Scanner.Scanner;
}
-func FileExists(name string) bool {
+func fileExists(name string) bool {
fd, err := OS.Open(name, OS.O_RDONLY, 0);
if err == nil {
fd.Close();
}
-func AddDeps(globalset map [string] bool, wset *array.Array, src_file string, flags *Flags) {
+func addDeps(globalset map [string] bool, wset *array.Array, src_file string, flags *Flags) {
dummy, found := globalset[src_file];
if !found {
globalset[src_file] = true;
return;
}
- nimports := prog.decls.Len();
+ nimports := prog.Decls.Len();
if nimports > 0 {
print(src_file, ".6:\t");
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;
+ 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") {
+ if fileExists(src + ".go") {
wset.Push(src);
print(" ", src, ".6");
} else if
- FileExists(Platform.GOROOT + "/pkg/" + src + ".6") ||
- FileExists(Platform.GOROOT + "/pkg/" + src + ".a") {
+ fileExists(Platform.GOROOT + "/pkg/" + src + ".6") ||
+ fileExists(Platform.GOROOT + "/pkg/" + src + ".a") {
} else {
// TODO should collect these and print later
wset := array.New(0);
wset.Push(src_file);
for wset.Len() > 0 {
- AddDeps(globalset, wset, wset.Pop().(string), flags);
+ addDeps(globalset, wset, wset.Pop().(string), flags);
}
}
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.tok, P.pos, P.val = t.Tok, t.Pos, t.Val;
}
P.opt_semi = false;
if P.scope_lev < 0 {
panic("cannot declare objects in other packages");
}
- if x.tok != Scanner.ILLEGAL { // ignore bad exprs
- obj := x.obj;
- assert(x.tok == Scanner.IDENT && obj.kind == AST.NONE);
- obj.kind = kind;
- obj.pnolev = P.scope_lev;
- if scope.LookupLocal(obj.ident) != nil {
- P.Error(obj.pos, `"` + obj.ident + `" is declared already`);
+ if x.Tok != Scanner.ILLEGAL { // ignore bad exprs
+ obj := x.Obj;
+ assert(x.Tok == Scanner.IDENT && obj.Kind == AST.NONE);
+ obj.Kind = kind;
+ obj.Pnolev = P.scope_lev;
+ if scope.LookupLocal(obj.Ident) != nil {
+ P.Error(obj.Pos, `"` + obj.Ident + `" is declared already`);
return; // don't insert it into the scope
}
scope.Insert(obj);
// Declare a comma-separated list of idents or a single ident.
func (P *Parser) Declare(p *AST.Expr, kind int) {
- for p.tok == Scanner.COMMA {
- P.DeclareInScope(P.top_scope, p.x, kind);
- p = p.y;
+ for p.Tok == Scanner.COMMA {
+ P.DeclareInScope(P.top_scope, p.X, kind);
+ p = p.Y;
}
P.DeclareInScope(P.top_scope, p, kind);
}
func (P *Parser) VerifyExport1(p *AST.Expr, exported bool) {
- obj := p.obj;
+ obj := p.Obj;
if exported {
if !obj.IsExported() {
- P.Error(obj.pos, `"` + obj.ident + `" should be uppercase`);
+ P.Error(obj.Pos, `"` + obj.Ident + `" should be uppercase`);
}
} else if P.scope_lev == 0 {
if obj.IsExported() {
- P.Error(obj.pos, `"` + obj.ident + `" should be lowercase`);
+ P.Error(obj.Pos, `"` + obj.Ident + `" should be lowercase`);
}
}
}
if !P.naming {
return;
}
- for p.tok == Scanner.COMMA {
- P.VerifyExport1(p.x, exported);
- p = p.y;
+ for p.Tok == Scanner.COMMA {
+ P.VerifyExport1(p.X, exported);
+ p = p.Y;
}
P.VerifyExport1(p, exported);
}
// ----------------------------------------------------------------------------
// AST support
-func ExprType(x *AST.Expr) *AST.Type {
+func exprType(x *AST.Expr) *AST.Type {
var t *AST.Type;
- if x.tok == Scanner.TYPE {
- t = x.obj.typ;
- } else if x.tok == Scanner.IDENT {
+ if x.Tok == Scanner.TYPE {
+ t = x.Obj.Typ;
+ } else if x.Tok == Scanner.IDENT {
// assume a type name
- t = AST.NewType(x.pos, AST.TYPENAME);
- t.expr = x;
- } else if x.tok == Scanner.PERIOD && x.y != nil && ExprType(x.x) != nil {
+ 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, AST.TYPENAME);
- t.expr = x;
+ t = AST.NewType(x.Pos, AST.TYPENAME);
+ t.Expr = x;
}
return t;
}
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 := AST.NewObject(x.pos, AST.NONE, "0");
+ if x != nil && x.Tok == Scanner.TYPE {
+ P.Error(x.Pos, "expected expression, found type");
+ val := AST.NewObject(x.Pos, AST.NONE, "0");
x = AST.NewLit(Scanner.INT, val);
}
return x;
if obj == nil {
obj = AST.NewObject(P.pos, AST.NONE, P.val);
} else {
- assert(obj.kind != AST.NONE);
+ assert(obj.Kind != AST.NONE);
}
x = AST.NewLit(Scanner.IDENT, obj);
- x.pos = P.pos; // override obj.pos (incorrect if object was looked up!)
+ x.Pos = P.pos; // override obj.pos (incorrect if object was looked up!)
if P.verbose {
P.PrintIndent();
print("Ident = \"", P.val, "\"\n");
x = P.NewExpr(pos, Scanner.COMMA, x, y);
last = x;
} else {
- last.y = P.NewExpr(pos, Scanner.COMMA, last.y, y);
- last = last.y;
+ last.Y = P.NewExpr(pos, Scanner.COMMA, last.Y, y);
+ last = last.Y;
}
}
P.Trace("TypeName");
t := AST.NewType(P.pos, AST.TYPENAME);
- t.expr = P.ParseQualifiedIdent();
+ t.Expr = P.ParseQualifiedIdent();
P.Ecart();
return t;
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);
+ t.Expr = P.NewExpr(P.pos, Scanner.ELLIPSIS, nil, nil);
P.Next();
} else if P.tok != Scanner.RBRACK {
- t.expr = P.ParseExpression(1);
+ t.Expr = P.ParseExpression(1);
}
P.Expect(Scanner.RBRACK);
- t.elt = P.ParseType();
+ t.Elt = P.ParseType();
P.Ecart();
return t;
P.Trace("ChannelType");
t := AST.NewType(P.pos, AST.CHANNEL);
- t.mode = AST.FULL;
+ t.Mode = AST.FULL;
if P.tok == Scanner.CHAN {
P.Next();
if P.tok == Scanner.ARROW {
P.Next();
- t.mode = AST.SEND;
+ t.Mode = AST.SEND;
}
} else {
P.Expect(Scanner.ARROW);
P.Expect(Scanner.CHAN);
- t.mode = AST.RECV;
+ t.Mode = AST.RECV;
}
- t.elt = P.ParseVarType();
+ t.Elt = P.ParseVarType();
P.Ecart();
return t;
t := AST.BadType;
if expect_ident {
x := P.ParseIdent(nil);
- t = AST.NewType(x.pos, AST.TYPENAME);
- t.expr = x;
+ t = AST.NewType(x.Pos, AST.TYPENAME);
+ t.Expr = x;
} else if P.tok == Scanner.ELLIPSIS {
t = AST.NewType(P.pos, AST.ELLIPSIS);
P.Next();
// convert the type entries into identifiers
for i, n := i0, list.Len(); i < n; i++ {
t := list.At(i).(*AST.Type);
- if t.form == AST.TYPENAME && t.expr.tok == Scanner.IDENT {
- list.Set(i, t.expr);
+ if t.Form == AST.TYPENAME && t.Expr.Tok == Scanner.IDENT {
+ list.Set(i, t.Expr);
} else {
list.Set(i, AST.BadExpr);
- P.Error(t.pos, "identifier expected");
+ P.Error(t.Pos, "identifier expected");
}
}
// add type
t := AST.NewType(P.pos, AST.STRUCT);
P.Expect(Scanner.LPAREN);
if P.tok != Scanner.RPAREN {
- t.list = P.ParseParameterList(ellipsis_ok);
+ t.List = P.ParseParameterList(ellipsis_ok);
}
- t.end = P.pos;
+ t.End = P.pos;
P.Expect(Scanner.RPAREN);
P.Ecart();
typ := P.TryType();
if typ != nil {
t = AST.NewType(P.pos, AST.STRUCT);
- t.list = array.New(0);
- t.list.Push(AST.NewTypeExpr(typ));
- t.end = P.pos;
+ t.List = array.New(0);
+ t.List.Push(AST.NewTypeExpr(typ));
+ t.End = P.pos;
}
}
P.scope_lev++;
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();
+ t.List = P.ParseParameters(true).List; // TODO find better solution
+ t.End = P.pos;
+ t.Elt = P.ParseResult();
P.scope_lev--;
P.CloseScope();
P.OpenScope();
P.scope_lev++;
- t.list = array.New(0);
+ t.List = array.New(0);
for P.tok == Scanner.IDENT {
- P.ParseMethodSpec(t.list);
+ P.ParseMethodSpec(t.List);
if P.tok != Scanner.RBRACE {
P.Expect(Scanner.SEMICOLON);
}
}
- t.end = P.pos;
+ t.End = P.pos;
P.scope_lev--;
P.CloseScope();
t := AST.NewType(P.pos, AST.MAP);
P.Expect(Scanner.MAP);
P.Expect(Scanner.LBRACK);
- t.key = P.ParseVarType();
+ t.Key = P.ParseVarType();
P.Expect(Scanner.RBRACK);
- t.elt = P.ParseVarType();
+ t.Elt = P.ParseVarType();
P.Ecart();
return t;
P.OpenScope();
P.scope_lev++;
- t.list = array.New(0);
+ t.List = array.New(0);
for P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
- P.ParseVarList(t.list, false);
+ P.ParseVarList(t.List, false);
if P.tok == Scanner.STRING {
// ParseOperand takes care of string concatenation
- t.list.Push(P.ParseOperand());
+ t.List.Push(P.ParseOperand());
}
if P.tok == Scanner.SEMICOLON {
P.Next();
}
}
P.OptSemicolon();
- t.end = P.pos;
+ t.End = P.pos;
P.scope_lev--;
P.CloseScope();
t := AST.NewType(P.pos, AST.POINTER);
P.Expect(Scanner.MUL);
- t.elt = P.ParseType();
+ t.Elt = P.ParseType();
P.Ecart();
return t;
x = P.NewExpr(pos, Scanner.COMMA, x, y);
first = false;
} else {
- x.y = P.NewExpr(pos, Scanner.COMMA, x.y, y);
+ x.Y = P.NewExpr(pos, Scanner.COMMA, x.Y, y);
}
}
val := AST.NewObject(P.pos, AST.NONE, "");
x := AST.NewLit(Scanner.FUNC, val);
P.Expect(Scanner.FUNC);
- val.typ = P.ParseFunctionType();
+ val.Typ = P.ParseFunctionType();
P.expr_lev++;
P.scope_lev++;
- val.block, val.end = P.ParseBlock();
+ val.Block, val.End = P.ParseBlock();
P.scope_lev--;
P.expr_lev--;
x.t = P.ParseType();
if P.tok == Scanner.COMMA {
P.Next();
- x.y = P.ParseExpressionList();
+ x.Y = P.ParseExpressionList();
}
P.expr_lev--;
P.Expect(Scanner.RPAREN);
val := AST.NewObject(P.pos, AST.NONE, P.val);
x = AST.NewLit(P.tok, val);
P.Next();
- if x.tok == Scanner.STRING {
+ if x.Tok == Scanner.STRING {
// TODO should remember the list instead of
// concatenate the strings here
for ; P.tok == Scanner.STRING; P.Next() {
- x.obj.ident += P.val;
+ x.Obj.Ident += P.val;
}
}
P.Expect(Scanner.PERIOD);
if P.tok == Scanner.IDENT {
- x.y = P.ParseIdent(nil);
+ x.Y = P.ParseIdent(nil);
} else {
P.Expect(Scanner.LPAREN);
- x.y = AST.NewTypeExpr(P.ParseType());
+ x.Y = AST.NewTypeExpr(P.ParseType());
P.Expect(Scanner.RPAREN);
}
if P.tok != Scanner.RPAREN {
P.expr_lev++;
var t *AST.Type;
- if x0.tok == Scanner.IDENT && (x0.obj.ident == "new" || x0.obj.ident == "make") {
+ if x0.Tok == Scanner.IDENT && (x0.Obj.Ident == "new" || x0.Obj.Ident == "make") {
// heuristic: assume it's a new(T) or make(T, ...) call, try to parse a type
t = P.TryType();
}
if t != nil {
// we found a type
- x.y = AST.NewTypeExpr(t);
+ x.Y = AST.NewTypeExpr(t);
if P.tok == Scanner.COMMA {
pos := P.pos;
P.Next();
y := P.ParseExpressionList();
// create list manually because NewExpr checks for type expressions
z := AST.NewExpr(pos, Scanner.COMMA, nil, y);
- z.x = x.y;
- x.y = z;
+ z.X = x.Y;
+ x.Y = z;
}
} else {
// normal argument list
- x.y = P.ParseExpressionList();
+ x.Y = P.ParseExpressionList();
}
P.expr_lev--;
}
// first element determines mode
singles := true;
- if x.tok == Scanner.COLON {
+ if x.Tok == Scanner.COLON {
singles = false;
}
y := P.ParseExpression(0);
if singles {
- if y.tok == Scanner.COLON {
- P.Error(y.x.pos, "single value expected; found pair");
+ if y.Tok == Scanner.COLON {
+ P.Error(y.X.Pos, "single value expected; found pair");
}
} else {
- if y.tok != Scanner.COLON {
- P.Error(y.pos, "key:value pair expected; found single value");
+ if y.Tok != Scanner.COLON {
+ P.Error(y.Pos, "key:value pair expected; found single value");
}
}
x = P.NewExpr(pos, Scanner.COMMA, x, y);
last = x;
} else {
- last.y = P.NewExpr(pos, Scanner.COMMA, last.y, y);
- last = last.y;
+ last.Y = P.NewExpr(pos, Scanner.COMMA, last.Y, y);
+ last = last.Y;
}
if P.tok == Scanner.COMMA {
P.Trace("CompositeLit");
x := P.NewExpr(P.pos, Scanner.LBRACE, nil, nil);
- x.obj = AST.NewObject(t.pos, AST.TYPE, "");
- x.obj.typ = t;
+ x.Obj = AST.NewObject(t.Pos, AST.TYPE, "");
+ x.Obj.Typ = t;
P.Expect(Scanner.LBRACE);
if P.tok != Scanner.RBRACE {
- x.y = P.ParseCompositeElements();
+ x.Y = P.ParseCompositeElements();
}
P.Expect(Scanner.RBRACE);
// (composites inside control clauses must be parenthesized)
var t *AST.Type;
if P.expr_lev >= 0 {
- t = ExprType(x);
+ t = exprType(x);
}
if t != nil {
x = P.ParseCompositeLit(t);
pos, tok := P.pos, P.tok;
P.Next();
y := P.ParseUnaryExpr();
- if tok == Scanner.MUL && y.tok == Scanner.TYPE {
+ if tok == Scanner.MUL && y.Tok == Scanner.TYPE {
// pointer type
t := AST.NewType(pos, AST.POINTER);
- t.elt = y.obj.typ;
+ t.Elt = y.Obj.Typ;
x = AST.NewTypeExpr(t);
} else {
x = P.NewExpr(pos, tok, nil, y);
case Scanner.COLON:
// label declaration
s = AST.NewStat(P.pos, Scanner.COLON);
- s.expr = x;
+ s.Expr = x;
if x.Len() != 1 {
- P.Error(x.pos, "illegal label declaration");
+ P.Error(x.Pos, "illegal label declaration");
}
P.Next(); // consume ":"
P.opt_semi = true;
} else {
y = P.ParseExpressionList();
if is_range {
- P.Error(y.pos, "expected 'range', found expression");
+ P.Error(y.Pos, "expected 'range', found expression");
}
if xl, yl := x.Len(), y.Len(); xl > 1 && yl > 1 && xl != yl {
- P.Error(x.pos, "arity of lhs doesn't match rhs");
+ P.Error(x.Pos, "arity of lhs doesn't match rhs");
}
}
- s = AST.NewStat(x.pos, Scanner.EXPRSTAT);
- s.expr = AST.NewExpr(pos, tok, x, y);
+ s = AST.NewStat(x.Pos, Scanner.EXPRSTAT);
+ s.Expr = AST.NewExpr(pos, tok, x, y);
case Scanner.RANGE:
pos := P.pos;
P.Next();
y := P.ParseExpression(1);
y = P.NewExpr(pos, Scanner.RANGE, nil, y);
- s = AST.NewStat(x.pos, Scanner.EXPRSTAT);
- s.expr = AST.NewExpr(pos, Scanner.DEFINE, x, y);
+ s = AST.NewStat(x.Pos, Scanner.EXPRSTAT);
+ s.Expr = AST.NewExpr(pos, Scanner.DEFINE, x, y);
default:
var pos, tok int;
pos, tok = P.pos, P.tok;
P.Next();
} else {
- pos, tok = x.pos, Scanner.EXPRSTAT;
+ pos, tok = x.Pos, Scanner.EXPRSTAT;
}
s = AST.NewStat(pos, tok);
- s.expr = x;
+ s.Expr = x;
if x.Len() != 1 {
- P.Error(x.pos, "only one expression allowed");
+ P.Error(x.Pos, "only one expression allowed");
}
}
s := AST.NewStat(P.pos, Scanner.GO);
P.Expect(Scanner.GO);
- s.expr = P.ParseExpression(1);
+ s.Expr = P.ParseExpression(1);
P.Ecart();
return s;
s := AST.NewStat(P.pos, Scanner.RETURN);
P.Expect(Scanner.RETURN);
if P.tok != Scanner.SEMICOLON && P.tok != Scanner.RBRACE {
- s.expr = P.ParseExpressionList();
+ s.Expr = P.ParseExpressionList();
}
P.Ecart();
s := AST.NewStat(P.pos, tok);
P.Expect(tok);
if tok != Scanner.FALLTHROUGH && P.tok == Scanner.IDENT {
- s.expr = P.ParseIdent(P.top_scope);
+ s.Expr = P.ParseIdent(P.top_scope);
}
P.Ecart();
prev_lev := P.expr_lev;
P.expr_lev = -1;
if P.tok != Scanner.SEMICOLON {
- s.init = P.ParseSimpleStat(keyword == Scanner.FOR);
+ s.Init = P.ParseSimpleStat(keyword == Scanner.FOR);
// TODO check for range clause and exit if found
}
if P.tok == Scanner.SEMICOLON {
P.Next();
if P.tok != Scanner.SEMICOLON && P.tok != Scanner.LBRACE {
- s.expr = P.ParseExpression(1);
+ s.Expr = P.ParseExpression(1);
}
if keyword == Scanner.FOR {
P.Expect(Scanner.SEMICOLON);
if P.tok != Scanner.LBRACE {
- s.post = P.ParseSimpleStat(false);
+ s.Post = P.ParseSimpleStat(false);
}
}
} else {
- if s.init != nil { // guard in case of errors
- s.expr, s.init = s.init.expr, nil;
+ if s.Init != nil { // guard in case of errors
+ s.Expr, s.Init = s.Init.Expr, nil;
}
}
P.expr_lev = prev_lev;
P.OpenScope();
s := P.ParseControlClause(Scanner.IF);
- s.block, s.end = P.ParseBlock();
+ s.Block, s.End = P.ParseBlock();
if P.tok == Scanner.ELSE {
P.Next();
s1 := AST.BadStat;
s1 = P.ParseStatement();
if s1 != nil {
// not the empty statement
- if s1.tok != Scanner.LBRACE {
+ if s1.Tok != Scanner.LBRACE {
// wrap in a block if we don't have one
b := AST.NewStat(P.pos, Scanner.LBRACE);
- b.block = array.New(0);
- b.block.Push(s1);
+ b.Block = array.New(0);
+ b.Block.Push(s1);
s1 = b;
}
- s.post = s1;
+ s.Post = s1;
}
} else {
s1 = AST.NewStat(P.pos, Scanner.LBRACE);
- s1.block, s1.end = P.ParseBlock();
+ s1.Block, s1.End = P.ParseBlock();
}
- s.post = s1;
+ s.Post = s1;
}
P.CloseScope();
P.OpenScope();
s := P.ParseControlClause(Scanner.FOR);
- s.block, s.end = P.ParseBlock();
+ s.Block, s.End = P.ParseBlock();
P.CloseScope();
P.Ecart();
s := AST.NewStat(P.pos, P.tok);
if P.tok == Scanner.CASE {
P.Next();
- s.expr = P.ParseExpressionList();
+ s.Expr = P.ParseExpressionList();
} else {
P.Expect(Scanner.DEFAULT);
}
s := P.ParseCase();
if P.tok != Scanner.CASE && P.tok != Scanner.DEFAULT && P.tok != Scanner.RBRACE {
- s.block = P.ParseStatementList();
+ s.Block = P.ParseStatementList();
}
P.Ecart();
P.OpenScope();
s := P.ParseControlClause(Scanner.SWITCH);
- s.block = array.New(0);
+ s.Block = array.New(0);
P.Expect(Scanner.LBRACE);
for P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
- s.block.Push(P.ParseCaseClause());
+ s.Block.Push(P.ParseCaseClause());
}
- s.end = P.pos;
+ s.End = P.pos;
P.Expect(Scanner.RBRACE);
P.opt_semi = true;
P.CloseScope();
P.Expect(Scanner.ARROW); // use Expect() error handling
}
}
- s.expr = x;
+ s.Expr = x;
} else {
P.Expect(Scanner.DEFAULT);
}
s := P.ParseCommCase();
if P.tok != Scanner.CASE && P.tok != Scanner.DEFAULT && P.tok != Scanner.RBRACE {
- s.block = P.ParseStatementList();
+ s.Block = P.ParseStatementList();
}
P.Ecart();
P.Trace("SelectStat");
s := AST.NewStat(P.pos, Scanner.SELECT);
- s.block = array.New(0);
+ s.Block = array.New(0);
P.Expect(Scanner.SELECT);
P.Expect(Scanner.LBRACE);
for P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
- s.block.Push(P.ParseCommClause());
+ s.Block.Push(P.ParseCommClause());
}
P.Expect(Scanner.RBRACE);
P.opt_semi = true;
P.Expect(Scanner.RANGE);
P.ParseIdentList();
P.Expect(Scanner.DEFINE);
- s.expr = P.ParseExpression(1);
- s.block, s.end = P.ParseBlock();
+ s.Expr = P.ParseExpression(1);
+ s.Block, s.End = P.ParseBlock();
P.Ecart();
return s;
switch P.tok {
case Scanner.CONST, Scanner.TYPE, Scanner.VAR:
s = AST.NewStat(P.pos, P.tok);
- s.decl = P.ParseDeclaration();
+ s.Decl = P.ParseDeclaration();
case Scanner.FUNC:
// for now we do not allow local function declarations,
// instead we assume this starts a function literal
s = P.ParseControlFlowStat(P.tok);
case Scanner.LBRACE:
s = AST.NewStat(P.pos, Scanner.LBRACE);
- s.block, s.end = P.ParseBlock();
+ s.Block, s.End = P.ParseBlock();
case Scanner.IF:
s = P.ParseIfStat();
case Scanner.FOR:
P.Error(P.pos, `"import ." not yet handled properly`);
P.Next();
} else if P.tok == Scanner.IDENT {
- d.ident = P.ParseIdent(nil);
+ d.Ident = P.ParseIdent(nil);
}
if P.tok == Scanner.STRING {
// TODO eventually the scanner should strip the quotes
val := AST.NewObject(P.pos, AST.NONE, P.val);
- d.val = AST.NewLit(Scanner.STRING, val);
+ d.Val = AST.NewLit(Scanner.STRING, val);
P.Next();
} else {
P.Expect(Scanner.STRING); // use Expect() error handling
}
- if d.ident != nil {
- P.Declare(d.ident, AST.PACKAGE);
+ if d.Ident != nil {
+ P.Declare(d.Ident, AST.PACKAGE);
}
P.Ecart();
P.Trace("ConstSpec");
d := AST.NewDecl(pos, Scanner.CONST, exported);
- d.ident = P.ParseIdentList();
- d.typ = P.TryType();
+ d.Ident = P.ParseIdentList();
+ d.Typ = P.TryType();
if P.tok == Scanner.ASSIGN {
P.Next();
- d.val = P.ParseExpressionList();
+ d.Val = P.ParseExpressionList();
}
- P.Declare(d.ident, AST.CONST);
- P.VerifyExport(d.ident, exported);
+ P.Declare(d.Ident, AST.CONST);
+ P.VerifyExport(d.Ident, exported);
P.Ecart();
return d;
P.Trace("TypeSpec");
d := AST.NewDecl(pos, Scanner.TYPE, exported);
- d.ident = P.ParseIdent(nil);
- d.typ = P.ParseType();
+ d.Ident = P.ParseIdent(nil);
+ d.Typ = P.ParseType();
P.opt_semi = true;
- P.VerifyExport(d.ident, exported);
+ P.VerifyExport(d.Ident, exported);
P.Ecart();
return d;
P.Trace("VarSpec");
d := AST.NewDecl(pos, Scanner.VAR, exported);
- d.ident = P.ParseIdentList();
+ d.Ident = P.ParseIdentList();
if P.tok == Scanner.ASSIGN {
P.Next();
- d.val = P.ParseExpressionList();
+ d.Val = P.ParseExpressionList();
} else {
- d.typ = P.ParseVarType();
+ d.Typ = P.ParseVarType();
if P.tok == Scanner.ASSIGN {
P.Next();
- d.val = P.ParseExpressionList();
+ d.Val = P.ParseExpressionList();
}
}
- P.Declare(d.ident, AST.VAR);
- P.VerifyExport(d.ident, exported);
+ P.Declare(d.Ident, AST.VAR);
+ P.VerifyExport(d.Ident, exported);
P.Ecart();
return d;
if P.tok == Scanner.LPAREN {
P.Next();
d = AST.NewDecl(pos, keyword, exported);
- d.list = array.New(0);
+ d.List = array.New(0);
for P.tok != Scanner.RPAREN && P.tok != Scanner.EOF {
- d.list.Push(P.ParseSpec(exported, pos, keyword));
+ d.List.Push(P.ParseSpec(exported, pos, keyword));
if P.tok == Scanner.SEMICOLON {
P.Next();
} else {
break;
}
}
- d.end = P.pos;
+ d.End = P.pos;
P.Expect(Scanner.RPAREN);
P.opt_semi = true;
if P.tok == Scanner.LPAREN {
pos := P.pos;
recv = P.ParseParameters(true);
- if recv.nfields() != 1 {
+ if recv.Nfields() != 1 {
P.Error(pos, "must have exactly one receiver");
}
}
- d.ident = P.ParseIdent(nil);
- d.typ = P.ParseFunctionType();
- d.typ.key = recv;
+ d.Ident = P.ParseIdent(nil);
+ d.Typ = P.ParseFunctionType();
+ d.Typ.Key = recv;
if P.tok == Scanner.LBRACE {
P.scope_lev++;
- d.list, d.end = P.ParseBlock();
+ d.List, d.End = P.ParseBlock();
P.scope_lev--;
}
if recv == nil || exported {
- P.VerifyExport(d.ident, exported);
+ P.VerifyExport(d.Ident, exported);
}
P.Ecart();
P.Trace("ExportDecl");
d := AST.NewDecl(P.pos, Scanner.EXPORT, false);
- d.ident = P.ParseIdentList();
+ d.Ident = P.ParseIdentList();
P.Ecart();
return d;
P.OpenScope();
p := AST.NewProgram(P.pos);
P.Expect(Scanner.PACKAGE);
- p.ident = P.ParseIdent(nil);
+ p.Ident = P.ParseIdent(nil);
// package body
{ P.OpenScope();
- p.decls = array.New(0);
+ p.Decls = array.New(0);
for P.tok == Scanner.IMPORT {
- p.decls.Push(P.ParseDecl(false, Scanner.IMPORT));
+ p.Decls.Push(P.ParseDecl(false, Scanner.IMPORT));
P.OptSemicolon();
}
if !P.deps {
for P.tok != Scanner.EOF {
- p.decls.Push(P.ParseDeclaration());
+ p.Decls.Push(P.ParseDeclaration());
P.OptSemicolon();
}
}
P.CloseScope();
}
- p.comments = P.comments;
+ p.Comments = P.comments;
P.CloseScope();
P.Ecart();
USER string;
-func GetEnv(key string) string {
+func getEnv(key string) string {
n := len(key);
for i := 0; i < sys.envc(); i++ {
v := sys.envv(i);
func init() {
- GOARCH = GetEnv("GOARCH");
- GOOS = GetEnv("GOOS");
- GOROOT = GetEnv("GOROOT");
- USER = GetEnv("USER");
+ GOARCH = getEnv("GOARCH");
+ GOOS = getEnv("GOOS");
+ GOROOT = getEnv("GOROOT");
+ USER = getEnv("USER");
}
export const (
MAGIC_obj_file = "@gri-go.7@v0"; // make it clear that it cannot be a source file
- src_file_ext = ".go";
- obj_file_ext = ".7";
+ Src_file_ext = ".go";
+ Obj_file_ext = ".7";
)
export func ReadObjectFile(filename string) (data string, ok bool) {
- data, ok = sys.readfile(filename + obj_file_ext);
+ data, ok = sys.readfile(filename + Obj_file_ext);
magic := MAGIC_obj_file; // TODO remove once len(constant) works
if ok && len(data) >= len(magic) && data[0 : len(magic)] == magic {
return data, ok;
export func ReadSourceFile(name string) (data string, ok bool) {
- name = Utils.TrimExt(name, src_file_ext) + src_file_ext;
+ name = Utils.TrimExt(name, Src_file_ext) + Src_file_ext;
data, ok = sys.readfile(name);
return data, ok;
}
export func WriteObjectFile(name string, data string) bool {
- name = Utils.TrimExt(Utils.BaseName(name), src_file_ext) + obj_file_ext;
+ name = Utils.TrimExt(Utils.BaseName(name), Src_file_ext) + Obj_file_ext;
return sys.writefile(name, data);
}
}
-func Usage() {
+func usage() {
print("usage: pretty { flags } { files }\n");
Flag.PrintDefaults();
sys.exit(0);
Flag.Parse();
if Flag.NFlag() == 0 && Flag.NArg() == 0 {
- Usage();
+ usage();
}
// process files
)
-type Printer struct {
+export type Printer struct {
// output
text io.Write;
func (P *Printer) NextComment() {
P.cindex++;
if P.comments != nil && P.cindex < P.comments.Len() {
- P.cpos = P.comments.At(P.cindex).(*AST.Comment).pos;
+ P.cpos = P.comments.At(P.cindex).(*AST.Comment).Pos;
} else {
P.cpos = 1<<30; // infinite
}
// ----------------------------------------------------------------------------
// Printing support
-func HtmlEscape(s string) string {
+func htmlEscape(s string) string {
if *html {
var esc string;
for i := 0; i < len(s); i++ {
case '&': esc = "&";
default: continue;
}
- return s[0 : i] + esc + HtmlEscape(s[i+1 : len(s)]);
+ return s[0 : i] + esc + htmlEscape(s[i+1 : len(s)]);
}
}
return s;
// Reduce contiguous sequences of '\t' in a string to a single '\t'.
-func Untabify(s string) string {
+func untabify(s string) string {
for i := 0; i < len(s); i++ {
if s[i] == '\t' {
j := i;
j++;
}
if j-i > 1 { // more then one tab
- return s[0 : i+1] + Untabify(s[j : len(s)]);
+ return s[0 : i+1] + untabify(s[j : len(s)]);
}
}
}
for ; P.HasComment(pos); P.NextComment() {
// we have a comment/newline that comes before the string
comment := P.comments.At(P.cindex).(*AST.Comment);
- ctext := comment.text;
+ ctext := comment.Text;
if ctext == "\n" {
// found a newline in src - count it
if *debug {
P.Printf("[%d]", P.cpos);
}
- // calling Untabify increases the change for idempotent output
+ // calling untabify increases the change for idempotent output
// since tabs in comments are also interpreted by tabwriter
- P.Printf("%s", HtmlEscape(Untabify(ctext)));
+ P.Printf("%s", htmlEscape(untabify(ctext)));
if ctext[1] == '/' {
//-style comments must end in newline
if *debug {
P.Printf("[%d]", pos);
}
- P.Printf("%s%s%s", tag, HtmlEscape(s), endtag);
+ P.Printf("%s%s%s", tag, htmlEscape(s), endtag);
// --------------------------------
// interpret state
"<html>\n"
"<head>\n"
" <META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\">\n"
- " <title>" + HtmlEscape(title) + "</title>\n"
+ " <title>" + htmlEscape(title) + "</title>\n"
" <style type=\"text/css\">\n"
" </style>\n"
"</head>\n"
func (P *Printer) HtmlIdentifier(x *AST.Expr) {
- if x.tok != Scanner.IDENT {
+ if x.Tok != Scanner.IDENT {
panic();
}
- obj := x.obj;
- if *html && obj.kind != AST.NONE {
+ obj := x.Obj;
+ 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);
- if x.pos == obj.pos {
+ // - no need to htmlEscape ident
+ id := Utils.IntToString(obj.Id, 10);
+ if x.Pos == obj.Pos {
// probably the declaration of x
- P.TaggedString(x.pos, `<a name="id` + id + `">`, obj.ident, `</a>`);
+ P.TaggedString(x.Pos, `<a name="id` + id + `">`, obj.Ident, `</a>`);
} else {
// probably not the declaration of x
- P.TaggedString(x.pos, `<a href="#id` + id + `">`, obj.ident, `</a>`);
+ P.TaggedString(x.Pos, `<a href="#id` + id + `">`, obj.Ident, `</a>`);
}
} else {
- P.String(x.pos, obj.ident);
+ P.String(x.Pos, obj.Ident);
}
}
for i, n := 0, list.Len(); i < n; i++ {
x := list.At(i).(*AST.Expr);
if i > 0 {
- if prev == x.tok || prev == Scanner.TYPE {
+ if prev == x.Tok || prev == Scanner.TYPE {
P.separator = comma;
} else {
P.separator = blank;
}
}
P.Expr(x);
- prev = x.tok;
+ prev = x.Tok;
}
}
P.String(0, ")");
for i, n := 0, list.Len(); i < n; i++ {
x := list.At(i).(*AST.Expr);
if i > 0 {
- if prev == Scanner.TYPE && x.tok != Scanner.STRING || prev == Scanner.STRING {
+ if prev == Scanner.TYPE && x.Tok != Scanner.STRING || prev == Scanner.STRING {
P.separator = semicolon;
P.newlines = 1;
- } else if prev == x.tok {
+ } else if prev == x.Tok {
P.separator = comma;
} else {
P.separator = tab;
}
}
P.Expr(x);
- prev = x.tok;
+ prev = x.Tok;
}
P.newlines = 1;
}
func (P *Printer) Type(t *AST.Type) int {
separator := semicolon;
- switch t.form {
+ switch t.Form {
case AST.TYPENAME:
- P.Expr(t.expr);
+ P.Expr(t.Expr);
case AST.ARRAY:
- P.String(t.pos, "[");
- if t.expr != nil {
- P.Expr(t.expr);
+ P.String(t.Pos, "[");
+ if t.Expr != nil {
+ P.Expr(t.Expr);
}
P.String(0, "]");
- separator = P.Type(t.elt);
+ separator = P.Type(t.Elt);
case AST.STRUCT, AST.INTERFACE:
- switch t.form {
- case AST.STRUCT: P.String(t.pos, "struct");
- case AST.INTERFACE: P.String(t.pos, "interface");
+ 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.Fields(t.list, t.end);
+ P.Fields(t.List, t.End);
}
separator = none;
case AST.MAP:
- P.String(t.pos, "map [");
- P.Type(t.key);
+ P.String(t.Pos, "map [");
+ P.Type(t.Key);
P.String(0, "]");
- separator = P.Type(t.elt);
+ separator = P.Type(t.Elt);
case AST.CHANNEL:
var m string;
- switch t.mode {
+ switch t.Mode {
case AST.FULL: m = "chan ";
case AST.RECV: m = "<-chan ";
case AST.SEND: m = "chan <- ";
}
- P.String(t.pos, m);
- separator = P.Type(t.elt);
+ P.String(t.Pos, m);
+ separator = P.Type(t.Elt);
case AST.POINTER:
- P.String(t.pos, "*");
- separator = P.Type(t.elt);
+ P.String(t.Pos, "*");
+ separator = P.Type(t.Elt);
case AST.FUNCTION:
- P.Parameters(t.pos, t.list);
- if t.elt != nil {
+ P.Parameters(t.Pos, t.List);
+ if t.Elt != nil {
P.separator = blank;
- list := t.elt.list;
+ list := t.Elt.List;
if list.Len() > 1 {
P.Parameters(0, list);
} else {
}
case AST.ELLIPSIS:
- P.String(t.pos, "...");
+ P.String(t.Pos, "...");
default:
- P.Error(t.pos, t.form, "type");
+ P.Error(t.Pos, t.Form, "type");
}
return separator;
return; // empty expression list
}
- switch x.tok {
+ switch x.Tok {
case Scanner.TYPE:
// type expr
- P.Type(x.obj.typ);
+ P.Type(x.Obj.Typ);
case Scanner.IDENT:
P.HtmlIdentifier(x);
case Scanner.INT, Scanner.STRING, Scanner.FLOAT:
// literal
- P.String(x.pos, x.obj.ident);
+ P.String(x.Pos, x.Obj.Ident);
case Scanner.FUNC:
// function literal
- P.String(x.pos, "func");
- P.Type(x.obj.typ);
- P.Block(0, x.obj.block, x.obj.end, true);
+ P.String(x.Pos, "func");
+ P.Type(x.Obj.Typ);
+ P.Block(0, x.Obj.Block, x.Obj.End, true);
P.newlines = 0;
case Scanner.COMMA:
// list
// (don't use binary expression printing because of different spacing)
- P.Expr(x.x);
- P.String(x.pos, ",");
+ P.Expr(x.X);
+ P.String(x.Pos, ",");
P.separator = blank;
P.state = inside_list;
- P.Expr(x.y);
+ P.Expr(x.Y);
case Scanner.PERIOD:
// selector or type guard
- P.Expr1(x.x, Scanner.HighestPrec);
- P.String(x.pos, ".");
- if x.y.tok == Scanner.TYPE {
+ P.Expr1(x.X, Scanner.HighestPrec);
+ P.String(x.Pos, ".");
+ if x.Y.Tok == Scanner.TYPE {
P.String(0, "(");
- P.Expr(x.y);
+ P.Expr(x.Y);
P.String(0, ")");
} else {
- P.Expr1(x.y, Scanner.HighestPrec);
+ P.Expr1(x.Y, Scanner.HighestPrec);
}
case Scanner.LBRACK:
// index
- P.Expr1(x.x, Scanner.HighestPrec);
- P.String(x.pos, "[");
- P.Expr1(x.y, 0);
+ P.Expr1(x.X, Scanner.HighestPrec);
+ P.String(x.Pos, "[");
+ P.Expr1(x.Y, 0);
P.String(0, "]");
case Scanner.LPAREN:
// call
- P.Expr1(x.x, Scanner.HighestPrec);
- P.String(x.pos, "(");
- P.Expr(x.y);
+ P.Expr1(x.X, Scanner.HighestPrec);
+ P.String(x.Pos, "(");
+ P.Expr(x.Y);
P.String(0, ")");
case Scanner.LBRACE:
// composite literal
- P.Type(x.obj.typ);
- P.String(x.pos, "{");
- P.Expr(x.y);
+ P.Type(x.Obj.Typ);
+ P.String(x.Pos, "{");
+ P.Expr(x.Y);
P.String(0, "}");
default:
// unary and binary expressions including ":" for pairs
prec := Scanner.UnaryPrec;
- if x.x != nil {
- prec = Scanner.Precedence(x.tok);
+ if x.X != nil {
+ prec = Scanner.Precedence(x.Tok);
}
if prec < prec1 {
P.String(0, "(");
}
- if x.x == nil {
+ if x.X == nil {
// unary expression
- P.Token(x.pos, x.tok);
- if x.tok == Scanner.RANGE {
+ P.Token(x.Pos, x.Tok);
+ if x.Tok == Scanner.RANGE {
P.separator = blank;
}
} else {
// binary expression
- P.Expr1(x.x, prec);
+ P.Expr1(x.X, prec);
P.separator = blank;
- P.Token(x.pos, x.tok);
+ P.Token(x.Pos, x.Tok);
P.separator = blank;
}
- P.Expr1(x.y, prec);
+ P.Expr1(x.Y, prec);
if prec < prec1 {
P.String(0, ")");
}
func (P *Printer) ControlClause(s *AST.Stat) {
- has_post := s.tok == Scanner.FOR && s.post != nil; // post also used by "if"
+ has_post := s.Tok == Scanner.FOR && s.Post != nil; // post also used by "if"
P.separator = blank;
- if s.init == nil && !has_post {
+ if s.Init == nil && !has_post {
// no semicolons required
- if s.expr != nil {
- P.Expr(s.expr);
+ if s.Expr != nil {
+ P.Expr(s.Expr);
}
} else {
// all semicolons required
// (they are not separators, print them explicitly)
- if s.init != nil {
- P.Stat(s.init);
+ if s.Init != nil {
+ P.Stat(s.Init);
P.separator = none;
}
P.String(0, ";");
P.separator = blank;
- if s.expr != nil {
- P.Expr(s.expr);
+ if s.Expr != nil {
+ P.Expr(s.Expr);
P.separator = none;
}
- if s.tok == Scanner.FOR {
+ if s.Tok == Scanner.FOR {
P.String(0, ";");
P.separator = blank;
if has_post {
- P.Stat(s.post);
+ P.Stat(s.Post);
}
}
}
func (P *Printer) Declaration(d *AST.Decl, parenthesized bool);
func (P *Printer) Stat(s *AST.Stat) {
- switch s.tok {
+ switch s.Tok {
case Scanner.EXPRSTAT:
// expression statement
- P.Expr(s.expr);
+ P.Expr(s.Expr);
P.separator = semicolon;
case Scanner.COLON:
// label declaration
P.indentation--;
- P.Expr(s.expr);
- P.Token(s.pos, s.tok);
+ P.Expr(s.Expr);
+ P.Token(s.Pos, s.Tok);
P.indentation++;
P.separator = none;
case Scanner.CONST, Scanner.TYPE, Scanner.VAR:
// declaration
- P.Declaration(s.decl, false);
+ P.Declaration(s.Decl, false);
case Scanner.INC, Scanner.DEC:
- P.Expr(s.expr);
- P.Token(s.pos, s.tok);
+ P.Expr(s.Expr);
+ P.Token(s.Pos, s.Tok);
P.separator = semicolon;
case Scanner.LBRACE:
// block
- P.Block(s.pos, s.block, s.end, true);
+ P.Block(s.Pos, s.Block, s.End, true);
case Scanner.IF:
- P.String(s.pos, "if");
+ P.String(s.Pos, "if");
P.ControlClause(s);
- P.Block(0, s.block, s.end, true);
- if s.post != nil {
+ P.Block(0, s.Block, s.End, true);
+ if s.Post != nil {
P.separator = blank;
P.String(0, "else");
P.separator = blank;
- P.Stat(s.post);
+ P.Stat(s.Post);
}
case Scanner.FOR:
- P.String(s.pos, "for");
+ P.String(s.Pos, "for");
P.ControlClause(s);
- P.Block(0, s.block, s.end, true);
+ P.Block(0, s.Block, s.End, true);
case Scanner.SWITCH, Scanner.SELECT:
- P.Token(s.pos, s.tok);
+ P.Token(s.Pos, s.Tok);
P.ControlClause(s);
- P.Block(0, s.block, s.end, false);
+ P.Block(0, s.Block, s.End, false);
case Scanner.CASE, Scanner.DEFAULT:
- P.Token(s.pos, s.tok);
- if s.expr != nil {
+ P.Token(s.Pos, s.Tok);
+ if s.Expr != nil {
P.separator = blank;
- P.Expr(s.expr);
+ P.Expr(s.Expr);
}
P.String(0, ":");
P.indentation++;
- P.StatementList(s.block);
+ P.StatementList(s.Block);
P.indentation--;
P.newlines = 1;
case Scanner.GO, Scanner.RETURN, Scanner.FALLTHROUGH, Scanner.BREAK, Scanner.CONTINUE, Scanner.GOTO:
- P.Token(s.pos, s.tok);
- if s.expr != nil {
+ P.Token(s.Pos, s.Tok);
+ if s.Expr != nil {
P.separator = blank;
- P.Expr(s.expr);
+ P.Expr(s.Expr);
}
P.separator = semicolon;
default:
- P.Error(s.pos, s.tok, "stat");
+ P.Error(s.Pos, s.Tok, "stat");
}
}
func (P *Printer) Declaration(d *AST.Decl, parenthesized bool) {
if !parenthesized {
- if d.exported {
- P.String(d.pos, "export");
+ if d.Exported {
+ P.String(d.Pos, "export");
P.separator = blank;
}
- P.Token(d.pos, d.tok);
+ P.Token(d.Pos, d.Tok);
P.separator = blank;
}
- if d.tok != Scanner.FUNC && d.list != nil {
+ if d.Tok != Scanner.FUNC && d.List != nil {
// group of parenthesized declarations
P.state = opening_scope;
P.String(0, "(");
- if d.list.Len() > 0 {
+ if d.List.Len() > 0 {
P.newlines = 1;
- for i := 0; i < d.list.Len(); i++ {
- P.Declaration(d.list.At(i).(*AST.Decl), true);
+ for i := 0; i < d.List.Len(); i++ {
+ P.Declaration(d.List.At(i).(*AST.Decl), true);
P.separator = semicolon;
P.newlines = 1;
}
}
P.state = closing_scope;
- P.String(d.end, ")");
+ P.String(d.End, ")");
} else {
// single declaration
- switch d.tok {
+ switch d.Tok {
case Scanner.IMPORT:
- if d.ident != nil {
- P.Expr(d.ident);
+ if d.Ident != nil {
+ P.Expr(d.Ident);
} else {
- P.String(d.val.pos, ""); // flush pending ';' separator/newlines
+ P.String(d.Val.Pos, ""); // flush pending ';' separator/newlines
}
P.separator = tab;
- P.Expr(d.val);
+ P.Expr(d.Val);
P.separator = semicolon;
case Scanner.EXPORT:
- P.Expr(d.ident);
+ P.Expr(d.Ident);
P.separator = semicolon;
case Scanner.TYPE:
- P.Expr(d.ident);
+ P.Expr(d.Ident);
P.separator = blank; // TODO switch to tab? (but indentation problem with structs)
- P.separator = P.Type(d.typ);
+ P.separator = P.Type(d.Typ);
case Scanner.CONST, Scanner.VAR:
- P.Expr(d.ident);
- if d.typ != nil {
+ P.Expr(d.Ident);
+ if d.Typ != nil {
P.separator = blank; // TODO switch to tab? (indentation problem with structs)
- P.separator = P.Type(d.typ);
+ P.separator = P.Type(d.Typ);
}
- if d.val != nil {
+ if d.Val != nil {
P.separator = tab;
P.String(0, "=");
P.separator = blank;
- P.Expr(d.val);
+ P.Expr(d.Val);
}
P.separator = semicolon;
case Scanner.FUNC:
- if d.typ.key != nil {
+ if d.Typ.Key != nil {
// method: print receiver
- P.Parameters(0, d.typ.key.list);
+ P.Parameters(0, d.Typ.Key.List);
P.separator = blank;
}
- P.Expr(d.ident);
- P.separator = P.Type(d.typ);
- if d.list != nil {
+ P.Expr(d.Ident);
+ P.separator = P.Type(d.Typ);
+ if d.List != nil {
P.separator = blank;
- P.Block(0, d.list, d.end, true);
+ P.Block(0, d.List, d.End, true);
}
default:
- P.Error(d.pos, d.tok, "decl");
+ P.Error(d.Pos, d.Tok, "decl");
}
}
// Program
func (P *Printer) Program(p *AST.Program) {
- P.String(p.pos, "package");
+ P.String(p.Pos, "package");
P.separator = blank;
- P.Expr(p.ident);
+ P.Expr(p.Ident);
P.newlines = 1;
- for i := 0; i < p.decls.Len(); i++ {
- P.Declaration(p.decls.At(i).(*AST.Decl), false);
+ for i := 0; i < p.Decls.Len(); i++ {
+ P.Declaration(p.Decls.At(i).(*AST.Decl), false);
}
P.newlines = 1;
}
padchar = '\t';
}
text := tabwriter.New(os.Stdout, *tabwidth, 1, padchar, true, *html);
- P.Init(text, prog.comments);
+ P.Init(text, prog.Comments);
// TODO would be better to make the name of the src file be the title
- P.HtmlPrologue("package " + prog.ident.obj.ident);
+ P.HtmlPrologue("package " + prog.Ident.Obj.Ident);
P.Program(prog);
P.HtmlEpilogue();
package Scanner
-import "utf8"
-import "unicode"
-import Utils "utils"
-
+import (
+ "utf8";
+ "unicode";
+ "utils";
+)
export const (
ILLEGAL = iota;
PERIOD;
// keywords
- KEYWORDS_BEG;
+ Keywords_beg; // do not export eventually
BREAK;
CASE;
CHAN;
SWITCH;
TYPE;
VAR;
- KEYWORDS_END;
+ Keywords_end; // do not export eventually
// AST use only
EXPRSTAT;
}
-var Keywords map [string] int;
+var keywords map [string] int;
func init() {
- Keywords = make(map [string] int);
- for i := KEYWORDS_BEG + 1; i < KEYWORDS_END; i++ {
- Keywords[TokenString(i)] = i;
+ keywords = make(map [string] int);
+ for i := Keywords_beg + 1; i < Keywords_end; i++ {
+ keywords[TokenString(i)] = i;
}
}
// Read the next Unicode char into S.ch.
// S.ch < 0 means end-of-file.
-func (S *Scanner) Next() {
+func (S *Scanner) next() {
if S.pos < len(S.src) {
// assume ascii
r, w := int(S.src[S.pos]), 1;
}
-func (S *Scanner) ExpectNoErrors() {
+func (S *Scanner) expectNoErrors() {
// set the next expected error position to one after eof
// (the eof position is a legal error position!)
S.testpos = len(S.src) + 1;
S.linepos = 0;
S.testmode = testmode;
- S.ExpectNoErrors(); // S.src must be set
- S.Next(); // S.ExpectNoErrrors() must be called before
+ S.expectNoErrors(); // S.src must be set
+ S.next(); // S.expectNoErrrors() must be called before
}
-func CharString(ch int) string {
+func charString(ch int) string {
s := string(ch);
switch ch {
case '\a': s = `\a`;
}
-func (S *Scanner) Expect(ch int) {
+func (S *Scanner) expect(ch int) {
if S.ch != ch {
- S.Error(S.chpos, "expected " + CharString(ch) + ", found " + CharString(S.ch));
+ S.Error(S.chpos, "expected " + charString(ch) + ", found " + charString(S.ch));
}
- S.Next(); // make always progress
+ S.next(); // make always progress
}
-func (S *Scanner) SkipWhitespace() {
+func (S *Scanner) skipWhitespace() {
for {
switch S.ch {
case '\t', '\r', ' ':
default:
return;
}
- S.Next();
+ S.next();
}
panic("UNREACHABLE");
}
-func (S *Scanner) ScanComment() string {
+func (S *Scanner) scanComment() string {
// first '/' already consumed
pos := S.chpos - 1;
if S.ch == '/' {
//-style comment
- S.Next();
+ S.next();
for S.ch >= 0 {
- S.Next();
+ S.next();
if S.ch == '\n' {
// '\n' terminates comment but we do not include
// it in the comment (otherwise we don't see the
- // start of a newline in SkipWhitespace()).
+ // start of a newline in skipWhitespace()).
goto exit;
}
}
} else {
/*-style comment */
- S.Expect('*');
+ S.expect('*');
for S.ch >= 0 {
ch := S.ch;
- S.Next();
+ S.next();
if ch == '*' && S.ch == '/' {
- S.Next();
+ S.next();
goto exit;
}
}
case len(comment) >= 8 && comment[3 : 8] == "ERROR" :
// an error is expected at the next token position
oldpos = S.testpos;
- S.SkipWhitespace();
+ S.skipWhitespace();
S.testpos = S.chpos;
case len(comment) >= 7 && comment[3 : 7] == "SYNC" :
// scanning/parsing synchronized again - no (follow-up) errors expected
oldpos = S.testpos;
- S.ExpectNoErrors();
+ S.expectNoErrors();
}
if 0 <= oldpos && oldpos <= len(S.src) {
}
-func (S *Scanner) ScanIdentifier() (tok int, val string) {
+func (S *Scanner) scanIdentifier() (tok int, val string) {
pos := S.chpos;
for is_letter(S.ch) || digit_val(S.ch) < 10 {
- S.Next();
+ S.next();
}
val = S.src[pos : S.chpos];
var present bool;
- tok, present = Keywords[val];
+ tok, present = keywords[val];
if !present {
tok = IDENT;
}
}
-func (S *Scanner) ScanMantissa(base int) {
+func (S *Scanner) scanMantissa(base int) {
for digit_val(S.ch) < base {
- S.Next();
+ S.next();
}
}
-func (S *Scanner) ScanNumber(seen_decimal_point bool) (tok int, val 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);
+ S.scanMantissa(10);
goto exponent;
}
if S.ch == '0' {
// int or float
- S.Next();
+ S.next();
if S.ch == 'x' || S.ch == 'X' {
// hexadecimal int
- S.Next();
- S.ScanMantissa(16);
+ S.next();
+ S.scanMantissa(16);
} else {
// octal int or float
- S.ScanMantissa(8);
+ S.scanMantissa(8);
if digit_val(S.ch) < 10 || S.ch == '.' || S.ch == 'e' || S.ch == 'E' {
// float
tok = FLOAT;
mantissa:
// decimal int or float
- S.ScanMantissa(10);
+ S.scanMantissa(10);
if S.ch == '.' {
// float
tok = FLOAT;
- S.Next();
- S.ScanMantissa(10)
+ S.next();
+ S.scanMantissa(10)
}
exponent:
if S.ch == 'e' || S.ch == 'E' {
// float
tok = FLOAT;
- S.Next();
+ S.next();
if S.ch == '-' || S.ch == '+' {
- S.Next();
+ S.next();
}
- S.ScanMantissa(10);
+ S.scanMantissa(10);
}
exit:
}
-func (S *Scanner) ScanDigits(n int, base int) {
+func (S *Scanner) scanDigits(n int, base int) {
for digit_val(S.ch) < base {
- S.Next();
+ S.next();
n--;
}
if n > 0 {
}
-func (S *Scanner) ScanEscape(quote int) string {
+func (S *Scanner) scanEscape(quote int) string {
// TODO: fix this routine
ch := S.ch;
pos := S.chpos;
- S.Next();
+ S.next();
switch ch {
case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\':
return string(ch);
case '0', '1', '2', '3', '4', '5', '6', '7':
- S.ScanDigits(3 - 1, 8); // 1 char already read
+ S.scanDigits(3 - 1, 8); // 1 char already read
return ""; // TODO fix this
case 'x':
- S.ScanDigits(2, 16);
+ S.scanDigits(2, 16);
return ""; // TODO fix this
case 'u':
- S.ScanDigits(4, 16);
+ S.scanDigits(4, 16);
return ""; // TODO fix this
case 'U':
- S.ScanDigits(8, 16);
+ S.scanDigits(8, 16);
return ""; // TODO fix this
default:
}
-func (S *Scanner) ScanChar() string {
+func (S *Scanner) scanChar() string {
// '\'' already consumed
pos := S.chpos - 1;
ch := S.ch;
- S.Next();
+ S.next();
if ch == '\\' {
- S.ScanEscape('\'');
+ S.scanEscape('\'');
}
- S.Expect('\'');
+ S.expect('\'');
return S.src[pos : S.chpos];
}
-func (S *Scanner) ScanString() string {
+func (S *Scanner) scanString() string {
// '"' already consumed
pos := S.chpos - 1;
for S.ch != '"' {
ch := S.ch;
- S.Next();
+ S.next();
if ch == '\n' || ch < 0 {
S.Error(pos, "string not terminated");
break;
}
if ch == '\\' {
- S.ScanEscape('"');
+ S.scanEscape('"');
}
}
- S.Next();
+ S.next();
return S.src[pos : S.chpos];
}
-func (S *Scanner) ScanRawString() string {
+func (S *Scanner) scanRawString() string {
// '`' already consumed
pos := S.chpos - 1;
for S.ch != '`' {
ch := S.ch;
- S.Next();
+ S.next();
if ch == '\n' || ch < 0 {
S.Error(pos, "string not terminated");
break;
}
}
- S.Next();
+ S.next();
return S.src[pos : S.chpos];
}
-func (S *Scanner) Select2(tok0, tok1 int) int {
+func (S *Scanner) select2(tok0, tok1 int) int {
if S.ch == '=' {
- S.Next();
+ S.next();
return tok1;
}
return tok0;
}
-func (S *Scanner) Select3(tok0, tok1, ch2, tok2 int) int {
+func (S *Scanner) select3(tok0, tok1, ch2, tok2 int) int {
if S.ch == '=' {
- S.Next();
+ S.next();
return tok1;
}
if S.ch == ch2 {
- S.Next();
+ S.next();
return tok2;
}
return tok0;
}
-func (S *Scanner) Select4(tok0, tok1, ch2, tok2, tok3 int) int {
+func (S *Scanner) select4(tok0, tok1, ch2, tok2, tok3 int) int {
if S.ch == '=' {
- S.Next();
+ S.next();
return tok1;
}
if S.ch == ch2 {
- S.Next();
+ S.next();
if S.ch == '=' {
- S.Next();
+ S.next();
return tok3;
}
return tok2;
func (S *Scanner) Scan() (pos, tok int, val string) {
loop:
- S.SkipWhitespace();
+ S.skipWhitespace();
pos, tok = S.chpos, ILLEGAL;
switch ch := S.ch; {
- case is_letter(ch): tok, val = S.ScanIdentifier();
- case digit_val(ch) < 10: tok, val = S.ScanNumber(false);
+ case is_letter(ch): tok, val = S.scanIdentifier();
+ case digit_val(ch) < 10: tok, val = S.scanNumber(false);
default:
- S.Next(); // always make progress
+ S.next(); // always make progress
switch ch {
case -1: tok = EOF;
case '\n': tok, val = COMMENT, "\n";
- case '"': tok, val = STRING, S.ScanString();
- case '\'': tok, val = INT, S.ScanChar();
- case '`': tok, val = STRING, S.ScanRawString();
- case ':': tok = S.Select2(COLON, DEFINE);
+ case '"': tok, val = STRING, S.scanString();
+ 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 = S.ScanNumber(true);
+ tok, val = S.scanNumber(true);
} else if S.ch == '.' {
- S.Next();
+ S.next();
if S.ch == '.' {
- S.Next();
+ S.next();
tok = ELLIPSIS;
}
} else {
case ']': tok = RBRACK;
case '{': tok = LBRACE;
case '}': tok = RBRACE;
- case '+': tok = S.Select3(ADD, ADD_ASSIGN, '+', INC);
- case '-': tok = S.Select3(SUB, SUB_ASSIGN, '-', DEC);
- case '*': tok = S.Select2(MUL, MUL_ASSIGN);
+ case '+': tok = S.select3(ADD, ADD_ASSIGN, '+', INC);
+ case '-': tok = S.select3(SUB, SUB_ASSIGN, '-', DEC);
+ case '*': tok = S.select2(MUL, MUL_ASSIGN);
case '/':
if S.ch == '/' || S.ch == '*' {
- tok, val = COMMENT, S.ScanComment();
+ tok, val = COMMENT, S.scanComment();
if !S.scan_comments {
goto loop;
}
} else {
- tok = S.Select2(QUO, QUO_ASSIGN);
+ tok = S.select2(QUO, QUO_ASSIGN);
}
- case '%': tok = S.Select2(REM, REM_ASSIGN);
- case '^': tok = S.Select2(XOR, XOR_ASSIGN);
+ case '%': tok = S.select2(REM, REM_ASSIGN);
+ case '^': tok = S.select2(XOR, XOR_ASSIGN);
case '<':
if S.ch == '-' {
- S.Next();
+ S.next();
tok = ARROW;
} else {
- tok = S.Select4(LSS, LEQ, '<', SHL, SHL_ASSIGN);
+ tok = S.select4(LSS, LEQ, '<', SHL, SHL_ASSIGN);
}
- case '>': tok = S.Select4(GTR, GEQ, '>', SHR, SHR_ASSIGN);
- case '=': tok = S.Select2(ASSIGN, EQL);
- case '!': tok = S.Select2(NOT, NEQ);
- case '&': tok = S.Select3(AND, AND_ASSIGN, '&', LAND);
- case '|': tok = S.Select3(OR, OR_ASSIGN, '|', LOR);
+ case '>': tok = S.select4(GTR, GEQ, '>', SHR, SHR_ASSIGN);
+ case '=': tok = S.select2(ASSIGN, EQL);
+ case '!': tok = S.select2(NOT, NEQ);
+ case '&': tok = S.select3(AND, AND_ASSIGN, '&', LAND);
+ case '|': tok = S.select3(OR, OR_ASSIGN, '|', LOR);
default:
- S.Error(pos, "illegal character " + CharString(ch));
+ S.Error(pos, "illegal character " + charString(ch));
tok = ILLEGAL;
}
}
export type Token struct {
- pos int;
- tok int;
- val string;
+ Pos int;
+ Tok int;
+ Val string;
}
go func(S *Scanner, ch chan <- *Token) {
for {
t := new(Token);
- t.pos, t.tok, t.val = S.Scan();
+ t.Pos, t.Tok, t.Val = S.Scan();
ch <- t;
- if t.tok == EOF {
+ if t.Tok == EOF {
break;
}
}
package main
-type Proto struct {
+export type Proto struct {
a int "a tag";
b, c, d *Proto "bcd" "tag";
*Proto "proto tag"
)
-const /* enum1 */ (
+export const /* enum1 */ (
EnumTag0 = iota;
EnumTag1;
EnumTag2;
)
-type S struct {}
+export type S struct {}
-type T struct {
+export type T struct {
x, y int;
s string;
next_t *T
var (
- A = 5;
+ aa = 5;
u, v, w int = 0, 0, 0;
foo = "foo";
fixed_array0 = [10]int{};
var (
// Unicode identifiers
- ä, ö, ü, Á, Ø, Å, ƒ, ß int;
+ ä, ö, ü, ƒ, ß int;
)
}
println("A3");
- for i : x := range a {
+ for i, x := range a {
println(i, x);
}
println("M1");
- for i range m {
+ for i := range m {
println(i);
}
println("M2");
- for i, x range m {
+ for i, x := range m {
println(i, x);
}
println("M3");
var i string;
var x int;
- for i : x = range m {
+ for i, x = range m {
println(i, x);
}
}
COUNT=0
count() {
+ #echo $1
let COUNT=$COUNT+1
let M=$COUNT%10
if [ $M == 0 ]; then
# 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 ) ;;
- * ) $1 $2; count ;;
+ * ) $1 $2; count $F;;
esac
}
echo "Error (selftest1): pretty -t selftest1.go"
exit 1
fi
-count
+count selftest1.go
# run over all .go files
)
-type State struct {
+type state struct {
// setup
err Scanner.ErrorHandler;
}
-func (s *State) Init(err Scanner.ErrorHandler) {
+func (s *state) Init(err Scanner.ErrorHandler) {
s.err = err;
}
}
-func (s *State) Error(pos int, msg string) {
+func (s *state) Error(pos int, msg string) {
s.err.Error(pos, msg);
}
// ----------------------------------------------------------------------------
-func (s *State) CheckType() {
+func (s *state) CheckType() {
}
-func (s *State) CheckDeclaration(d *AST.Decl) {
- if d.tok != Scanner.FUNC && d.list != nil {
+func (s *state) CheckDeclaration(d *AST.Decl) {
+ if d.Tok != Scanner.FUNC && d.List != nil {
// group of parenthesized declarations
- for i := 0; i < d.list.Len(); i++ {
- s.CheckDeclaration(d.list.At(i).(*AST.Decl))
+ for i := 0; i < d.List.Len(); i++ {
+ s.CheckDeclaration(d.List.At(i).(*AST.Decl))
}
} else {
// single declaration
- switch d.tok {
+ switch d.Tok {
case Scanner.IMPORT:
case Scanner.EXPORT:
case Scanner.CONST:
}
-func (s *State) CheckProgram(p *AST.Program) {
- for i := 0; i < p.decls.Len(); i++ {
- s.CheckDeclaration(p.decls.At(i).(*AST.Decl));
+func (s *state) CheckProgram(p *AST.Program) {
+ for i := 0; i < p.Decls.Len(); i++ {
+ s.CheckDeclaration(p.Decls.At(i).(*AST.Decl));
}
}
// ----------------------------------------------------------------------------
export func CheckProgram(err Scanner.ErrorHandler, p *AST.Program) {
- var s State;
+ var s state;
s.Init(err);
s.CheckProgram(p);
}
export var (
- scope *AST.Scope;
- types array.Array;
+ Scope *AST.Scope;
+ Types array.Array;
// internal types
- void_typ,
- bad_typ,
- nil_typ,
+ 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,
+ 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;
+ Byte_typ,
+ Uint_typ,
+ Int_typ,
+ Float_typ,
+ Uintptr_typ *AST.Type;
- true_obj,
- false_obj,
- iota_obj,
- nil_obj *AST.Object;
+ True_obj,
+ False_obj,
+ Iota_obj,
+ Nil_obj *AST.Object;
)
-func DeclObj(kind int, ident string, typ *AST.Type) *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
+ obj.Typ = typ;
+ if kind == AST.TYPE && typ.Obj == nil {
+ typ.Obj = obj; // set primary type object
}
- scope.Insert(obj);
+ Scope.Insert(obj);
return obj
}
-func DeclType(form int, ident string, size int) *AST.Type {
+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;
+ typ.Size = size;
+ return declObj(AST.TYPE, ident, typ).Typ;
}
-func Register(typ *AST.Type) *AST.Type {
- typ.ref = types.Len();
- types.Push(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);
+ 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);
+ 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));
+ 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));
+ 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);
+ 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);
+ 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();
}