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
c5119538
Commit
c5119538
authored
Sep 25, 2008
by
Robert Griesemer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
snapshot: more pretty printer stuff
R=r OCL=15863 CL=15863
parent
99ec0313
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
125 additions
and
87 deletions
+125
-87
ast.go
usr/gri/pretty/ast.go
+35
-18
parser.go
usr/gri/pretty/parser.go
+49
-58
printer.go
usr/gri/pretty/printer.go
+41
-11
No files found.
usr/gri/pretty/ast.go
View file @
c5119538
...
...
@@ -49,6 +49,7 @@ export type Visitor interface {
DoSwitchStat
(
x
*
SwitchStat
);
DoReturnStat
(
x
*
ReturnStat
);
DoIncDecStat
(
x
*
IncDecStat
);
DoControlFlowStat
(
x
*
ControlFlowStat
);
// Program
DoProgram
(
x
*
Program
);
...
...
@@ -65,6 +66,9 @@ export type Node interface {
// ----------------------------------------------------------------------------
// Lists
//
// If p is a list and p == nil, then p.len() == 0.
// Thus, empty lists can be represented by nil.
export
type
List
struct
{
a
*
[]
Node
...
...
@@ -335,19 +339,26 @@ export type Assignment struct {
}
export
type
ControlClause
struct
{
init
Stat
;
expr
Expr
;
post
Stat
;
has_init
,
has_expr
,
has_post
bool
;
}
export
type
IfStat
struct
{
pos
int
;
// position of "if"
init
Stat
;
cond
Expr
;
then
,
else_
*
Block
;
ctrl
*
ControlClause
;
then
*
Block
;
else_
Stat
;
has_else
bool
;
}
export
type
ForStat
struct
{
pos
int
;
// position of "for"
init
Stat
;
cond
Expr
;
post
Stat
;
ctrl
*
ControlClause
;
body
*
Block
;
}
...
...
@@ -362,15 +373,14 @@ export type CaseClause struct {
export
type
SwitchStat
struct
{
pos
int
;
// position of "switch"
init
Stat
;
tag
Expr
;
ctrl
*
ControlClause
;
cases
*
List
;
// list of *CaseClause
}
export
type
ReturnStat
struct
{
pos
int
;
// position of "return"
res
*
List
;
res
*
List
;
// list of Expr
}
...
...
@@ -381,16 +391,23 @@ export type IncDecStat struct {
}
func
(
x
*
Block
)
Visit
(
v
Visitor
)
{
v
.
DoBlock
(
x
);
}
func
(
x
*
ExprStat
)
Visit
(
v
Visitor
)
{
v
.
DoExprStat
(
x
);
}
func
(
x
*
Assignment
)
Visit
(
v
Visitor
)
{
v
.
DoAssignment
(
x
);
}
func
(
x
*
IfStat
)
Visit
(
v
Visitor
)
{
v
.
DoIfStat
(
x
);
}
func
(
x
*
ForStat
)
Visit
(
v
Visitor
)
{
v
.
DoForStat
(
x
);
}
func
(
x
*
CaseClause
)
Visit
(
v
Visitor
)
{
v
.
DoCaseClause
(
x
);
}
func
(
x
*
SwitchStat
)
Visit
(
v
Visitor
)
{
v
.
DoSwitchStat
(
x
);
}
func
(
x
*
ReturnStat
)
Visit
(
v
Visitor
)
{
v
.
DoReturnStat
(
x
);
}
func
(
x
*
IncDecStat
)
Visit
(
v
Visitor
)
{
v
.
DoIncDecStat
(
x
);
}
export
type
ControlFlowStat
struct
{
pos
int
;
// position of token
tok
int
;
label
*
Ident
;
// nil, if no label
}
func
(
x
*
Block
)
Visit
(
v
Visitor
)
{
v
.
DoBlock
(
x
);
}
func
(
x
*
ExprStat
)
Visit
(
v
Visitor
)
{
v
.
DoExprStat
(
x
);
}
func
(
x
*
Assignment
)
Visit
(
v
Visitor
)
{
v
.
DoAssignment
(
x
);
}
func
(
x
*
IfStat
)
Visit
(
v
Visitor
)
{
v
.
DoIfStat
(
x
);
}
func
(
x
*
ForStat
)
Visit
(
v
Visitor
)
{
v
.
DoForStat
(
x
);
}
func
(
x
*
CaseClause
)
Visit
(
v
Visitor
)
{
v
.
DoCaseClause
(
x
);
}
func
(
x
*
SwitchStat
)
Visit
(
v
Visitor
)
{
v
.
DoSwitchStat
(
x
);
}
func
(
x
*
ReturnStat
)
Visit
(
v
Visitor
)
{
v
.
DoReturnStat
(
x
);
}
func
(
x
*
IncDecStat
)
Visit
(
v
Visitor
)
{
v
.
DoIncDecStat
(
x
);
}
func
(
x
*
ControlFlowStat
)
Visit
(
v
Visitor
)
{
v
.
DoControlFlowStat
(
x
);
}
// ----------------------------------------------------------------------------
// Program
...
...
usr/gri/pretty/parser.go
View file @
c5119538
...
...
@@ -404,7 +404,7 @@ func (P *Parser) ParseMapType() *AST.MapType {
func
(
P
*
Parser
)
ParseStructType
()
*
AST
.
StructType
{
P
.
Trace
(
"StructType"
);
typ
:=
new
(
AST
.
StructType
);
typ
.
pos
=
P
.
pos
;
typ
.
fields
=
AST
.
NewList
();
...
...
@@ -912,99 +912,91 @@ func (P *Parser) ParseGoStat() {
func
(
P
*
Parser
)
ParseReturnStat
()
*
AST
.
ReturnStat
{
P
.
Trace
(
"ReturnStat"
);
re
t
:=
new
(
AST
.
ReturnStat
);
re
t
.
pos
=
P
.
pos
;
sta
t
:=
new
(
AST
.
ReturnStat
);
sta
t
.
pos
=
P
.
pos
;
P
.
Expect
(
Scanner
.
RETURN
);
if
P
.
tok
!=
Scanner
.
SEMICOLON
&&
P
.
tok
!=
Scanner
.
RBRACE
{
re
t
.
res
=
P
.
ParseExpressionList
();
sta
t
.
res
=
P
.
ParseExpressionList
();
}
P
.
Ecart
();
return
re
t
;
return
sta
t
;
}
func
(
P
*
Parser
)
ParseControlFlowStat
(
tok
int
)
{
func
(
P
*
Parser
)
ParseControlFlowStat
(
tok
int
)
*
AST
.
ControlFlowStat
{
P
.
Trace
(
"ControlFlowStat"
);
stat
:=
new
(
AST
.
ControlFlowStat
);
stat
.
pos
,
stat
.
tok
=
P
.
pos
,
P
.
tok
;
P
.
Expect
(
tok
);
if
P
.
tok
==
Scanner
.
IDENT
{
P
.
ParseIdent
();
stat
.
label
=
P
.
ParseIdent
();
}
P
.
Ecart
();
return
stat
;
}
func
(
P
*
Parser
)
Parse
StatHeader
(
keyword
int
)
(
init_
AST
.
Stat
,
expr_
AST
.
Expr
,
post_
AST
.
Stat
)
{
func
(
P
*
Parser
)
Parse
ControlClause
(
keyword
int
)
*
AST
.
ControlClause
{
P
.
Trace
(
"StatHeader"
);
var
(
init
AST
.
Stat
=
AST
.
NIL
;
expr
AST
.
Expr
=
AST
.
NIL
;
post
AST
.
Stat
=
AST
.
NIL
;
)
has_init
,
has_expr
,
has_post
:=
false
,
false
,
false
;
ctrl
:=
new
(
AST
.
ControlClause
);
ctrl
.
init
,
ctrl
.
expr
,
ctrl
.
post
=
AST
.
NIL
,
AST
.
NIL
,
AST
.
NIL
;
P
.
Expect
(
keyword
);
if
P
.
tok
!=
Scanner
.
LBRACE
{
if
P
.
tok
!=
Scanner
.
SEMICOLON
{
init
=
P
.
ParseSimpleStat
();
has_init
=
true
;
ctrl
.
init
=
P
.
ParseSimpleStat
();
ctrl
.
has_init
=
true
;
}
if
P
.
tok
==
Scanner
.
SEMICOLON
{
P
.
Next
();
if
P
.
tok
!=
Scanner
.
SEMICOLON
&&
P
.
tok
!=
Scanner
.
LBRACE
{
ctrl
.
expr
=
P
.
ParseExpression
();
ctrl
.
has_expr
=
true
;
}
if
keyword
==
Scanner
.
FOR
{
if
P
.
tok
!=
Scanner
.
SEMICOLON
{
expr
=
P
.
ParseExpression
();
has_expr
=
true
;
}
P
.
Expect
(
Scanner
.
SEMICOLON
);
if
P
.
tok
!=
Scanner
.
LBRACE
{
post
=
P
.
ParseSimpleStat
();
has_post
=
true
;
}
}
else
{
if
P
.
tok
!=
Scanner
.
LBRACE
{
expr
=
P
.
ParseExpression
();
has_expr
=
true
;
ctrl
.
post
=
P
.
ParseSimpleStat
();
ctrl
.
has_post
=
true
;
}
}
}
else
{
ctrl
.
expr
,
ctrl
.
has_expr
=
ctrl
.
init
,
ctrl
.
has_init
;
ctrl
.
init
,
ctrl
.
has_init
=
AST
.
NIL
,
false
;
}
}
P
.
Ecart
();
return
init
,
expr
,
post
;
return
ctrl
;
}
func
(
P
*
Parser
)
ParseIfStat
()
*
AST
.
IfStat
{
P
.
Trace
(
"IfStat"
);
x
:=
new
(
AST
.
IfStat
);
x
.
pos
=
P
.
pos
;
var
dummy
AST
.
Stat
;
x
.
init
,
x
.
cond
,
dummy
=
P
.
ParseStatHeader
(
Scanner
.
IF
);
x
.
then
=
P
.
ParseBlock
();
stat
:=
new
(
AST
.
IfStat
);
stat
.
pos
=
P
.
pos
;
stat
.
ctrl
=
P
.
ParseControlClause
(
Scanner
.
IF
);
stat
.
then
=
P
.
ParseBlock
();
if
P
.
tok
==
Scanner
.
ELSE
{
P
.
Next
();
b
:=
new
(
AST
.
Block
);
b
.
stats
=
AST
.
NewList
();
if
P
.
tok
==
Scanner
.
IF
{
b
.
stats
.
Add
(
P
.
ParseIfStat
()
);
stat
.
else_
=
P
.
ParseIfStat
(
);
}
else
{
// TODO
should be P.ParseBlock()
b
.
stats
.
Add
(
P
.
ParseStatement
()
);
// TODO
: Should be P.ParseBlock().
stat
.
else_
=
P
.
ParseStatement
(
);
}
x
.
else_
=
b
;
stat
.
has_else
=
true
;
}
P
.
Ecart
();
return
x
;
return
stat
;
}
...
...
@@ -1014,7 +1006,7 @@ func (P *Parser) ParseForStat() *AST.ForStat {
stat
:=
new
(
AST
.
ForStat
);
stat
.
pos
=
P
.
pos
;
P
.
ParseStatHeader
(
Scanner
.
FOR
);
stat
.
ctrl
=
P
.
ParseControlClause
(
Scanner
.
FOR
);
stat
.
body
=
P
.
ParseBlock
();
P
.
Ecart
();
...
...
@@ -1065,10 +1057,8 @@ func (P *Parser) ParseSwitchStat() *AST.SwitchStat {
stat
:=
new
(
AST
.
SwitchStat
);
stat
.
pos
=
P
.
pos
;
stat
.
init
=
AST
.
NIL
;
stat
.
ctrl
=
P
.
ParseControlClause
(
Scanner
.
SWITCH
)
;
stat
.
cases
=
AST
.
NewList
();
P
.
ParseStatHeader
(
Scanner
.
SWITCH
);
P
.
Expect
(
Scanner
.
LBRACE
);
for
P
.
tok
==
Scanner
.
CASE
||
P
.
tok
==
Scanner
.
DEFAULT
{
...
...
@@ -1169,7 +1159,7 @@ func (P *Parser) TryStatement() (stat_ AST.Stat, ok_ bool) {
case
Scanner
.
RETURN
:
stat
=
P
.
ParseReturnStat
();
case
Scanner
.
BREAK
,
Scanner
.
CONTINUE
,
Scanner
.
GOTO
:
P
.
ParseControlFlowStat
(
P
.
tok
);
stat
=
P
.
ParseControlFlowStat
(
P
.
tok
);
case
Scanner
.
LBRACE
:
stat
=
P
.
ParseBlock
();
case
Scanner
.
IF
:
...
...
@@ -1219,7 +1209,7 @@ func (P *Parser) ParseImportSpec() {
}
func
(
P
*
Parser
)
ParseConstSpec
(
exported
bool
)
AST
.
Decl
{
func
(
P
*
Parser
)
ParseConstSpec
(
exported
bool
)
*
AST
.
Const
Decl
{
P
.
Trace
(
"ConstSpec"
);
decl
:=
new
(
AST
.
ConstDecl
);
...
...
@@ -1237,7 +1227,7 @@ func (P *Parser) ParseConstSpec(exported bool) AST.Decl {
}
func
(
P
*
Parser
)
ParseTypeSpec
(
exported
bool
)
AST
.
Decl
{
func
(
P
*
Parser
)
ParseTypeSpec
(
exported
bool
)
*
AST
.
Type
Decl
{
P
.
Trace
(
"TypeSpec"
);
decl
:=
new
(
AST
.
TypeDecl
);
...
...
@@ -1249,7 +1239,7 @@ func (P *Parser) ParseTypeSpec(exported bool) AST.Decl {
}
func
(
P
*
Parser
)
ParseVarSpec
(
exported
bool
)
AST
.
Decl
{
func
(
P
*
Parser
)
ParseVarSpec
(
exported
bool
)
*
AST
.
Var
Decl
{
P
.
Trace
(
"VarSpec"
);
decl
:=
new
(
AST
.
VarDecl
);
...
...
@@ -1270,7 +1260,7 @@ func (P *Parser) ParseVarSpec(exported bool) AST.Decl {
}
// TODO
With method variables, we wouldn't need this dispatch function
.
// TODO
Replace this by using function pointers derived from methods
.
func
(
P
*
Parser
)
ParseSpec
(
exported
bool
,
keyword
int
)
AST
.
Decl
{
var
decl
AST
.
Decl
=
AST
.
NIL
;
switch
keyword
{
...
...
@@ -1333,13 +1323,14 @@ func (P *Parser) ParseFuncDecl(exported bool) *AST.FuncDecl {
var
recv
*
AST
.
VarDeclList
;
if
P
.
tok
==
Scanner
.
LPAREN
{
recv_pos
:=
P
.
pos
;
recv
:=
P
.
ParseParameters
()
.
at
(
0
);
/*
if n != 1 {
P.Error(recv_pos, "must have exactly one receiver");
pos
:=
P
.
pos
;
tmp
:=
P
.
ParseParameters
();
if
tmp
.
len
()
>
0
{
recv
=
tmp
.
at
(
0
);
}
if
recv
.
idents
.
len
()
!=
1
{
P
.
Error
(
pos
,
"must have exactly one receiver"
);
}
*/
}
fun
.
ident
=
P
.
ParseIdent
();
...
...
usr/gri/pretty/printer.go
View file @
c5119538
...
...
@@ -8,7 +8,8 @@ import Scanner "scanner"
import
AST
"ast"
type
Printer
/* implements AST.Visitor */
struct
{
// Printer implements AST.Visitor
type
Printer
struct
{
indent
int
;
}
...
...
@@ -49,7 +50,7 @@ func (P *Printer) PrintList(p *AST.List) {
// Basics
func
(
P
*
Printer
)
DoNil
(
x
*
AST
.
Nil
)
{
P
.
String
(
"
?
"
);
P
.
String
(
"
<NIL>
"
);
}
...
...
@@ -162,7 +163,7 @@ func (P *Printer) DoFuncDecl(x *AST.FuncDecl) {
P
.
String
(
"func "
);
if
x
.
typ
.
recv
!=
nil
{
P
.
String
(
"("
);
P
.
PrintList
(
x
.
typ
.
recv
.
idents
);
P
.
DoVarDeclList
(
x
.
typ
.
recv
);
P
.
String
(
") "
);
}
P
.
DoIdent
(
x
.
ident
);
...
...
@@ -193,6 +194,7 @@ func (P *Printer) DoDeclaration(x *AST.Declaration) {
if
i
>
0
{
P
.
NewLine
(
0
);
}
//print("*** i = ", i, "\n");
P
.
Print
(
x
.
decls
.
at
(
i
));
}
P
.
NewLine
(
-
1
);
...
...
@@ -291,21 +293,38 @@ func (P *Printer) DoAssignment(x *AST.Assignment) {
}
func
(
P
*
Printer
)
PrintControlClause
(
x
*
AST
.
ControlClause
)
{
if
x
.
has_init
{
P
.
String
(
" "
);
P
.
Print
(
x
.
init
);
P
.
String
(
";"
);
}
if
x
.
has_expr
{
P
.
String
(
" "
);
P
.
Print
(
x
.
expr
);
}
if
x
.
has_post
{
P
.
String
(
"; "
);
P
.
Print
(
x
.
post
);
}
P
.
String
(
" "
);
}
func
(
P
*
Printer
)
DoIfStat
(
x
*
AST
.
IfStat
)
{
P
.
String
(
"if "
);
P
.
Print
(
x
.
init
);
P
.
String
(
"; "
);
P
.
Print
(
x
.
cond
);
P
.
String
(
"if"
);
P
.
PrintControlClause
(
x
.
ctrl
);
P
.
DoBlock
(
x
.
then
);
if
x
.
else_
!=
nil
{
if
x
.
has_else
{
P
.
String
(
" else "
);
P
.
DoBlock
(
x
.
else_
);
P
.
Print
(
x
.
else_
);
}
}
func
(
P
*
Printer
)
DoForStat
(
x
*
AST
.
ForStat
)
{
P
.
String
(
"for "
);
P
.
String
(
"for"
);
P
.
PrintControlClause
(
x
.
ctrl
);
P
.
DoBlock
(
x
.
body
);
}
...
...
@@ -360,7 +379,8 @@ func (P *Printer) DoCaseClause(x *AST.CaseClause) {
func
(
P
*
Printer
)
DoSwitchStat
(
x
*
AST
.
SwitchStat
)
{
P
.
String
(
"switch "
);
P
.
String
(
"switch"
);
P
.
PrintControlClause
(
x
.
ctrl
);
P
.
String
(
"{"
);
P
.
NewLine
(
0
);
for
i
:=
0
;
i
<
x
.
cases
.
len
();
i
++
{
...
...
@@ -385,6 +405,16 @@ func (P *Printer) DoIncDecStat(x *AST.IncDecStat) {
}
func
(
P
*
Printer
)
DoControlFlowStat
(
x
*
AST
.
ControlFlowStat
)
{
P
.
String
(
Scanner
.
TokenName
(
x
.
tok
));
if
x
.
label
!=
nil
{
P
.
String
(
" "
);
P
.
Print
(
x
.
label
);
}
P
.
String
(
";"
);
}
// ----------------------------------------------------------------------------
// Program
...
...
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