]> Cypherpunks repositories - gostls13.git/commitdiff
- better comment classification
authorRobert Griesemer <gri@golang.org>
Fri, 14 Nov 2008 03:06:57 +0000 (19:06 -0800)
committerRobert Griesemer <gri@golang.org>
Fri, 14 Nov 2008 03:06:57 +0000 (19:06 -0800)
- related cleanups

R=r
OCL=19227
CL=19227

usr/gri/pretty/ast.go
usr/gri/pretty/parser.go
usr/gri/pretty/printer.go
usr/gri/pretty/scanner.go

index 928e85dc69767f9c4e2bfe5b8c7918181e1f36ec..3731a0357e0cef378220a21bd8a749c215e1a3e5 100644 (file)
@@ -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;
 }
 
index d9e7c921ee82bd8ce53dfed07d3e8906a7597cb9..5cd454918bada6271a1ec16fb603e3fafb5960c5 100644 (file)
@@ -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));
        }
 }
 
index 14f8e60b5f5073dce1229ea87af4f0737f4dfe1f..57b3124ba753fbf5a08a07b0822efc93d46a78e5 100644 (file)
@@ -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 {
-                               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();
-                       }
-                       */
+               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 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();
index 0c986423b51d4e0ff3adcc6fa0c665b90aea8f3a..6aca9beb0f3c65dc5489d26868b4e60965b5ac37 100644 (file)
@@ -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;
@@ -595,18 +603,22 @@ exit:
                        S.ErrorMsg(oldpos, "ERROR not found");
                }
        }
-       
-       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 {
+                       tok = COMMENT_WB;
+               }
        } else {
-               // only whitespace before comment on this line
-               comment = "\t" + comment;
+               if trailing_ws {
+                       tok = COMMENT_BW;
+               } else {
+                       tok = COMMENT_BB;
+               }
        }
-       return comment;
+
+       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);
                        }