Commit 2a58e7d7 authored by Robert Griesemer's avatar Robert Griesemer

more work on elastic tabs:

- new code enabled, but no comments printed yet (so the effect
  of the elastic tabs is not seen yet)

TBR=r
DELTA=200  (93 added, 69 deleted, 38 changed)
OCL=18951
CL=18951
parent 600ee088
...@@ -36,96 +36,117 @@ func PrintBlanks(n int) { ...@@ -36,96 +36,117 @@ func PrintBlanks(n int) {
// (http://nickgravgaard.com/elastictabstops/index.html) // (http://nickgravgaard.com/elastictabstops/index.html)
type Buffer struct { type Buffer struct {
segment string; // current line segment
lines AST.List; // a list of lines; and each line is a list of strings lines AST.List; // a list of lines; and each line is a list of strings
widths AST.List; }
func (b *Buffer) Line(i int) *AST.List {
return b.lines.at(i).(*AST.List);
}
func (b *Buffer) Tab() {
b.lines.at(b.lines.len() - 1).(*AST.List).Add(b.segment);
b.segment = "";
} }
func (b *Buffer) Newline() { func (b *Buffer) Newline() {
b.Tab(); // add last segment to current line
b.lines.Add(AST.NewList()); b.lines.Add(AST.NewList());
} }
func (b *Buffer) Print(s string) {
b.segment += s;
}
func (b *Buffer) Init() { func (b *Buffer) Init() {
b.lines.Init(); b.lines.Init();
b.widths.Init(); b.lines.Add(AST.NewList());
b.Newline();
} }
func (b *Buffer) ComputeWidths() { func (b *Buffer) PrintLines(line0, line1 int, widths *AST.List) {
// iterate through all columns j for i := line0; i < line1; i++ {
for j := 0; ; j++ { nsep := 0;
width := -1; // initial column width line := b.Line(i);
for j := 0; j < line.len(); j++ {
// iterate through all lines i s := line.at(j).(string);
for i := 0; i < b.lines.len(); i++ { PrintBlanks(nsep);
line := b.lines.at(i).(*AST.List); print(s);
if j < line.len() { if j < widths.len() {
// the j.th column exists in this line nsep = widths.at(j).(int) - len(s);
w := len(line.at(j).(string)); assert(nsep >= 0);
if w > width { if nsep < int(tabwith.IVal()) {
width = w; nsep = int(tabwith.IVal());
} }
} else {
nsep = 0;
} }
} }
println();
if width >= 0 {
assert(b.widths.len() == j);
b.widths.Add(width);
} else {
// no column j - we are done
return;
}
} }
} }
func (b *Buffer) Flush() { func (b *Buffer) Format(line0, line1 int, widths *AST.List) {
b.ComputeWidths(); i0, i1 := line0, line0;
column := widths.len();
// print the lines width := -1;
for i := 0; i < b.lines.len(); i++ { for i := line0; i < line1; i++ {
line := b.lines.at(i).(*AST.List); line := b.Line(i);
for j := 0; j < line.len(); j++ { if column < line.len() - 1 {
s := line.at(j).(string); if width < 0 {
d := b.widths.at(j).(int) - len(s); // column start
assert(d >= 0); i1 = i;
if d < int(tabwith.IVal()) { b.PrintLines(i0, i1, widths);
d = int(tabwith.IVal()); }
w := len(line.at(column).(string));
if w > width {
width = w;
}
} else {
if width >= 0 {
// column end
i0 = i;
widths.Add(width);
b.Format(i1, i0, widths);
widths.Pop();
width = -1;
} }
PrintBlanks(d); // +1 padding
print(s);
} }
println();
} }
b.PrintLines(i0, line1, widths);
b.lines.Clear();
b.widths.Clear();
b.Newline();
} }
func (b *Buffer) Indent(n int) { func (b *Buffer) Dump() {
line := b.lines.at(b.lines.len() - 1).(*AST.List); for i := 0; i < b.lines.len(); i++ {
for ; n > 0; n-- { line := b.Line(i);
line.Add(""); print("(", i, ") ");
for j := 0; j < line.len(); j++ {
print("[", line.at(j).(string), "]");
}
print("\n");
} }
print("\n");
} }
func (b *Buffer) Print(s string) { func (b *Buffer) Flush() {
i := b.lines.len() - 1; b.Tab(); // add last segment to current line
line := b.lines.at(i).(*AST.List); b.Format(0, b.lines.len(), AST.NewList());
j := line.len() - 1; b.lines.Clear();
if j < 0 { b.lines.Add(AST.NewList());
line.Add(s);
} else {
line.set(j, line.at(j).(string) + s);
}
} }
// ----------------------------------------------------------------------------
// Printer
export type Printer struct { export type Printer struct {
buf Buffer; buf Buffer;
...@@ -142,28 +163,42 @@ export type Printer struct { ...@@ -142,28 +163,42 @@ export type Printer struct {
} }
const NEW_CODE = false; func CountNewlinesAndTabs(s string) (int, int, string) {
nls, tabs := 0, 0;
for i := 0; i < len(s); i++ {
switch ch := s[i]; ch {
case '\n': nls++;
case '\t': tabs++;
case ' ':
default:
// non-whitespace char
assert(ch == '/');
return nls, tabs, s[i : len(s)];
}
}
return nls, tabs, "";
}
func (P *Printer) String(pos int, s string) { func (P *Printer) String(pos int, s string) {
if P.semi && P.level > 0 { // no semicolons at level 0 if P.semi && P.level > 0 { // no semicolons at level 0
if NEW_CODE { P.buf.Print(";");
P.buf.Print(";");
} else {
print(";");
}
} }
/* /*
for pos > P.cpos { for pos > P.cpos {
// we have a comment // we have a comment
c := P.clist.at(P.cindex).(*AST.Comment); comment := P.clist.at(P.cindex).(*AST.Comment);
if len(c.text) > 1 && c.text[1] == '/' { nls, tabs, text := CountNewlinesAndTabs(comment.text);
print(" " + c.text);
if nls == 0 && len(text) > 1 && text[1] == '/' {
P.buf.Tab();
P.buf.Print(text);
if P.newl <= 0 { if P.newl <= 0 {
P.newl = 1; // line comments must have a newline //P.newl = 1; // line comments must have a newline
} }
} else { } else {
print(c.text); P.buf.Print(text);
} }
P.cindex++; P.cindex++;
if P.cindex < P.clist.len() { if P.cindex < P.clist.len() {
...@@ -175,30 +210,19 @@ func (P *Printer) String(pos int, s string) { ...@@ -175,30 +210,19 @@ func (P *Printer) String(pos int, s string) {
*/ */
if P.newl > 0 { if P.newl > 0 {
if NEW_CODE { P.buf.Newline();
P.buf.Flush(); if P.newl > 1 {
} for i := P.newl; i > 1; i-- {
for i := P.newl; i > 0; i-- { //P.buf.Flush();
if NEW_CODE {
P.buf.Newline(); P.buf.Newline();
} else {
print("\n");
} }
} }
if NEW_CODE { for i := P.indent; i > 0; i-- {
P.buf.Indent(P.indent); P.buf.Tab();
} else {
for i := P.indent; i > 0; i-- {
print("\t");
}
} }
} }
if NEW_CODE { P.buf.Print(s);
P.buf.Print(s);
} else {
print(s);
}
P.semi, P.newl = false, 0; P.semi, P.newl = false, 0;
} }
...@@ -668,5 +692,5 @@ func (P *Printer) Program(p *AST.Program) { ...@@ -668,5 +692,5 @@ func (P *Printer) Program(p *AST.Program) {
} }
P.newl = 1; P.newl = 1;
P.String(0, ""); // flush P.buf.Flush(); // TODO should not access P.buf directly here
} }
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