Commit 22e0e1b0 authored by Robert Griesemer's avatar Robert Griesemer

- better comment classification

- related cleanups

R=r
OCL=19227
CL=19227
parent 3c2f0ae1
......@@ -258,14 +258,14 @@ export var BadDecl = NewDecl(0, Scanner.ILLEGAL, false);
// Program
export type Comment struct {
pos int;
pos, tok int;
text string;
}
export func NewComment(pos int, text string) *Comment {
export func NewComment(pos, tok int, text string) *Comment {
c := new(Comment);
c.pos, c.text = pos, text;
c.pos, c.tok, c.text = pos, tok, text;
return c;
}
......
......@@ -77,8 +77,15 @@ func (P *Parser) Next0() {
func (P *Parser) Next() {
for P.Next0(); P.tok == Scanner.COMMENT; P.Next0() {
P.comments.Add(AST.NewComment(P.pos, P.val));
// TODO This is too expensive for every token - fix
for P.Next0();
P.tok == Scanner.COMMENT_WW ||
P.tok == Scanner.COMMENT_WB ||
P.tok == Scanner.COMMENT_BW ||
P.tok == Scanner.COMMENT_BB ;
P.Next0()
{
P.comments.Add(AST.NewComment(P.pos, P.tok, P.val));
}
}
......
......@@ -234,45 +234,36 @@ func (P *Printer) String(pos int, s string) {
assert(len(text) >= 3); // classification char + "//" or "/*"
// classify comment
switch text[0] {
case ' ':
// not only white space before comment on the same line
// - put into next cell if //-style comment
// - preceed with a space if /*-style comment
//print("[case a][", text[1 : len(text)], "]");
if text[2] == '/' {
P.buf.Tab();
} else {
switch comment.tok {
case Scanner.COMMENT_BB:
// black space before and after comment on the same line
// - print surrounded by blanks
P.buf.Print(" ");
P.buf.Print(text);
P.buf.Print(" ");
}
/*
case '\n':
// comment starts at beginning of line
// - reproduce exactly
//print("[case b][", text[1 : len(text)], "]");
if !P.buf.AtLineBegin() {
P.buf.Newline();
}
*/
case Scanner.COMMENT_BW:
// only white space after comment on the same line
// - put into next cell
P.buf.Tab();
P.buf.Print(text);
case '\n', '\t':
case Scanner.COMMENT_WW, Scanner.COMMENT_WB:
// only white space before comment on the same line
// - indent
//print("[case c][", text[1 : len(text)], "]");
if !P.buf.EmptyLine() {
P.buf.Newline();
}
for i := P.indent; i > 0; i-- {
P.buf.Tab();
}
P.buf.Print(text);
default:
panic("UNREACHABLE");
}
P.buf.Print(text[1 : len(text)]);
if text[2] == '/' {
if text[1] == '/' {
// line comments must end in newline
// TODO should we set P.newl instead?
P.buf.Newline();
......
......@@ -13,9 +13,13 @@ export const (
INT;
FLOAT;
STRING;
COMMENT;
EOF;
COMMENT_BB;
COMMENT_BW;
COMMENT_WB;
COMMENT_WW;
ADD;
SUB;
MUL;
......@@ -116,9 +120,13 @@ export func TokenString(tok int) string {
case INT: return "INT";
case FLOAT: return "FLOAT";
case STRING: return "STRING";
case COMMENT: return "COMMENT";
case EOF: return "EOF";
case COMMENT_BB: return "COMMENT_BB";
case COMMENT_BW: return "COMMENT_BW";
case COMMENT_WB: return "COMMENT_WB";
case COMMENT_WW: return "COMMENT_WW";
case ADD: return "+";
case SUB: return "-";
case MUL: return "*";
......@@ -518,29 +526,23 @@ func (S *Scanner) Expect(ch int) {
}
func (S *Scanner) SkipWhitespace() int {
pos := -1; // no new line position yet
if S.chpos == 0 {
// file beginning is always start of a new line
pos = 0;
}
// Returns true if a newline was seen, returns false otherwise.
func (S *Scanner) SkipWhitespace() bool {
sawnl := S.chpos == 0; // file beginning is always start of a new line
for {
switch S.ch {
case '\t', '\r', ' ': // nothing to do
case '\n': pos = S.pos; // remember start of new line
default: goto exit;
case '\n': sawnl = true;
default: return sawnl;
}
S.Next();
}
exit:
return pos;
panic("UNREACHABLE");
return false;
}
func (S *Scanner) ScanComment(nlpos int) string {
func (S *Scanner) ScanComment(leading_ws bool) (tok int, val string) {
// first '/' already consumed
pos := S.chpos - 1;
......@@ -575,6 +577,12 @@ func (S *Scanner) ScanComment(nlpos int) string {
exit:
comment := S.src[pos : S.chpos];
// skip whitespace but stop at line end
for S.ch == '\t' || S.ch == '\r' || S.ch == ' ' {
S.Next();
}
trailing_ws := S.ch == '\n';
if S.testmode {
// interpret ERROR and SYNC comments
oldpos := -1;
......@@ -596,17 +604,21 @@ 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;
if leading_ws {
if trailing_ws {
tok = COMMENT_WW;
} else {
// only whitespace before comment on this line
comment = "\t" + comment;
tok = COMMENT_WB;
}
return comment;
} else {
if trailing_ws {
tok = COMMENT_BW;
} else {
tok = COMMENT_BB;
}
}
return tok, comment;
}
......@@ -835,7 +847,7 @@ func (S *Scanner) Select4(tok0, tok1, ch2, tok2, tok3 int) int {
func (S *Scanner) Scan() (pos, tok int, val string) {
nlpos := S.SkipWhitespace();
sawnl := S.SkipWhitespace();
pos, tok = S.chpos, ILLEGAL;
......@@ -875,7 +887,7 @@ func (S *Scanner) Scan() (pos, tok int, val string) {
case '*': tok = S.Select2(MUL, MUL_ASSIGN);
case '/':
if S.ch == '/' || S.ch == '*' {
tok, val = COMMENT, S.ScanComment(nlpos);
tok, val = S.ScanComment(sawnl);
} else {
tok = S.Select2(QUO, QUO_ASSIGN);
}
......
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