Commit 3c2f0ae1 authored by Robert Griesemer's avatar Robert Griesemer

* pretty printing snapshot: towards printing comments nicely

- implemented elastic tabstops algorithm, now correct and documented
- first cut at printing comments (use -comments flag, disabled for now)
- struct field types are now aligned (using elastic tab stops)
- needs more fine-tuning

* fixed a bug in test script
* added quick smoke test to makefile and invoke it in run.bash
  instead of the full test

R=r
OCL=19220
CL=19220
parent e2621b80
...@@ -32,7 +32,7 @@ time make ...@@ -32,7 +32,7 @@ time make
(xcd ../usr/gri/pretty (xcd ../usr/gri/pretty
make clean make clean
time make time make
make test make smoketest
) || exit $? ) || exit $?
(xcd ../test (xcd ../test
......
...@@ -11,6 +11,9 @@ pretty: pretty.6 ...@@ -11,6 +11,9 @@ pretty: pretty.6
test: pretty test: pretty
./test.sh ./test.sh
smoketest: pretty
./test.sh parser.go
install: pretty install: pretty
cp pretty $(HOME)/bin/pretty cp pretty $(HOME)/bin/pretty
......
...@@ -43,6 +43,11 @@ func (p *List) at(i int) Any { ...@@ -43,6 +43,11 @@ func (p *List) at(i int) Any {
} }
func (p *List) last() Any {
return p.a[len(p.a) - 1];
}
func (p *List) set(i int, x Any) { func (p *List) set(i int, x Any) {
p.a[i] = x; p.a[i] = x;
} }
......
...@@ -77,13 +77,8 @@ func (P *Parser) Next0() { ...@@ -77,13 +77,8 @@ func (P *Parser) Next0() {
func (P *Parser) Next() { func (P *Parser) Next() {
P.Next0();
if P.tok == Scanner.COMMENT {
pos, s := P.pos, P.val;
for P.Next0(); P.tok == Scanner.COMMENT; P.Next0() { for P.Next0(); P.tok == Scanner.COMMENT; P.Next0() {
s += P.val; P.comments.Add(AST.NewComment(P.pos, P.val));
}
P.comments.Add(AST.NewComment(pos, s));
} }
} }
......
This diff is collapsed.
...@@ -518,22 +518,29 @@ func (S *Scanner) Expect(ch int) { ...@@ -518,22 +518,29 @@ func (S *Scanner) Expect(ch int) {
} }
func (S *Scanner) SkipWhitespace() { func (S *Scanner) SkipWhitespace() int {
for S.ch == ' ' || S.ch == '\r' { pos := -1; // no new line position yet
S.Next();
if S.chpos == 0 {
// file beginning is always start of a new line
pos = 0;
} }
}
for {
switch S.ch {
case '\t', '\r', ' ': // nothing to do
case '\n': pos = S.pos; // remember start of new line
default: goto exit;
}
S.Next();
}
func (S *Scanner) ScanWhitespace() string { exit:
// first char ('\n' or '\t', 1 byte) already consumed return pos;
pos := S.chpos - 1;
S.SkipWhitespace();
return S.src[pos : S.chpos];
} }
func (S *Scanner) ScanComment() string { func (S *Scanner) ScanComment(nlpos int) string {
// first '/' already consumed // first '/' already consumed
pos := S.chpos - 1; pos := S.chpos - 1;
...@@ -543,6 +550,9 @@ func (S *Scanner) ScanComment() string { ...@@ -543,6 +550,9 @@ func (S *Scanner) ScanComment() string {
for S.ch >= 0 { for S.ch >= 0 {
S.Next(); S.Next();
if S.ch == '\n' { if S.ch == '\n' {
// '\n' terminates comment but we do not include
// it in the comment (otherwise we cannot see the
// start of a newline in SkipWhitespace()).
goto exit; goto exit;
} }
} }
...@@ -554,6 +564,7 @@ func (S *Scanner) ScanComment() string { ...@@ -554,6 +564,7 @@ func (S *Scanner) ScanComment() string {
ch := S.ch; ch := S.ch;
S.Next(); S.Next();
if ch == '*' && S.ch == '/' { if ch == '*' && S.ch == '/' {
S.Next();
goto exit; goto exit;
} }
} }
...@@ -562,7 +573,6 @@ func (S *Scanner) ScanComment() string { ...@@ -562,7 +573,6 @@ func (S *Scanner) ScanComment() string {
S.Error(pos, "comment not terminated"); S.Error(pos, "comment not terminated");
exit: exit:
S.Next();
comment := S.src[pos : S.chpos]; comment := S.src[pos : S.chpos];
if S.testmode { if S.testmode {
...@@ -586,6 +596,16 @@ exit: ...@@ -586,6 +596,16 @@ exit:
} }
} }
if nlpos < 0 {
// not only whitespace before comment on this line
comment = " " + comment;
} else if nlpos == pos {
// comment starts at the beginning of the line
comment = "\n" + comment;
} else {
// only whitespace before comment on this line
comment = "\t" + comment;
}
return comment; return comment;
} }
...@@ -815,20 +835,17 @@ func (S *Scanner) Select4(tok0, tok1, ch2, tok2, tok3 int) int { ...@@ -815,20 +835,17 @@ func (S *Scanner) Select4(tok0, tok1, ch2, tok2, tok3 int) int {
func (S *Scanner) Scan() (pos, tok int, val string) { func (S *Scanner) Scan() (pos, tok int, val string) {
S.SkipWhitespace(); nlpos := S.SkipWhitespace();
ch := S.ch; pos, tok = S.chpos, ILLEGAL;
pos = S.chpos;
tok = ILLEGAL;
switch { switch ch := S.ch; {
case is_letter(ch): tok, val = S.ScanIdentifier(); case is_letter(ch): tok, val = S.ScanIdentifier();
case digit_val(ch) < 10: tok, val = S.ScanNumber(false); case digit_val(ch) < 10: tok, val = S.ScanNumber(false);
default: default:
S.Next(); // always make progress S.Next(); // always make progress
switch ch { switch ch {
case -1: tok = EOF; case -1: tok = EOF;
case '\n', '\t': tok, val = COMMENT, S.ScanWhitespace();
case '"': tok, val = STRING, S.ScanString(); case '"': tok, val = STRING, S.ScanString();
case '\'': tok, val = INT, S.ScanChar(); case '\'': tok, val = INT, S.ScanChar();
case '`': tok, val = STRING, S.ScanRawString(); case '`': tok, val = STRING, S.ScanRawString();
...@@ -858,7 +875,7 @@ func (S *Scanner) Scan() (pos, tok int, val string) { ...@@ -858,7 +875,7 @@ func (S *Scanner) Scan() (pos, tok int, val string) {
case '*': tok = S.Select2(MUL, MUL_ASSIGN); case '*': tok = S.Select2(MUL, MUL_ASSIGN);
case '/': case '/':
if S.ch == '/' || S.ch == '*' { if S.ch == '/' || S.ch == '*' {
tok, val = COMMENT, S.ScanComment(); tok, val = COMMENT, S.ScanComment(nlpos);
} else { } else {
tok = S.Select2(QUO, QUO_ASSIGN); tok = S.Select2(QUO, QUO_ASSIGN);
} }
......
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import Fmt "fmt"
type T struct {
x, y int;
s string;
next_t *T
}
var (
A = 5;
a, b, c int = 0, 0, 0;
foo = "foo";
)
func main() {
// the prolog
for i := 0; i <= 10 /* limit */; i++ {
println(i); // the index
println(i + 1); // the index + 1
println(i + 1000); // the index + 1000
println();
}
// the epilog
println("foo"); // foo
println("foobar"); // foobar
var x int;
}
...@@ -96,11 +96,11 @@ valid() { ...@@ -96,11 +96,11 @@ valid() {
runtest() { runtest() {
#echo "Testing silent mode" #echo "Testing silent mode"
cleanup cleanup
$1 silent $1 silent $2
#echo "Testing idempotency" #echo "Testing idempotency"
cleanup cleanup
$1 idempotent $1 idempotent $2
} }
......
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