Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
golang
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
golang
Commits
a3b4a3c2
Commit
a3b4a3c2
authored
Nov 08, 2008
by
Robert Griesemer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
- steps towards "flexible tab stops" simulation in pretty
printing output - not yet enabled R=r OCL=18842 CL=18842
parent
4328d442
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
179 additions
and
26 deletions
+179
-26
ast.go
usr/gri/pretty/ast.go
+11
-1
parser.go
usr/gri/pretty/parser.go
+7
-2
printer.go
usr/gri/pretty/printer.go
+149
-15
scanner.go
usr/gri/pretty/scanner.go
+12
-8
No files found.
usr/gri/pretty/ast.go
View file @
a3b4a3c2
...
...
@@ -27,6 +27,11 @@ export type List struct {
}
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
);
...
...
@@ -78,9 +83,14 @@ func (p *List) Pop() Any {
}
func
(
p
*
List
)
Clear
()
{
p
.
a
=
p
.
a
[
0
:
0
];
}
export
func
NewList
()
*
List
{
p
:=
new
(
List
);
p
.
a
=
new
([]
Any
,
10
)
[
0
:
0
]
;
p
.
Init
()
;
return
p
;
}
...
...
usr/gri/pretty/parser.go
View file @
a3b4a3c2
...
...
@@ -77,8 +77,13 @@ 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
));
P
.
Next0
();
if
P
.
tok
==
Scanner
.
COMMENT
{
pos
,
s
:=
P
.
pos
,
P
.
val
;
for
P
.
Next0
();
P
.
tok
==
Scanner
.
COMMENT
;
P
.
Next0
()
{
s
+=
P
.
val
;
}
P
.
comments
.
Add
(
AST
.
NewComment
(
pos
,
s
));
}
}
...
...
usr/gri/pretty/printer.go
View file @
a3b4a3c2
...
...
@@ -7,11 +7,128 @@ package Printer
import
Strings
"strings"
import
Scanner
"scanner"
import
AST
"ast"
import
Flag
"flag"
import
Fmt
"fmt"
var
tabwith
=
Flag
.
Int
(
"tabwidth"
,
4
,
nil
,
"tab width"
);
// ----------------------------------------------------------------------------
// Support
func
assert
(
p
bool
)
{
if
!
p
{
panic
(
"assert failed"
);
}
}
func
PrintBlanks
(
n
int
)
{
// TODO make this faster
for
;
n
>
0
;
n
--
{
print
(
" "
);
}
}
// ----------------------------------------------------------------------------
// Implemententation of flexible tab stops.
// (http://nickgravgaard.com/elastictabstops/index.html)
type
Buffer
struct
{
lines
AST
.
List
;
// a list of lines; and each line is a list of strings
widths
AST
.
List
;
}
func
(
b
*
Buffer
)
Newline
()
{
b
.
lines
.
Add
(
AST
.
NewList
());
}
func
(
b
*
Buffer
)
Init
()
{
b
.
lines
.
Init
();
b
.
widths
.
Init
();
b
.
Newline
();
}
func
(
b
*
Buffer
)
ComputeWidths
()
{
// iterate through all columns j
for
j
:=
0
;
;
j
++
{
width
:=
-
1
;
// initial column width
// iterate through all lines i
for
i
:=
0
;
i
<
b
.
lines
.
len
();
i
++
{
line
:=
b
.
lines
.
at
(
i
)
.
(
*
AST
.
List
);
if
j
<
line
.
len
()
{
// the j.th column exists in this line
w
:=
len
(
line
.
at
(
j
)
.
(
string
));
if
w
>
width
{
width
=
w
;
}
}
}
if
width
>=
0
{
assert
(
b
.
widths
.
len
()
==
j
);
b
.
widths
.
Add
(
width
);
}
else
{
// no column j - we are done
return
;
}
}
}
export
type
Printer
struct
{
pos
int
;
// actual output position
func
(
b
*
Buffer
)
Flush
()
{
b
.
ComputeWidths
();
// print the lines
for
i
:=
0
;
i
<
b
.
lines
.
len
();
i
++
{
line
:=
b
.
lines
.
at
(
i
)
.
(
*
AST
.
List
);
for
j
:=
0
;
j
<
line
.
len
();
j
++
{
s
:=
line
.
at
(
j
)
.
(
string
);
d
:=
b
.
widths
.
at
(
j
)
.
(
int
)
-
len
(
s
);
assert
(
d
>=
0
);
if
d
<
int
(
tabwith
.
IVal
())
{
d
=
int
(
tabwith
.
IVal
());
}
PrintBlanks
(
d
);
// +1 padding
print
(
s
);
}
println
();
}
b
.
lines
.
Clear
();
b
.
widths
.
Clear
();
b
.
Newline
();
}
func
(
b
*
Buffer
)
Indent
(
n
int
)
{
line
:=
b
.
lines
.
at
(
b
.
lines
.
len
()
-
1
)
.
(
*
AST
.
List
);
for
;
n
>
0
;
n
--
{
line
.
Add
(
""
);
}
}
func
(
b
*
Buffer
)
Print
(
s
string
)
{
i
:=
b
.
lines
.
len
()
-
1
;
line
:=
b
.
lines
.
at
(
i
)
.
(
*
AST
.
List
);
j
:=
line
.
len
()
-
1
;
if
j
<
0
{
line
.
Add
(
s
);
}
else
{
line
.
set
(
j
,
line
.
at
(
j
)
.
(
string
)
+
s
);
}
}
export
type
Printer
struct
{
buf
Buffer
;
// formatting control
level
int
;
// true scope level
indent
int
;
// indentation level
...
...
@@ -25,24 +142,22 @@ export type Printer struct {
}
// Bottleneck interface - all output goes through here.
func
(
P
*
Printer
)
print
(
s
string
)
{
print
(
s
);
// TODO do we need the code below?
// P.pos += Strings.utflen(s);
}
const
NEW_CODE
=
false
;
func
(
P
*
Printer
)
String
(
pos
int
,
s
string
)
{
if
P
.
semi
&&
P
.
level
>
0
{
// no semicolons at level 0
print
(
";"
);
if
NEW_CODE
{
P
.
buf
.
Print
(
";"
);
}
else
{
print
(
";"
);
}
}
/*
for pos > P.cpos {
// we have a comment
c := P.clist.at(P.cindex).(*AST.Comment);
if c.text[1] == '/' {
if
len(c.text) > 1 &&
c.text[1] == '/' {
print(" " + c.text);
if P.newl <= 0 {
P.newl = 1; // line comments must have a newline
...
...
@@ -60,15 +175,30 @@ func (P *Printer) String(pos int, s string) {
*/
if
P
.
newl
>
0
{
if
NEW_CODE
{
P
.
buf
.
Flush
();
}
for
i
:=
P
.
newl
;
i
>
0
;
i
--
{
print
(
"
\n
"
);
if
NEW_CODE
{
P
.
buf
.
Newline
();
}
else
{
print
(
"
\n
"
);
}
}
for
i
:=
P
.
indent
;
i
>
0
;
i
--
{
print
(
"
\t
"
);
if
NEW_CODE
{
P
.
buf
.
Indent
(
P
.
indent
);
}
else
{
for
i
:=
P
.
indent
;
i
>
0
;
i
--
{
print
(
"
\t
"
);
}
}
}
print
(
s
);
if
NEW_CODE
{
P
.
buf
.
Print
(
s
);
}
else
{
print
(
s
);
}
P
.
semi
,
P
.
newl
=
false
,
0
;
}
...
...
@@ -519,6 +649,8 @@ func (P *Printer) Declaration(d *AST.Decl, parenthesized bool) {
func
(
P
*
Printer
)
Program
(
p
*
AST
.
Program
)
{
// TODO should initialize all fields?
P
.
buf
.
Init
();
P
.
clist
=
p
.
comments
;
P
.
cindex
=
0
;
if
p
.
comments
.
len
()
>
0
{
...
...
@@ -527,6 +659,7 @@ func (P *Printer) Program(p *AST.Program) {
P
.
cpos
=
1000000000
;
// infinite
}
// Print package
P
.
String
(
p
.
pos
,
"package "
);
P
.
Expr
(
p
.
ident
);
P
.
newl
=
2
;
...
...
@@ -534,5 +667,6 @@ func (P *Printer) Program(p *AST.Program) {
P
.
Declaration
(
p
.
decls
.
at
(
i
),
false
);
}
P
.
newl
=
1
;
P
.
String
(
0
,
""
);
// flush
}
usr/gri/pretty/scanner.go
View file @
a3b4a3c2
...
...
@@ -109,7 +109,7 @@ export const (
export
func
TokenString
(
tok
int
)
string
{
switch
(
tok
)
{
switch
tok
{
case
ILLEGAL
:
return
"ILLEGAL"
;
case
IDENT
:
return
"IDENT"
;
...
...
@@ -249,11 +249,6 @@ func init() {
}
func
is_whitespace
(
ch
int
)
bool
{
return
ch
==
' '
||
ch
==
'\r'
||
ch
==
'\n'
||
ch
==
'\t'
;
}
func
is_letter
(
ch
int
)
bool
{
return
'a'
<=
ch
&&
ch
<=
'z'
||
'A'
<=
ch
&&
ch
<=
'Z'
||
ch
==
'_'
||
ch
>=
128
;
}
...
...
@@ -524,12 +519,20 @@ func (S *Scanner) Expect(ch int) {
func
(
S
*
Scanner
)
SkipWhitespace
()
{
for
is_whitespace
(
S
.
ch
)
{
for
S
.
ch
==
' '
||
S
.
ch
==
'\r'
{
S
.
Next
();
}
}
func
(
S
*
Scanner
)
ScanWhitespace
()
string
{
// first char ('\n' or '\t', 1 byte) already consumed
pos
:=
S
.
chpos
-
1
;
S
.
SkipWhitespace
();
return
S
.
src
[
pos
:
S
.
chpos
];
}
func
(
S
*
Scanner
)
ScanComment
()
string
{
// first '/' already consumed
pos
:=
S
.
chpos
-
1
;
...
...
@@ -686,7 +689,7 @@ func (S *Scanner) ScanEscape(quote int) string {
ch
:=
S
.
ch
;
pos
:=
S
.
chpos
;
S
.
Next
();
switch
(
ch
)
{
switch
ch
{
case
'a'
,
'b'
,
'f'
,
'n'
,
'r'
,
't'
,
'v'
,
'\\'
:
return
string
(
ch
);
...
...
@@ -825,6 +828,7 @@ func (S *Scanner) Scan() (pos, tok int, val string) {
S
.
Next
();
// always make progress
switch
ch
{
case
-
1
:
tok
=
EOF
;
case
'\n'
,
'\t'
:
tok
,
val
=
COMMENT
,
S
.
ScanWhitespace
();
case
'"'
:
tok
,
val
=
STRING
,
S
.
ScanString
();
case
'\'
'
:
tok
,
val
=
INT
,
S
.
ScanChar
();
case
'`'
:
tok
,
val
=
STRING
,
S
.
ScanRawString
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment