Commit fcdcf33a authored by Robert Griesemer's avatar Robert Griesemer

- array-ify code, remove local implementation

R=r
OCL=19648
CL=19651
parent 9af3ee54
...@@ -4,7 +4,10 @@ ...@@ -4,7 +4,10 @@
package AST package AST
import Scanner "scanner" import (
"array";
Scanner "scanner";
)
type ( type (
...@@ -16,90 +19,6 @@ type ( ...@@ -16,90 +19,6 @@ type (
) )
// ----------------------------------------------------------------------------
// Lists
//
// If p is a list and p == nil, then p.len() == 0.
// Thus, empty lists can be represented by nil.
export type List struct {
a *[] Any;
}
func (p *List) Init() {
p.a = new([] Any, 10) [0 : 0];
}
func (p *List) len() int {
if p == nil { return 0; }
return len(p.a);
}
func (p *List) at(i int) Any {
return p.a[i];
}
func (p *List) last() Any {
return p.a[len(p.a) - 1];
}
func (p *List) set(i int, x Any) {
p.a[i] = x;
}
func (p *List) Add(x Any) {
a := p.a;
n := len(a);
if n == cap(a) {
b := new([] Any, 2*n);
for i := 0; i < n; i++ {
b[i] = a[i];
}
a = b;
}
a = a[0 : n + 1];
a[n] = x;
p.a = a;
}
func (p *List) Pop() Any {
a := p.a;
n := len(a);
var x Any;
if n > 0 {
x = a[n - 1];
a = a[0 : n - 1];
p.a = a;
} else {
panic("pop from empty list");
}
return x;
}
func (p *List) Clear() {
p.a = p.a[0 : 0];
}
export func NewList() *List {
p := new(List);
p.Init();
return p;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// All nodes have a source position and and token. // All nodes have a source position and and token.
...@@ -117,11 +36,11 @@ export type Expr struct { ...@@ -117,11 +36,11 @@ export type Expr struct {
// TODO find a more space efficient way to hold these // TODO find a more space efficient way to hold these
s string; // identifiers and literals s string; // identifiers and literals
t *Type; // type expressions, function literal types t *Type; // type expressions, function literal types
block *List; // stats for function literals block *array.Array; // stats for function literals
} }
func (x *Expr) len() int { func (x *Expr) Len() int {
if x == nil { if x == nil {
return 0; return 0;
} }
...@@ -169,14 +88,17 @@ export type Type struct { ...@@ -169,14 +88,17 @@ export type Type struct {
mode int; // channel mode mode int; // channel mode
key *Type; // receiver type, map key key *Type; // receiver type, map key
elt *Type; // array element, map or channel value, or pointer base type, result type elt *Type; // array element, map or channel value, or pointer base type, result type
list *List; // struct fields, interface methods, function parameters list *array.Array; // struct fields, interface methods, function parameters
} }
func (t *Type) nfields() int { func (t *Type) nfields() int {
if t.list == nil {
return 0;
}
nx, nt := 0, 0; nx, nt := 0, 0;
for i, n := 0, t.list.len(); i < n; i++ { for i, n := 0, t.list.Len(); i < n; i++ {
if t.list.at(i).(*Expr).tok == Scanner.TYPE { if t.list.At(i).(*Expr).tok == Scanner.TYPE {
nt++; nt++;
} else { } else {
nx++; nx++;
...@@ -214,7 +136,7 @@ export type Stat struct { ...@@ -214,7 +136,7 @@ export type Stat struct {
Node; Node;
init, post *Stat; init, post *Stat;
expr *Expr; expr *Expr;
block *List; block *array.Array;
decl *Decl; decl *Decl;
} }
...@@ -240,7 +162,7 @@ export type Decl struct { ...@@ -240,7 +162,7 @@ export type Decl struct {
val *Expr; val *Expr;
// list of *Decl for ()-style declarations // list of *Decl for ()-style declarations
// list of *Stat for func declarations (or nil for forward decl) // list of *Stat for func declarations (or nil for forward decl)
list *List; list *array.Array;
} }
...@@ -273,8 +195,8 @@ export func NewComment(pos, tok int, text string) *Comment { ...@@ -273,8 +195,8 @@ export func NewComment(pos, tok int, text string) *Comment {
export type Program struct { export type Program struct {
pos int; // tok is Scanner.PACKAGE pos int; // tok is Scanner.PACKAGE
ident *Expr; ident *Expr;
decls *List; decls *array.Array;
comments *List; comments *array.Array;
} }
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
package Compilation package Compilation
import "array"
import OS "os" import OS "os"
import Platform "platform" import Platform "platform"
import Scanner "scanner" import Scanner "scanner"
...@@ -61,7 +62,7 @@ func FileExists(name string) bool { ...@@ -61,7 +62,7 @@ func FileExists(name string) bool {
} }
func AddDeps(globalset *map [string] bool, wset *AST.List, src_file string, flags *Flags) { func AddDeps(globalset *map [string] bool, wset *array.Array, src_file string, flags *Flags) {
dummy, found := globalset[src_file]; dummy, found := globalset[src_file];
if !found { if !found {
globalset[src_file] = true; globalset[src_file] = true;
...@@ -71,13 +72,13 @@ func AddDeps(globalset *map [string] bool, wset *AST.List, src_file string, flag ...@@ -71,13 +72,13 @@ func AddDeps(globalset *map [string] bool, wset *AST.List, src_file string, flag
return; return;
} }
nimports := prog.decls.len(); nimports := prog.decls.Len();
if nimports > 0 { if nimports > 0 {
print(src_file, ".6:\t"); print(src_file, ".6:\t");
localset := new(map [string] bool); localset := new(map [string] bool);
for i := 0; i < nimports; i++ { for i := 0; i < nimports; i++ {
decl := prog.decls.at(i).(*AST.Decl); decl := prog.decls.At(i).(*AST.Decl);
assert(decl.tok == Scanner.IMPORT && decl.val.tok == Scanner.STRING); assert(decl.tok == Scanner.IMPORT && decl.val.tok == Scanner.STRING);
src := decl.val.s; src := decl.val.s;
src = src[1 : len(src) - 1]; // strip "'s src = src[1 : len(src) - 1]; // strip "'s
...@@ -87,7 +88,7 @@ func AddDeps(globalset *map [string] bool, wset *AST.List, src_file string, flag ...@@ -87,7 +88,7 @@ func AddDeps(globalset *map [string] bool, wset *AST.List, src_file string, flag
if !found { if !found {
localset[src] = true; localset[src] = true;
if FileExists(src + ".go") { if FileExists(src + ".go") {
wset.Add(src); wset.Push(src);
print(" ", src, ".6"); print(" ", src, ".6");
} else if } else if
FileExists(Platform.GOROOT + "/pkg/" + src + ".6") || FileExists(Platform.GOROOT + "/pkg/" + src + ".6") ||
...@@ -107,9 +108,9 @@ func AddDeps(globalset *map [string] bool, wset *AST.List, src_file string, flag ...@@ -107,9 +108,9 @@ func AddDeps(globalset *map [string] bool, wset *AST.List, src_file string, flag
export func ComputeDeps(src_file string, flags *Flags) { export func ComputeDeps(src_file string, flags *Flags) {
globalset := new(map [string] bool); globalset := new(map [string] bool);
wset := AST.NewList(); wset := array.New(0);
wset.Add(src_file); wset.Push(src_file);
for wset.len() > 0 { for wset.Len() > 0 {
AddDeps(globalset, wset, wset.Pop().(string), flags); AddDeps(globalset, wset, wset.Pop().(string), flags);
} }
} }
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
package Parser package Parser
import "array"
import Scanner "scanner" import Scanner "scanner"
import AST "ast" import AST "ast"
...@@ -16,7 +17,7 @@ export type Parser struct { ...@@ -16,7 +17,7 @@ export type Parser struct {
// Scanner // Scanner
scanner *Scanner.Scanner; scanner *Scanner.Scanner;
tokchan *<-chan *Scanner.Token; tokchan *<-chan *Scanner.Token;
comments *AST.List; comments *array.Array;
// Scanner.Token // Scanner.Token
pos int; // token source position pos int; // token source position
...@@ -85,7 +86,7 @@ func (P *Parser) Next() { ...@@ -85,7 +86,7 @@ func (P *Parser) Next() {
P.tok == Scanner.COMMENT_BB ; P.tok == Scanner.COMMENT_BB ;
P.Next0() P.Next0()
{ {
P.comments.Add(AST.NewComment(P.pos, P.tok, P.val)); P.comments.Push(AST.NewComment(P.pos, P.tok, P.val));
} }
} }
...@@ -98,7 +99,7 @@ func (P *Parser) Open(verbose, sixg, deps bool, scanner *Scanner.Scanner, tokcha ...@@ -98,7 +99,7 @@ func (P *Parser) Open(verbose, sixg, deps bool, scanner *Scanner.Scanner, tokcha
P.scanner = scanner; P.scanner = scanner;
P.tokchan = tokchan; P.tokchan = tokchan;
P.comments = AST.NewList(); P.comments = array.New(0);
P.Next(); P.Next();
P.expr_lev = 0; P.expr_lev = 0;
...@@ -327,13 +328,13 @@ func (P *Parser) ParseVarDecl(expect_ident bool) *AST.Type { ...@@ -327,13 +328,13 @@ func (P *Parser) ParseVarDecl(expect_ident bool) *AST.Type {
} }
func (P *Parser) ParseVarDeclList(list *AST.List, ellipsis_ok bool) { func (P *Parser) ParseVarDeclList(list *array.Array, ellipsis_ok bool) {
P.Trace("VarDeclList"); P.Trace("VarDeclList");
// parse a list of types // parse a list of types
i0 := list.len(); i0 := list.Len();
for { for {
list.Add(P.ParseVarDecl(ellipsis_ok /* param list */ && i0 > 0)); list.Push(P.ParseVarDecl(ellipsis_ok /* param list */ && i0 > 0));
if P.tok == Scanner.COMMA { if P.tok == Scanner.COMMA {
P.Next(); P.Next();
} else { } else {
...@@ -357,24 +358,24 @@ func (P *Parser) ParseVarDeclList(list *AST.List, ellipsis_ok bool) { ...@@ -357,24 +358,24 @@ func (P *Parser) ParseVarDeclList(list *AST.List, ellipsis_ok bool) {
if typ != nil { if typ != nil {
// all list entries must be identifiers // all list entries must be identifiers
// 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.tok == Scanner.IDENT && 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);
P.Error(t.pos, "identifier expected"); P.Error(t.pos, "identifier expected");
} }
} }
// add type // add type
list.Add(AST.NewTypeExpr(typ)); list.Push(AST.NewTypeExpr(typ));
} else { } else {
// all list entries are types // all list entries are types
// convert all type entries into type expressions // convert all type entries into type expressions
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);
list.set(i, AST.NewTypeExpr(t)); list.Set(i, AST.NewTypeExpr(t));
} }
} }
...@@ -382,10 +383,10 @@ func (P *Parser) ParseVarDeclList(list *AST.List, ellipsis_ok bool) { ...@@ -382,10 +383,10 @@ func (P *Parser) ParseVarDeclList(list *AST.List, ellipsis_ok bool) {
} }
func (P *Parser) ParseParameterList(ellipsis_ok bool) *AST.List { func (P *Parser) ParseParameterList(ellipsis_ok bool) *array.Array {
P.Trace("ParameterList"); P.Trace("ParameterList");
list := AST.NewList(); list := array.New(0);
P.ParseVarDeclList(list, ellipsis_ok); P.ParseVarDeclList(list, ellipsis_ok);
for P.tok == Scanner.COMMA { for P.tok == Scanner.COMMA {
P.Next(); P.Next();
...@@ -438,8 +439,8 @@ func (P *Parser) ParseResult() *AST.Type { ...@@ -438,8 +439,8 @@ func (P *Parser) ParseResult() *AST.Type {
typ := P.TryType(); typ := P.TryType();
if typ != nil { if typ != nil {
t = AST.NewType(P.pos, Scanner.STRUCT); t = AST.NewType(P.pos, Scanner.STRUCT);
t.list = AST.NewList(); t.list = array.New(0);
t.list.Add(AST.NewTypeExpr(typ)); t.list.Push(AST.NewTypeExpr(typ));
} }
} }
...@@ -466,17 +467,17 @@ func (P *Parser) ParseFunctionType() *AST.Type { ...@@ -466,17 +467,17 @@ func (P *Parser) ParseFunctionType() *AST.Type {
} }
func (P *Parser) ParseMethodSpec(list *AST.List) { func (P *Parser) ParseMethodSpec(list *array.Array) {
P.Trace("MethodDecl"); P.Trace("MethodDecl");
list.Add(P.ParseIdentList()); list.Push(P.ParseIdentList());
t := AST.BadType; t := AST.BadType;
if P.sixg { if P.sixg {
t = P.ParseType(); t = P.ParseType();
} else { } else {
t = P.ParseFunctionType(); t = P.ParseFunctionType();
} }
list.Add(AST.NewTypeExpr(t)); list.Push(AST.NewTypeExpr(t));
P.Ecart(); P.Ecart();
} }
...@@ -489,7 +490,7 @@ func (P *Parser) ParseInterfaceType() *AST.Type { ...@@ -489,7 +490,7 @@ func (P *Parser) ParseInterfaceType() *AST.Type {
P.Expect(Scanner.INTERFACE); P.Expect(Scanner.INTERFACE);
if P.tok == Scanner.LBRACE { if P.tok == Scanner.LBRACE {
P.Next(); P.Next();
t.list = AST.NewList(); t.list = array.New(0);
for P.tok == Scanner.IDENT { for P.tok == Scanner.IDENT {
P.ParseMethodSpec(t.list); P.ParseMethodSpec(t.list);
if P.tok != Scanner.RBRACE { if P.tok != Scanner.RBRACE {
...@@ -528,12 +529,12 @@ func (P *Parser) ParseStructType() *AST.Type { ...@@ -528,12 +529,12 @@ func (P *Parser) ParseStructType() *AST.Type {
P.Expect(Scanner.STRUCT); P.Expect(Scanner.STRUCT);
if P.tok == Scanner.LBRACE { if P.tok == Scanner.LBRACE {
P.Next(); P.Next();
t.list = AST.NewList(); t.list = array.New(0);
for P.tok != Scanner.RBRACE && P.tok != Scanner.EOF { for P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
P.ParseVarDeclList(t.list, false); P.ParseVarDeclList(t.list, false);
if P.tok == Scanner.STRING { if P.tok == Scanner.STRING {
// ParseOperand takes care of string concatenation // ParseOperand takes care of string concatenation
t.list.Add(P.ParseOperand()); t.list.Push(P.ParseOperand());
} }
if P.tok == Scanner.SEMICOLON { if P.tok == Scanner.SEMICOLON {
P.Next(); P.Next();
...@@ -586,15 +587,15 @@ func (P *Parser) TryType() *AST.Type { ...@@ -586,15 +587,15 @@ func (P *Parser) TryType() *AST.Type {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Blocks // Blocks
func (P *Parser) ParseStatementList() *AST.List { func (P *Parser) ParseStatementList() *array.Array {
P.Trace("StatementList"); P.Trace("StatementList");
list := AST.NewList(); list := array.New(0);
for P.tok != Scanner.CASE && P.tok != Scanner.DEFAULT && P.tok != Scanner.RBRACE && P.tok != Scanner.EOF { for P.tok != Scanner.CASE && P.tok != Scanner.DEFAULT && P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
s := P.ParseStatement(); s := P.ParseStatement();
if s != nil { if s != nil {
// not the empty statement // not the empty statement
list.Add(s); list.Push(s);
} }
if P.tok == Scanner.SEMICOLON { if P.tok == Scanner.SEMICOLON {
P.Next(); P.Next();
...@@ -615,7 +616,7 @@ func (P *Parser) ParseStatementList() *AST.List { ...@@ -615,7 +616,7 @@ func (P *Parser) ParseStatementList() *AST.List {
} }
func (P *Parser) ParseBlock() *AST.List { func (P *Parser) ParseBlock() *array.Array {
P.Trace("Block"); P.Trace("Block");
P.Expect(Scanner.LBRACE); P.Expect(Scanner.LBRACE);
...@@ -982,7 +983,7 @@ func (P *Parser) ParseSimpleStat() *AST.Stat { ...@@ -982,7 +983,7 @@ func (P *Parser) ParseSimpleStat() *AST.Stat {
// label declaration // label declaration
s = AST.NewStat(P.pos, Scanner.COLON); s = AST.NewStat(P.pos, Scanner.COLON);
s.expr = x; s.expr = x;
if x.len() != 1 { if x.Len() != 1 {
P.Error(x.pos, "illegal label declaration"); P.Error(x.pos, "illegal label declaration");
} }
P.Next(); // consume ":" P.Next(); // consume ":"
...@@ -997,7 +998,7 @@ func (P *Parser) ParseSimpleStat() *AST.Stat { ...@@ -997,7 +998,7 @@ func (P *Parser) ParseSimpleStat() *AST.Stat {
pos, tok := P.pos, P.tok; pos, tok := P.pos, P.tok;
P.Next(); P.Next();
y := P.ParseExpressionList(); y := P.ParseExpressionList();
if xl, yl := x.len(), y.len(); xl > 1 && yl > 1 && xl != yl { 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 = AST.NewStat(x.pos, Scanner.EXPRSTAT);
...@@ -1013,7 +1014,7 @@ func (P *Parser) ParseSimpleStat() *AST.Stat { ...@@ -1013,7 +1014,7 @@ func (P *Parser) ParseSimpleStat() *AST.Stat {
} }
s = AST.NewStat(pos, tok); s = AST.NewStat(pos, tok);
s.expr = x; s.expr = x;
if x.len() != 1 { if x.Len() != 1 {
P.Error(x.pos, "only one expression allowed"); P.Error(x.pos, "only one expression allowed");
} }
} }
...@@ -1113,8 +1114,8 @@ func (P *Parser) ParseIfStat() *AST.Stat { ...@@ -1113,8 +1114,8 @@ func (P *Parser) ParseIfStat() *AST.Stat {
if s1.tok != Scanner.LBRACE { if s1.tok != Scanner.LBRACE {
// wrap in a block if we don't have one // wrap in a block if we don't have one
b := AST.NewStat(P.pos, Scanner.LBRACE); b := AST.NewStat(P.pos, Scanner.LBRACE);
b.block = AST.NewList(); b.block = array.New(0);
b.block.Add(s1); b.block.Push(s1);
s1 = b; s1 = b;
} }
s.post = s1; s.post = s1;
...@@ -1178,10 +1179,10 @@ func (P *Parser) ParseSwitchStat() *AST.Stat { ...@@ -1178,10 +1179,10 @@ func (P *Parser) ParseSwitchStat() *AST.Stat {
P.Trace("SwitchStat"); P.Trace("SwitchStat");
s := P.ParseControlClause(Scanner.SWITCH); s := P.ParseControlClause(Scanner.SWITCH);
s.block = AST.NewList(); s.block = array.New(0);
P.Expect(Scanner.LBRACE); P.Expect(Scanner.LBRACE);
for P.tok != Scanner.RBRACE && P.tok != Scanner.EOF { for P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
s.block.Add(P.ParseCaseClause()); s.block.Push(P.ParseCaseClause());
} }
P.Expect(Scanner.RBRACE); P.Expect(Scanner.RBRACE);
P.opt_semi = true; P.opt_semi = true;
...@@ -1236,11 +1237,11 @@ func (P *Parser) ParseSelectStat() *AST.Stat { ...@@ -1236,11 +1237,11 @@ func (P *Parser) ParseSelectStat() *AST.Stat {
P.Trace("SelectStat"); P.Trace("SelectStat");
s := AST.NewStat(P.pos, Scanner.SELECT); s := AST.NewStat(P.pos, Scanner.SELECT);
s.block = AST.NewList(); s.block = array.New(0);
P.Expect(Scanner.SELECT); P.Expect(Scanner.SELECT);
P.Expect(Scanner.LBRACE); P.Expect(Scanner.LBRACE);
for P.tok != Scanner.RBRACE && P.tok != Scanner.EOF { for P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
s.block.Add(P.ParseCommClause()); s.block.Push(P.ParseCommClause());
} }
P.Expect(Scanner.RBRACE); P.Expect(Scanner.RBRACE);
P.opt_semi = true; P.opt_semi = true;
...@@ -1414,9 +1415,9 @@ func (P *Parser) ParseDecl(exported bool, keyword int) *AST.Decl { ...@@ -1414,9 +1415,9 @@ func (P *Parser) ParseDecl(exported bool, keyword int) *AST.Decl {
if P.tok == Scanner.LPAREN { if P.tok == Scanner.LPAREN {
P.Next(); P.Next();
d = AST.NewDecl(P.pos, keyword, exported); d = AST.NewDecl(P.pos, keyword, exported);
d.list = AST.NewList(); d.list = array.New(0);
for P.tok != Scanner.RPAREN && P.tok != Scanner.EOF { for P.tok != Scanner.RPAREN && P.tok != Scanner.EOF {
d.list.Add(P.ParseSpec(exported, keyword)); d.list.Push(P.ParseSpec(exported, keyword));
if P.tok == Scanner.SEMICOLON { if P.tok == Scanner.SEMICOLON {
P.Next(); P.Next();
} else { } else {
...@@ -1539,15 +1540,15 @@ func (P *Parser) ParseProgram() *AST.Program { ...@@ -1539,15 +1540,15 @@ func (P *Parser) ParseProgram() *AST.Program {
P.Expect(Scanner.PACKAGE); P.Expect(Scanner.PACKAGE);
p.ident = P.ParseIdent(); p.ident = P.ParseIdent();
p.decls = AST.NewList(); p.decls = array.New(0);
for P.tok == Scanner.IMPORT { for P.tok == Scanner.IMPORT {
p.decls.Add(P.ParseDecl(false, Scanner.IMPORT)); p.decls.Push(P.ParseDecl(false, Scanner.IMPORT));
P.OptSemicolon(); P.OptSemicolon();
} }
if !P.deps { if !P.deps {
for P.tok != Scanner.EOF { for P.tok != Scanner.EOF {
p.decls.Add(P.ParseDeclaration()); p.decls.Push(P.ParseDeclaration());
P.OptSemicolon(); P.OptSemicolon();
} }
} }
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
package Printer package Printer
import "array"
import Strings "strings" import Strings "strings"
import Scanner "scanner" import Scanner "scanner"
import AST "ast" import AST "ast"
...@@ -44,7 +45,7 @@ export type Printer struct { ...@@ -44,7 +45,7 @@ export type Printer struct {
newl int; // pending "\n"'s newl int; // pending "\n"'s
// comments // comments
clist *AST.List; clist *array.Array;
cindex int; cindex int;
cpos int; cpos int;
} }
...@@ -71,7 +72,7 @@ func (P *Printer) String(pos int, s string) { ...@@ -71,7 +72,7 @@ func (P *Printer) String(pos int, s string) {
//print("cc", P.cpos, "\n"); //print("cc", P.cpos, "\n");
// we have a comment that comes before s // we have a comment that comes before s
comment := P.clist.at(P.cindex).(*AST.Comment); comment := P.clist.At(P.cindex).(*AST.Comment);
text := comment.text; text := comment.text;
assert(len(text) >= 3); // classification char + "//" or "/*" assert(len(text) >= 3); // classification char + "//" or "/*"
...@@ -115,8 +116,8 @@ func (P *Printer) String(pos int, s string) { ...@@ -115,8 +116,8 @@ func (P *Printer) String(pos int, s string) {
} }
P.cindex++; P.cindex++;
if P.cindex < P.clist.len() { if P.cindex < P.clist.Len() {
P.cpos = P.clist.at(P.cindex).(*AST.Comment).pos; P.cpos = P.clist.At(P.cindex).(*AST.Comment).pos;
} else { } else {
P.cpos = 1000000000; // infinite P.cpos = 1000000000; // infinite
} }
...@@ -191,43 +192,47 @@ func (P *Printer) Error(pos int, tok int, msg string) { ...@@ -191,43 +192,47 @@ func (P *Printer) Error(pos int, tok int, msg string) {
func (P *Printer) Type(t *AST.Type) func (P *Printer) Type(t *AST.Type)
func (P *Printer) Expr(x *AST.Expr) func (P *Printer) Expr(x *AST.Expr)
func (P *Printer) Parameters(pos int, list *AST.List) { func (P *Printer) Parameters(pos int, list *array.Array) {
P.String(pos, "("); P.String(pos, "(");
var prev int; if list != nil {
for i, n := 0, list.len(); i < n; i++ { var prev int;
x := list.at(i).(*AST.Expr); for i, n := 0, list.Len(); i < n; i++ {
if i > 0 { x := list.At(i).(*AST.Expr);
if prev == x.tok || prev == Scanner.TYPE { if i > 0 {
P.String(0, ", "); if prev == x.tok || prev == Scanner.TYPE {
} else { P.String(0, ", ");
P.Blank(); } else {
P.Blank();
}
} }
P.Expr(x);
prev = x.tok;
} }
P.Expr(x);
prev = x.tok;
} }
P.String(0, ")"); P.String(0, ")");
} }
func (P *Printer) Fields(list *AST.List) { func (P *Printer) Fields(list *array.Array) {
P.OpenScope("{"); P.OpenScope("{");
var prev int; if list != nil {
for i, n := 0, list.len(); i < n; i++ { var prev int;
x := list.at(i).(*AST.Expr); for i, n := 0, list.Len(); i < n; i++ {
if i > 0 { x := list.At(i).(*AST.Expr);
if prev == Scanner.TYPE && x.tok != Scanner.STRING || prev == Scanner.STRING { if i > 0 {
P.semi, P.newl = true, 1; if prev == Scanner.TYPE && x.tok != Scanner.STRING || prev == Scanner.STRING {
} else if prev == x.tok { P.semi, P.newl = true, 1;
P.String(0, ", "); } else if prev == x.tok {
} else { P.String(0, ", ");
P.Tab(); } else {
P.Tab();
}
} }
P.Expr(x);
prev = x.tok;
} }
P.Expr(x); P.newl = 1;
prev = x.tok;
} }
P.newl = 1;
P.CloseScope("}"); P.CloseScope("}");
} }
...@@ -291,7 +296,7 @@ func (P *Printer) Type(t *AST.Type) { ...@@ -291,7 +296,7 @@ func (P *Printer) Type(t *AST.Type) {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Expressions // Expressions
func (P *Printer) Block(list *AST.List, indent bool); func (P *Printer) Block(list *array.Array, indent bool);
func (P *Printer) Expr1(x *AST.Expr, prec1 int) { func (P *Printer) Expr1(x *AST.Expr, prec1 int) {
if x == nil { if x == nil {
...@@ -391,15 +396,17 @@ func (P *Printer) Expr(x *AST.Expr) { ...@@ -391,15 +396,17 @@ func (P *Printer) Expr(x *AST.Expr) {
func (P *Printer) Stat(s *AST.Stat) func (P *Printer) Stat(s *AST.Stat)
func (P *Printer) StatementList(list *AST.List) { func (P *Printer) StatementList(list *array.Array) {
for i, n := 0, list.len(); i < n; i++ { if list != nil {
P.Stat(list.at(i).(*AST.Stat)); for i, n := 0, list.Len(); i < n; i++ {
P.newl = 1; P.Stat(list.At(i).(*AST.Stat));
P.newl = 1;
}
} }
} }
func (P *Printer) Block(list *AST.List, indent bool) { func (P *Printer) Block(list *array.Array, indent bool) {
P.OpenScope("{"); P.OpenScope("{");
if !indent { if !indent {
P.indent--; P.indent--;
...@@ -536,8 +543,8 @@ func (P *Printer) Declaration(d *AST.Decl, parenthesized bool) { ...@@ -536,8 +543,8 @@ func (P *Printer) Declaration(d *AST.Decl, parenthesized bool) {
if d.tok != Scanner.FUNC && d.list != nil { if d.tok != Scanner.FUNC && d.list != nil {
P.OpenScope("("); P.OpenScope("(");
for i := 0; i < d.list.len(); i++ { for i := 0; i < d.list.Len(); i++ {
P.Declaration(d.list.at(i).(*AST.Decl), true); P.Declaration(d.list.At(i).(*AST.Decl), true);
P.semi, P.newl = true, 1; P.semi, P.newl = true, 1;
} }
P.CloseScope(")"); P.CloseScope(")");
...@@ -601,8 +608,8 @@ func (P *Printer) Program(p *AST.Program) { ...@@ -601,8 +608,8 @@ func (P *Printer) Program(p *AST.Program) {
P.clist = p.comments; P.clist = p.comments;
P.cindex = 0; P.cindex = 0;
if p.comments.len() > 0 { if p.comments.Len() > 0 {
P.cpos = p.comments.at(0).(*AST.Comment).pos; P.cpos = p.comments.At(0).(*AST.Comment).pos;
} else { } else {
P.cpos = 1000000000; // infinite P.cpos = 1000000000; // infinite
} }
...@@ -611,8 +618,8 @@ func (P *Printer) Program(p *AST.Program) { ...@@ -611,8 +618,8 @@ func (P *Printer) Program(p *AST.Program) {
P.String(p.pos, "package "); P.String(p.pos, "package ");
P.Expr(p.ident); P.Expr(p.ident);
P.newl = 2; P.newl = 2;
for i := 0; i < p.decls.len(); i++ { for i := 0; i < p.decls.Len(); i++ {
P.Declaration(p.decls.at(i), false); P.Declaration(p.decls.At(i), false);
} }
P.newl = 2; // TODO we should be able to do this with 1 instead of 2 P.newl = 2; // TODO we should be able to do this with 1 instead of 2
// but we are loosing the last buffer flush in that case // but we are loosing the last buffer flush in that case
......
...@@ -5,14 +5,15 @@ ...@@ -5,14 +5,15 @@
package tabwriter package tabwriter
import ( import (
OS "os"; "os";
IO "io"; "io";
Vector "vector"; "array";
) )
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// ByteArray // ByteArray
// TODO move this into std lib eventually
type ByteArray struct { type ByteArray struct {
a *[]byte; a *[]byte;
...@@ -75,7 +76,7 @@ func (b *ByteArray) Append(s *[]byte) { ...@@ -75,7 +76,7 @@ func (b *ByteArray) Append(s *[]byte) {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Implemententation of flexible tab stops. // Implementation of flexible tab stops.
// TabWriter is a representation for a list of lines consisting of // TabWriter is a representation for a list of lines consisting of
// cells. A new cell is added for each Tab() call, and a new line // cells. A new cell is added for each Tab() call, and a new line
...@@ -87,42 +88,42 @@ func (b *ByteArray) Append(s *[]byte) { ...@@ -87,42 +88,42 @@ func (b *ByteArray) Append(s *[]byte) {
export type TabWriter struct { export type TabWriter struct {
// configuration // configuration
writer IO.Write; writer io.Write;
usetabs bool; usetabs bool;
tabwidth int; tabwidth int;
// current state // current state
buf ByteArray; // the collected text w/o tabs and newlines buf ByteArray; // the collected text w/o tabs and newlines
width int; // width of last incomplete cell width int; // width of last incomplete cell
lines Vector.Vector; // list of lines; each line is a list of cell widths lines array.Array; // list of lines; each line is a list of cell widths
widths Vector.Vector; // list of column widths - (re-)used during formatting widths array.IntArray; // list of column widths - (re-)used during formatting
} }
func (b *TabWriter) AddLine() { func (b *TabWriter) AddLine() {
b.lines.Append(Vector.New()); b.lines.Push(array.NewIntArray(0));
} }
func (b *TabWriter) Init(writer IO.Write, usetabs bool, tabwidth int) { func (b *TabWriter) Init(writer io.Write, usetabs bool, tabwidth int) {
b.writer = writer; b.writer = writer;
b.usetabs = usetabs; b.usetabs = usetabs;
b.tabwidth = tabwidth; b.tabwidth = tabwidth;
b.buf.Init(1024); b.buf.Init(1024);
b.lines.Init(); b.lines.Init(0);
b.widths.Init(); b.widths.Init(0);
b.AddLine(); // the very first line b.AddLine(); // the very first line
} }
func (b *TabWriter) Line(i int) *Vector.Vector { func (b *TabWriter) Line(i int) *array.IntArray {
return b.lines.At(i).(*Vector.Vector); return b.lines.At(i).(*array.IntArray);
} }
func (b *TabWriter) LastLine() *Vector.Vector { func (b *TabWriter) LastLine() *array.IntArray {
return b.lines.At(b.lines.Len() - 1).(*Vector.Vector); return b.lines.At(b.lines.Len() - 1).(*array.IntArray);
} }
...@@ -133,7 +134,7 @@ func (b *TabWriter) Dump() { ...@@ -133,7 +134,7 @@ func (b *TabWriter) Dump() {
line := b.Line(i); line := b.Line(i);
print("(", i, ") "); print("(", i, ") ");
for j := 0; j < line.Len(); j++ { for j := 0; j < line.Len(); j++ {
w := line.At(j).(int); w := line.At(j);
print("[", string(b.buf.a[pos : pos + w]), "]"); print("[", string(b.buf.a[pos : pos + w]), "]");
pos += w; pos += w;
} }
...@@ -177,14 +178,14 @@ func (b *TabWriter) PrintLines(pos int, line0, line1 int) int { ...@@ -177,14 +178,14 @@ func (b *TabWriter) PrintLines(pos int, line0, line1 int) int {
for i := line0; i < line1; i++ { for i := line0; i < line1; i++ {
line := b.Line(i); line := b.Line(i);
for j := 0; j < line.Len(); j++ { for j := 0; j < line.Len(); j++ {
w := line.At(j).(int); w := line.At(j);
m, err := b.writer.Write(b.buf.a[pos : pos + w]); m, err := b.writer.Write(b.buf.a[pos : pos + w]);
if m != w { if m != w {
panic(); panic();
} }
pos += w; pos += w;
if j < b.widths.Len() { if j < b.widths.Len() {
b.Padding(w, b.widths.At(j).(int)); b.Padding(w, b.widths.At(j));
} }
} }
m, err := b.writer.Write(Newline); m, err := b.writer.Write(Newline);
...@@ -215,7 +216,7 @@ func (b *TabWriter) Format(pos int, line0, line1 int) int { ...@@ -215,7 +216,7 @@ func (b *TabWriter) Format(pos int, line0, line1 int) int {
if column < line.Len() - 1 { if column < line.Len() - 1 {
// cell exists in this column // cell exists in this column
// update width // update width
w := line.At(column).(int) + 1; // 1 = minimum space between cells w := line.At(column) + 1; // 1 = minimum space between cells
if w > width { if w > width {
width = w; width = w;
} }
...@@ -232,9 +233,9 @@ func (b *TabWriter) Format(pos int, line0, line1 int) int { ...@@ -232,9 +233,9 @@ func (b *TabWriter) Format(pos int, line0, line1 int) int {
// format and print all columns to the right of this column // format and print all columns to the right of this column
// (we know the widths of this column and all columns to the left) // (we know the widths of this column and all columns to the left)
b.widths.Append(width); b.widths.Push(width);
pos = b.Format(pos, last, this); pos = b.Format(pos, last, this);
b.widths.Remove(b.widths.Len() - 1); b.widths.Pop();
last = this; last = this;
} }
} }
...@@ -250,7 +251,7 @@ func (b *TabWriter) EmptyLine() bool { ...@@ -250,7 +251,7 @@ func (b *TabWriter) EmptyLine() bool {
func (b *TabWriter) Tab() { func (b *TabWriter) Tab() {
b.LastLine().Append(b.width); b.LastLine().Push(b.width);
b.width = 0; b.width = 0;
} }
...@@ -273,14 +274,14 @@ func (b *TabWriter) Newline() { ...@@ -273,14 +274,14 @@ func (b *TabWriter) Newline() {
// reset TabWriter // reset TabWriter
b.width = 0; b.width = 0;
b.buf.Clear(); b.buf.Clear();
b.lines.Reset(); b.lines.Init(0);
} }
b.AddLine(); b.AddLine();
} }
func (b *TabWriter) Write(buf *[]byte) (i int, err *OS.Error) { func (b *TabWriter) Write(buf *[]byte) (i int, err *os.Error) {
i0, n := 0, len(buf); i0, n := 0, len(buf);
for i = 0; i < n; i++ { for i = 0; i < n; i++ {
switch buf[i] { switch buf[i] {
...@@ -302,7 +303,7 @@ func (b *TabWriter) Write(buf *[]byte) (i int, err *OS.Error) { ...@@ -302,7 +303,7 @@ func (b *TabWriter) Write(buf *[]byte) (i int, err *OS.Error) {
} }
export func MakeTabWriter(writer IO.Write, usetabs bool, tabwidth int) *TabWriter { export func MakeTabWriter(writer io.Write, usetabs bool, tabwidth int) *TabWriter {
b := new(TabWriter); b := new(TabWriter);
b.Init(writer, usetabs, tabwidth); b.Init(writer, usetabs, tabwidth);
return b; return b;
......
...@@ -5,28 +5,28 @@ ...@@ -5,28 +5,28 @@
package main package main
import ( import (
OS "os"; "os";
IO "io"; "io";
Flag "flag"; "flag";
Fmt "fmt"; "fmt";
TabWriter "tabwriter"; "tabwriter";
) )
var ( var (
usetabs = Flag.Bool("usetabs", false, nil, "align with tabs instead of blanks"); usetabs = flag.Bool("usetabs", false, nil, "align with tabs instead of blanks");
tabwidth = Flag.Int("tabwidth", 4, nil, "tab width"); tabwidth = flag.Int("tabwidth", 4, nil, "tab width");
) )
func Error(fmt string, params ...) { func Error(format string, params ...) {
Fmt.printf(fmt, params); fmt.printf(format, params);
sys.exit(1); sys.exit(1);
} }
func Untab(name string, src *OS.FD, dst *TabWriter.TabWriter) { func Untab(name string, src *os.FD, dst *tabwriter.TabWriter) {
n, err := IO.Copyn(src, dst, 2e9 /* inf */); // TODO use Copy n, err := io.Copy(src, dst);
if err != nil { if err != nil {
Error("error while processing %s (%v)", name, err); Error("error while processing %s (%v)", name, err);
} }
...@@ -35,12 +35,12 @@ func Untab(name string, src *OS.FD, dst *TabWriter.TabWriter) { ...@@ -35,12 +35,12 @@ func Untab(name string, src *OS.FD, dst *TabWriter.TabWriter) {
func main() { func main() {
Flag.Parse(); flag.Parse();
dst := TabWriter.MakeTabWriter(OS.Stdout, usetabs.BVal(), int(tabwidth.IVal())); dst := tabwriter.MakeTabWriter(os.Stdout, usetabs.BVal(), int(tabwidth.IVal()));
if Flag.NArg() > 0 { if flag.NArg() > 0 {
for i := 0; i < Flag.NArg(); i++ { for i := 0; i < flag.NArg(); i++ {
name := Flag.Arg(i); name := flag.Arg(i);
src, err := OS.Open(name, OS.O_RDONLY, 0); src, err := os.Open(name, os.O_RDONLY, 0);
if err != nil { if err != nil {
Error("could not open %s (%v)\n", name, err); Error("could not open %s (%v)\n", name, err);
} }
...@@ -49,6 +49,6 @@ func main() { ...@@ -49,6 +49,6 @@ func main() {
} }
} else { } else {
// no files => use stdin // no files => use stdin
Untab("/dev/stdin", OS.Stdin, dst); Untab("/dev/stdin", os.Stdin, dst);
} }
} }
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