Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
go
Commits
ba620d50
Commit
ba620d50
authored
Mar 25, 2009
by
Robert Griesemer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
adjustments matching updated ast
R=r OCL=26746 CL=26746
parent
bafd8c39
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
338 additions
and
287 deletions
+338
-287
usr/gri/pretty/parser.go
usr/gri/pretty/parser.go
+199
-185
usr/gri/pretty/printer.go
usr/gri/pretty/printer.go
+139
-102
No files found.
usr/gri/pretty/parser.go
View file @
ba620d50
...
...
@@ -219,7 +219,7 @@ func (P *Parser) getDoc() ast.Comments {
func
(
P
*
Parser
)
tryType
()
ast
.
Expr
;
func
(
P
*
Parser
)
parseExpression
(
prec
int
)
ast
.
Expr
;
func
(
P
*
Parser
)
parseStatement
()
ast
.
St
a
t
;
func
(
P
*
Parser
)
parseStatement
()
ast
.
St
m
t
;
func
(
P
*
Parser
)
parseDeclaration
()
ast
.
Decl
;
...
...
@@ -489,18 +489,18 @@ func (P *Parser) parseResult() []*ast.Field {
defer
un
(
trace
(
P
,
"Result"
));
}
var
result
[]
*
ast
.
Field
;
var
result
s
[]
*
ast
.
Field
;
if
P
.
tok
==
token
.
LPAREN
{
result
=
P
.
parseParameters
(
false
);
result
s
=
P
.
parseParameters
(
false
);
}
else
if
P
.
tok
!=
token
.
FUNC
{
typ
:=
P
.
tryType
();
if
typ
!=
nil
{
result
=
make
([]
*
ast
.
Field
,
1
);
result
[
0
]
=
&
ast
.
Field
{
nil
,
nil
,
typ
,
nil
};
result
s
=
make
([]
*
ast
.
Field
,
1
);
result
s
[
0
]
=
&
ast
.
Field
{
nil
,
nil
,
typ
,
nil
};
}
}
return
result
;
return
result
s
;
}
...
...
@@ -510,16 +510,15 @@ func (P *Parser) parseResult() []*ast.Field {
// (params) type
// (params) (results)
func
(
P
*
Parser
)
parseSignature
()
*
ast
.
Signature
{
func
(
P
*
Parser
)
parseSignature
()
(
params
[]
*
ast
.
Field
,
results
[]
*
ast
.
Field
)
{
if
P
.
trace
{
defer
un
(
trace
(
P
,
"Signature"
));
}
params
:=
P
.
parseParameters
(
true
);
// TODO find better solution
//t.End = P.pos;
result
:=
P
.
parseResult
();
params
=
P
.
parseParameters
(
true
);
// TODO find better solution
results
=
P
.
parseResult
();
return
&
ast
.
Signature
{
params
,
result
}
;
return
params
,
results
;
}
...
...
@@ -529,9 +528,9 @@ func (P *Parser) parseFunctionType() *ast.FunctionType {
}
pos
:=
P
.
expect
(
token
.
FUNC
);
sig
:=
P
.
parseSignature
();
params
,
results
:=
P
.
parseSignature
();
return
&
ast
.
FunctionType
{
pos
,
sig
};
return
&
ast
.
FunctionType
{
pos
,
params
,
results
};
}
...
...
@@ -547,7 +546,8 @@ func (P *Parser) parseMethodSpec() *ast.Field {
if
tmp
,
is_ident
:=
x
.
(
*
ast
.
Ident
);
is_ident
&&
(
P
.
tok
==
token
.
COMMA
||
P
.
tok
==
token
.
LPAREN
)
{
// method(s)
idents
=
P
.
parseIdentList
(
x
);
typ
=
&
ast
.
FunctionType
{
nopos
,
P
.
parseSignature
()};
params
,
results
:=
P
.
parseSignature
();
typ
=
&
ast
.
FunctionType
{
nopos
,
params
,
results
};
}
else
{
// embedded interface
typ
=
x
;
...
...
@@ -606,7 +606,7 @@ func (P *Parser) parseMapType() *ast.MapType {
}
func
(
P
*
Parser
)
parseStringLi
t
(
x
*
ast
.
BasicLit
)
*
ast
.
StringLit
func
(
P
*
Parser
)
parseStringLi
st
(
x
*
ast
.
StringLit
)
[]
*
ast
.
StringLit
func
(
P
*
Parser
)
parseFieldDecl
()
*
ast
.
Field
{
if
P
.
trace
{
...
...
@@ -631,9 +631,9 @@ func (P *Parser) parseFieldDecl() *ast.Field {
typ
:=
P
.
tryType
();
// optional tag
var
tag
ast
.
Expr
;
var
tag
[]
*
ast
.
StringLit
;
if
P
.
tok
==
token
.
STRING
{
tag
=
P
.
parseStringLit
(
nil
);
tag
=
P
.
parseStringLi
s
t
(
nil
);
}
// analyze case
...
...
@@ -743,16 +743,16 @@ func (P *Parser) tryType() ast.Expr {
// ----------------------------------------------------------------------------
// Blocks
func
asSt
atList
(
list
*
vector
.
Vector
)
[]
ast
.
Sta
t
{
stats
:=
make
([]
ast
.
St
a
t
,
list
.
Len
());
func
asSt
mtList
(
list
*
vector
.
Vector
)
[]
ast
.
Stm
t
{
stats
:=
make
([]
ast
.
St
m
t
,
list
.
Len
());
for
i
:=
0
;
i
<
list
.
Len
();
i
++
{
stats
[
i
]
=
list
.
At
(
i
)
.
(
ast
.
St
a
t
);
stats
[
i
]
=
list
.
At
(
i
)
.
(
ast
.
St
m
t
);
}
return
stats
;
}
func
(
P
*
Parser
)
parseStatementList
()
[]
ast
.
St
a
t
{
func
(
P
*
Parser
)
parseStatementList
()
[]
ast
.
St
m
t
{
if
P
.
trace
{
defer
un
(
trace
(
P
,
"StatementList"
));
}
...
...
@@ -774,24 +774,21 @@ func (P *Parser) parseStatementList() []ast.Stat {
}
}
return
asSt
a
tList
(
list
);
return
asSt
m
tList
(
list
);
}
func
(
P
*
Parser
)
parseBlock
(
tok
int
)
*
ast
.
Block
{
func
(
P
*
Parser
)
parseBlock
Stmt
()
*
ast
.
BlockStmt
{
if
P
.
trace
{
defer
un
(
trace
(
P
,
"
Block
"
));
defer
un
(
trace
(
P
,
"
compositeStmt
"
));
}
pos
:=
P
.
expect
(
tok
);
lbrace
:=
P
.
expect
(
token
.
LBRACE
);
list
:=
P
.
parseStatementList
();
var
end
scanner
.
Location
;
if
tok
==
token
.
LBRACE
{
end
=
P
.
expect
(
token
.
RBRACE
);
rbrace
:=
P
.
expect
(
token
.
RBRACE
);
P
.
opt_semi
=
true
;
}
return
&
ast
.
Block
{
pos
,
tok
,
list
,
end
};
return
&
ast
.
Block
Stmt
{
lbrace
,
list
,
rbrace
};
}
...
...
@@ -803,19 +800,18 @@ func (P *Parser) parseFunctionLit() ast.Expr {
defer
un
(
trace
(
P
,
"FunctionLit"
));
}
pos
:=
P
.
expect
(
token
.
FUNC
);
typ
:=
P
.
parseSignature
();
typ
:=
P
.
parseFunctionType
();
P
.
expr_lev
++
;
body
:=
P
.
parseBlock
(
token
.
LBRACE
);
body
:=
P
.
parseBlock
Stmt
(
);
P
.
expr_lev
--
;
return
&
ast
.
FunctionLit
{
pos
,
typ
,
body
};
return
&
ast
.
FunctionLit
{
typ
,
body
};
}
func
(
P
*
Parser
)
parseStringLi
t
(
x
*
ast
.
BasicLit
)
*
ast
.
StringLit
{
func
(
P
*
Parser
)
parseStringLi
st
(
x
*
ast
.
StringLit
)
[]
*
ast
.
StringLit
{
if
P
.
trace
{
defer
un
(
trace
(
P
,
"StringLit"
));
defer
un
(
trace
(
P
,
"StringLi
s
t"
));
}
list
:=
vector
.
New
(
0
);
...
...
@@ -824,17 +820,17 @@ func (P *Parser) parseStringLit(x *ast.BasicLit) *ast.StringLit {
}
for
P
.
tok
==
token
.
STRING
{
list
.
Push
(
&
ast
.
BasicLit
{
P
.
pos
,
token
.
STRING
,
P
.
val
});
list
.
Push
(
&
ast
.
StringLit
{
P
.
pos
,
P
.
val
});
P
.
next
();
}
// convert list
strings
:=
make
([]
*
ast
.
Basic
Lit
,
list
.
Len
());
strings
:=
make
([]
*
ast
.
String
Lit
,
list
.
Len
());
for
i
:=
0
;
i
<
list
.
Len
();
i
++
{
strings
[
i
]
=
list
.
At
(
i
)
.
(
*
ast
.
Basic
Lit
);
strings
[
i
]
=
list
.
At
(
i
)
.
(
*
ast
.
String
Lit
);
}
return
&
ast
.
StringLit
{
strings
}
;
return
strings
;
}
...
...
@@ -847,16 +843,26 @@ func (P *Parser) parseOperand() ast.Expr {
case
token
.
IDENT
:
return
P
.
parseIdent
();
case
token
.
INT
,
token
.
FLOAT
,
token
.
CHAR
:
x
:=
&
ast
.
BasicLit
{
P
.
pos
,
P
.
tok
,
P
.
val
};
case
token
.
INT
:
x
:=
&
ast
.
IntLit
{
P
.
pos
,
P
.
val
};
P
.
next
();
return
x
;
case
token
.
FLOAT
:
x
:=
&
ast
.
FloatLit
{
P
.
pos
,
P
.
val
};
P
.
next
();
return
x
;
case
token
.
CHAR
:
x
:=
&
ast
.
CharLit
{
P
.
pos
,
P
.
val
};
P
.
next
();
return
x
;
case
token
.
STRING
:
x
:=
&
ast
.
BasicLit
{
P
.
pos
,
token
.
STRING
,
P
.
val
};
x
:=
&
ast
.
StringLit
{
P
.
pos
,
P
.
val
};
P
.
next
();
if
P
.
tok
==
token
.
STRING
{
return
P
.
parseStringLit
(
x
)
;
return
&
ast
.
StringList
{
P
.
parseStringList
(
x
)}
;
}
return
x
;
...
...
@@ -1106,9 +1112,9 @@ func (P *Parser) parseExpression(prec int) ast.Expr {
// Statements
func
(
P
*
Parser
)
parseSimpleSt
at
()
ast
.
Sta
t
{
func
(
P
*
Parser
)
parseSimpleSt
mt
()
ast
.
Stm
t
{
if
P
.
trace
{
defer
un
(
trace
(
P
,
"SimpleSt
a
t"
));
defer
un
(
trace
(
P
,
"SimpleSt
m
t"
));
}
x
:=
P
.
parseExpressionList
();
...
...
@@ -1119,86 +1125,85 @@ func (P *Parser) parseSimpleStat() ast.Stat {
P
.
expect
(
token
.
COLON
);
if
len
(
x
)
==
1
{
if
label
,
is_ident
:=
x
[
0
]
.
(
*
ast
.
Ident
);
is_ident
{
return
&
ast
.
LabeledSt
a
t
{
label
,
P
.
parseStatement
()};
return
&
ast
.
LabeledSt
m
t
{
label
,
P
.
parseStatement
()};
}
}
P
.
error
(
x
[
0
]
.
Pos
(),
"illegal label declaration"
);
return
nil
;
return
&
ast
.
BadStmt
{
x
[
0
]
.
Pos
()}
;
case
token
.
DEFINE
,
token
.
ASSIGN
,
token
.
ADD_ASSIGN
,
token
.
SUB_ASSIGN
,
token
.
MUL_ASSIGN
,
token
.
QUO_ASSIGN
,
token
.
REM_ASSIGN
,
token
.
AND_ASSIGN
,
token
.
OR_ASSIGN
,
token
.
XOR_ASSIGN
,
token
.
SHL_ASSIGN
,
token
.
SHR_ASSIGN
:
// assignment statement
or range clause
// assignment statement
pos
,
tok
:=
P
.
pos
,
P
.
tok
;
P
.
next
();
/*
if mode & range_ok != 0 && P.tok == token.RANGE {
// range clause
P.next();
if len(x) != 1 && len(x) != 2 {
P.error(x[0].Pos(), "expected 1 or 2 expressions on lhs of range clause");
}
if tok != token.DEFINE && tok != token.ASSIGN {
P.error(pos, "expected '=' or ':=', found '" + token.TokenString(tok) + "'");
}
y := P.parseExpression(1);
return &ast.RangeClause{x, pos, tok, y};
} else {
*/
// assignment statement
y
:=
P
.
parseExpressionList
();
xl
,
yl
:=
len
(
x
),
len
(
y
);
if
xl
>
1
&&
yl
>
1
&&
xl
!=
yl
{
P
.
error
(
x
[
0
]
.
Pos
(),
"arity of lhs doesn't match rhs"
);
// TODO use better loc for error
if
len
(
x
)
>
1
&&
len
(
y
)
>
1
&&
len
(
x
)
!=
len
(
y
)
{
P
.
error
(
x
[
0
]
.
Pos
(),
"arity of lhs doesn't match rhs"
);
}
return
&
ast
.
AssignStmt
{
x
,
pos
,
tok
,
y
};
}
return
&
ast
.
AssignmentStat
{
x
,
pos
,
tok
,
y
};
default
:
if
len
(
x
)
>
1
{
P
.
error
(
x
[
0
]
.
Pos
(),
"only one expression allowed"
);
// continue with first expression
}
if
P
.
tok
==
token
.
INC
||
P
.
tok
==
token
.
DEC
{
s
:=
&
ast
.
IncDecStat
{
x
[
0
],
P
.
tok
};
// increment or decrement
s
:=
&
ast
.
IncDecStmt
{
x
[
0
],
P
.
tok
};
P
.
next
();
// consume "++" or "--"
return
s
;
}
return
&
ast
.
ExprStat
{
x
[
0
]};
}
// expression
return
&
ast
.
ExprStmt
{
x
[
0
]};
}
unreachable
();
func
(
P
*
Parser
)
parseCallExpr
()
*
ast
.
CallExpr
{
x
:=
P
.
parseExpression
(
1
);
if
call
,
is_call
:=
x
.
(
*
ast
.
CallExpr
);
is_call
{
return
call
;
}
P
.
error
(
x
.
Pos
(),
"expected function/method call"
);
return
nil
;
}
func
(
P
*
Parser
)
parseGoSt
at
()
*
ast
.
GoSta
t
{
func
(
P
*
Parser
)
parseGoSt
mt
()
ast
.
Stm
t
{
if
P
.
trace
{
defer
un
(
trace
(
P
,
"GoSt
a
t"
));
defer
un
(
trace
(
P
,
"GoSt
m
t"
));
}
pos
:=
P
.
expect
(
token
.
GO
);
call
:=
P
.
parseExpression
(
1
);
return
&
ast
.
GoStat
{
pos
,
call
};
call
:=
P
.
parseCallExpr
();
if
call
!=
nil
{
return
&
ast
.
GoStmt
{
pos
,
call
};
}
return
&
ast
.
BadStmt
{
pos
};
}
func
(
P
*
Parser
)
parseDeferSt
at
()
*
ast
.
DeferSta
t
{
func
(
P
*
Parser
)
parseDeferSt
mt
()
ast
.
Stm
t
{
if
P
.
trace
{
defer
un
(
trace
(
P
,
"DeferSt
a
t"
));
defer
un
(
trace
(
P
,
"DeferSt
m
t"
));
}
pos
:=
P
.
expect
(
token
.
DEFER
);
call
:=
P
.
parseExpression
(
1
);
return
&
ast
.
DeferStat
{
pos
,
call
};
call
:=
P
.
parseCallExpr
();
if
call
!=
nil
{
return
&
ast
.
DeferStmt
{
pos
,
call
};
}
return
&
ast
.
BadStmt
{
pos
};
}
func
(
P
*
Parser
)
parseReturnSt
at
()
*
ast
.
ReturnSta
t
{
func
(
P
*
Parser
)
parseReturnSt
mt
()
*
ast
.
ReturnStm
t
{
if
P
.
trace
{
defer
un
(
trace
(
P
,
"ReturnSt
a
t"
));
defer
un
(
trace
(
P
,
"ReturnSt
m
t"
));
}
loc
:=
P
.
pos
;
...
...
@@ -1208,16 +1213,16 @@ func (P *Parser) parseReturnStat() *ast.ReturnStat {
x
=
P
.
parseExpressionList
();
}
return
&
ast
.
ReturnSt
a
t
{
loc
,
x
};
return
&
ast
.
ReturnSt
m
t
{
loc
,
x
};
}
func
(
P
*
Parser
)
parse
ControlFlowStat
(
tok
int
)
*
ast
.
ControlFlowSta
t
{
func
(
P
*
Parser
)
parse
BranchStmt
(
tok
int
)
*
ast
.
BranchStm
t
{
if
P
.
trace
{
defer
un
(
trace
(
P
,
"
ControlFlowSta
t"
));
defer
un
(
trace
(
P
,
"
BranchStm
t"
));
}
s
:=
&
ast
.
ControlFlowSta
t
{
P
.
pos
,
tok
,
nil
};
s
:=
&
ast
.
BranchStm
t
{
P
.
pos
,
tok
,
nil
};
P
.
expect
(
tok
);
if
tok
!=
token
.
FALLTHROUGH
&&
P
.
tok
==
token
.
IDENT
{
s
.
Label
=
P
.
parseIdent
();
...
...
@@ -1227,33 +1232,28 @@ func (P *Parser) parseControlFlowStat(tok int) *ast.ControlFlowStat {
}
/*
func (P *Parser) asIdent(x ast.Expr) *ast.Ident {
if name, ok := x.(*ast.Ident); ok {
return name;
func
(
P
*
Parser
)
isExpr
(
s
ast
.
Stmt
)
bool
{
if
s
==
nil
{
return
true
;
}
P.error(x.Pos(), "identifier expected"
);
return
&ast.Ident{x.Pos(), [...]byte{'B', 'A', 'D'}}
;
dummy
,
is_expr
:=
s
.
(
*
ast
.
ExprStmt
);
return
is_expr
;
}
func (P *Parser) isTypeSwitch(init ast.Stat) (lhs *ast.Ident, rhs ast.Expr) {
if assign, ok := init.(*ast.AssignmentStat); ok {
if guard, ok := assign.Rhs.(*ast.TypeAssertion); ok {
if tmp, ok := guard.Typ.(*ast.TypeType); ok {
// we appear to have a type switch
// TODO various error checks
return P.asIdent(assign.Lhs), guard.X;
}
func
(
P
*
Parser
)
asExpr
(
s
ast
.
Stmt
)
ast
.
Expr
{
if
s
==
nil
{
return
nil
;
}
if
es
,
is_expr
:=
s
.
(
*
ast
.
ExprStmt
);
is_expr
{
return
es
.
X
;
}
return nil, nil;
P
.
error
(
s
.
Pos
(),
"condition expected; found simple statement"
);
return
&
ast
.
BadExpr
{
s
.
Pos
()};
}
*/
func
(
P
*
Parser
)
parseControlClause
(
isForStat
bool
)
(
s1
,
s2
,
s3
ast
.
Stat
)
{
func
(
P
*
Parser
)
parseControlClause
(
isForStmt
bool
)
(
s1
,
s2
,
s3
ast
.
Stmt
)
{
if
P
.
trace
{
defer
un
(
trace
(
P
,
"ControlClause"
));
}
...
...
@@ -1263,18 +1263,18 @@ func (P *Parser) parseControlClause(isForStat bool) (s1, s2, s3 ast.Stat) {
P
.
expr_lev
=
-
1
;
if
P
.
tok
!=
token
.
SEMICOLON
{
s1
=
P
.
parseSimpleSt
a
t
();
s1
=
P
.
parseSimpleSt
m
t
();
}
if
P
.
tok
==
token
.
SEMICOLON
{
P
.
next
();
if
P
.
tok
!=
token
.
LBRACE
&&
P
.
tok
!=
token
.
SEMICOLON
{
s2
=
P
.
parseSimpleSt
a
t
();
s2
=
P
.
parseSimpleSt
m
t
();
}
if
isForSt
a
t
{
if
isForSt
m
t
{
// for statements have a 3rd section
P
.
expect
(
token
.
SEMICOLON
);
if
P
.
tok
!=
token
.
LBRACE
{
s3
=
P
.
parseSimpleSt
a
t
();
s3
=
P
.
parseSimpleSt
m
t
();
}
}
}
else
{
...
...
@@ -1288,42 +1288,21 @@ func (P *Parser) parseControlClause(isForStat bool) (s1, s2, s3 ast.Stat) {
}
func
(
P
*
Parser
)
isExpr
(
s
ast
.
Stat
)
bool
{
if
s
==
nil
{
return
true
;
}
dummy
,
is_expr
:=
s
.
(
*
ast
.
ExprStat
);
return
is_expr
;
}
func
(
P
*
Parser
)
asExpr
(
s
ast
.
Stat
)
ast
.
Expr
{
if
s
==
nil
{
return
nil
;
}
if
es
,
is_expr
:=
s
.
(
*
ast
.
ExprStat
);
is_expr
{
return
es
.
X
;
}
P
.
error
(
s
.
Pos
(),
"condition expected; found simple statement"
);
return
&
ast
.
BadExpr
{
s
.
Pos
()};
}
func
(
P
*
Parser
)
parseIfStat
()
*
ast
.
IfStat
{
func
(
P
*
Parser
)
parseIfStmt
()
*
ast
.
IfStmt
{
if
P
.
trace
{
defer
un
(
trace
(
P
,
"IfSt
a
t"
));
defer
un
(
trace
(
P
,
"IfSt
m
t"
));
}
pos
:=
P
.
expect
(
token
.
IF
);
s1
,
s2
,
dummy
:=
P
.
parseControlClause
(
false
);
body
:=
P
.
parseBlock
(
token
.
LBRACE
);
var
else_
ast
.
St
a
t
;
body
:=
P
.
parseBlock
Stmt
(
);
var
else_
ast
.
St
m
t
;
if
P
.
tok
==
token
.
ELSE
{
P
.
next
();
else_
=
P
.
parseStatement
();
}
return
&
ast
.
IfSt
a
t
{
pos
,
s1
,
P
.
asExpr
(
s2
),
body
,
else_
};
return
&
ast
.
IfSt
m
t
{
pos
,
s1
,
P
.
asExpr
(
s2
),
body
,
else_
};
}
...
...
@@ -1342,7 +1321,10 @@ func (P *Parser) parseCaseClause() *ast.CaseClause {
P
.
expect
(
token
.
DEFAULT
);
}
return
&
ast
.
CaseClause
{
loc
,
x
,
P
.
parseBlock
(
token
.
COLON
)};
colon
:=
P
.
expect
(
token
.
COLON
);
body
:=
P
.
parseStatementList
();
return
&
ast
.
CaseClause
{
loc
,
x
,
colon
,
body
};
}
...
...
@@ -1361,13 +1343,16 @@ func (P *Parser) parseTypeCaseClause() *ast.TypeCaseClause {
P
.
expect
(
token
.
DEFAULT
);
}
return
&
ast
.
TypeCaseClause
{
pos
,
typ
,
P
.
parseBlock
(
token
.
COLON
)};
colon
:=
P
.
expect
(
token
.
COLON
);
body
:=
P
.
parseStatementList
();
return
&
ast
.
TypeCaseClause
{
pos
,
typ
,
colon
,
body
};
}
func
(
P
*
Parser
)
parseSwitchSt
at
()
ast
.
Sta
t
{
func
(
P
*
Parser
)
parseSwitchSt
mt
()
ast
.
Stm
t
{
if
P
.
trace
{
defer
un
(
trace
(
P
,
"SwitchSt
a
t"
));
defer
un
(
trace
(
P
,
"SwitchSt
m
t"
));
}
pos
:=
P
.
expect
(
token
.
SWITCH
);
...
...
@@ -1382,8 +1367,8 @@ func (P *Parser) parseSwitchStat() ast.Stat {
}
rbrace
:=
P
.
expect
(
token
.
RBRACE
);
P
.
opt_semi
=
true
;
body
:=
&
ast
.
Block
{
lbrace
,
token
.
LBRACE
,
asSta
tList
(
cases
),
rbrace
};
return
&
ast
.
SwitchSt
a
t
{
pos
,
s1
,
P
.
asExpr
(
s2
),
body
};
body
:=
&
ast
.
Block
Stmt
{
lbrace
,
asStm
tList
(
cases
),
rbrace
};
return
&
ast
.
SwitchSt
m
t
{
pos
,
s1
,
P
.
asExpr
(
s2
),
body
};
}
else
{
// type switch
...
...
@@ -1395,8 +1380,8 @@ func (P *Parser) parseSwitchStat() ast.Stat {
}
rbrace
:=
P
.
expect
(
token
.
RBRACE
);
P
.
opt_semi
=
true
;
body
:=
&
ast
.
Block
{
lbrace
,
token
.
LBRACE
,
asSta
tList
(
cases
),
rbrace
};
return
&
ast
.
TypeSwitchSt
a
t
{
pos
,
s1
,
s2
,
body
};
body
:=
&
ast
.
Block
Stmt
{
lbrace
,
asStm
tList
(
cases
),
rbrace
};
return
&
ast
.
TypeSwitchSt
m
t
{
pos
,
s1
,
s2
,
body
};
}
unreachable
();
...
...
@@ -1438,13 +1423,16 @@ func (P *Parser) parseCommClause() *ast.CommClause {
P
.
expect
(
token
.
DEFAULT
);
}
return
&
ast
.
CommClause
{
loc
,
tok
,
lhs
,
rhs
,
P
.
parseBlock
(
token
.
COLON
)};
colon
:=
P
.
expect
(
token
.
COLON
);
body
:=
P
.
parseStatementList
();
return
&
ast
.
CommClause
{
loc
,
tok
,
lhs
,
rhs
,
colon
,
body
};
}
func
(
P
*
Parser
)
parseSelectSt
at
()
*
ast
.
SelectSta
t
{
func
(
P
*
Parser
)
parseSelectSt
mt
()
*
ast
.
SelectStm
t
{
if
P
.
trace
{
defer
un
(
trace
(
P
,
"SelectSt
a
t"
));
defer
un
(
trace
(
P
,
"SelectSt
m
t"
));
}
pos
:=
P
.
expect
(
token
.
SELECT
);
...
...
@@ -1455,28 +1443,54 @@ func (P *Parser) parseSelectStat() *ast.SelectStat {
}
rbrace
:=
P
.
expect
(
token
.
RBRACE
);
P
.
opt_semi
=
true
;
body
:=
&
ast
.
Block
{
lbrace
,
token
.
LBRACE
,
asSta
tList
(
cases
),
rbrace
};
body
:=
&
ast
.
Block
Stmt
{
lbrace
,
asStm
tList
(
cases
),
rbrace
};
return
&
ast
.
SelectSt
a
t
{
pos
,
body
};
return
&
ast
.
SelectSt
m
t
{
pos
,
body
};
}
func
(
P
*
Parser
)
parseForSt
at
()
ast
.
Sta
t
{
func
(
P
*
Parser
)
parseForSt
mt
()
ast
.
Stm
t
{
if
P
.
trace
{
defer
un
(
trace
(
P
,
"ForSt
a
t"
));
defer
un
(
trace
(
P
,
"ForSt
m
t"
));
}
pos
:=
P
.
expect
(
token
.
FOR
);
s1
,
s2
,
s3
:=
P
.
parseControlClause
(
true
);
body
:=
P
.
parseBlock
(
token
.
LBRACE
);
if
as
,
is_as
:=
s2
.
(
*
ast
.
AssignmentStat
);
is_as
{
// probably a for statement with a range clause
// TODO do all the checks!
return
&
ast
.
RangeStat
{
pos
,
s2
,
body
};
body
:=
P
.
parseBlockStmt
();
if
as
,
is_as
:=
s2
.
(
*
ast
.
AssignStmt
);
is_as
{
// possibly a for statement with a range clause; check assignment operator
if
as
.
Tok
!=
token
.
ASSIGN
&&
as
.
Tok
!=
token
.
DEFINE
{
P
.
error
(
as
.
Pos_
,
"'=' or ':=' expected"
);
return
&
ast
.
BadStmt
{
pos
};
}
// check lhs
var
key
,
value
ast
.
Expr
;
switch
len
(
as
.
Lhs
)
{
case
2
:
value
=
as
.
Lhs
[
1
];
fallthrough
;
case
1
:
key
=
as
.
Lhs
[
0
];
default
:
P
.
error
(
as
.
Lhs
[
0
]
.
Pos
(),
"expected 1 or 2 expressions"
);
return
&
ast
.
BadStmt
{
pos
};
}
// check rhs
if
len
(
as
.
Rhs
)
!=
1
{
P
.
error
(
as
.
Rhs
[
0
]
.
Pos
(),
"expected 1 expressions"
);
return
&
ast
.
BadStmt
{
pos
};
}
if
rhs
,
is_unary
:=
as
.
Rhs
[
0
]
.
(
*
ast
.
UnaryExpr
);
is_unary
&&
rhs
.
Tok
==
token
.
RANGE
{
// rhs is range expression; check lhs
return
&
ast
.
RangeStmt
{
pos
,
key
,
value
,
as
.
Pos_
,
as
.
Tok
,
rhs
.
X
,
body
}
}
else
{
P
.
error
(
s2
.
Pos
(),
"range clause expected"
);
return
&
ast
.
BadStmt
{
pos
};
}
}
else
{
// regular for statement
return
&
ast
.
ForSt
a
t
{
pos
,
s1
,
P
.
asExpr
(
s2
),
s3
,
body
};
return
&
ast
.
ForSt
m
t
{
pos
,
s1
,
P
.
asExpr
(
s2
),
s3
,
body
};
}
unreachable
();
...
...
@@ -1484,46 +1498,46 @@ func (P *Parser) parseForStat() ast.Stat {
}
func
(
P
*
Parser
)
parseStatement
()
ast
.
St
a
t
{
func
(
P
*
Parser
)
parseStatement
()
ast
.
St
m
t
{
if
P
.
trace
{
defer
un
(
trace
(
P
,
"Statement"
));
}
switch
P
.
tok
{
case
token
.
CONST
,
token
.
TYPE
,
token
.
VAR
:
return
&
ast
.
DeclSt
a
t
{
P
.
parseDeclaration
()};
return
&
ast
.
DeclSt
m
t
{
P
.
parseDeclaration
()};
case
// tokens that may start a top-level expression
token
.
IDENT
,
token
.
INT
,
token
.
FLOAT
,
token
.
CHAR
,
token
.
STRING
,
token
.
FUNC
,
token
.
LPAREN
,
// operand
token
.
LBRACK
,
token
.
STRUCT
,
// composite type
token
.
MUL
,
token
.
AND
,
token
.
ARROW
:
// unary operators
return
P
.
parseSimpleSt
a
t
();
return
P
.
parseSimpleSt
m
t
();
case
token
.
GO
:
return
P
.
parseGoSt
a
t
();
return
P
.
parseGoSt
m
t
();
case
token
.
DEFER
:
return
P
.
parseDeferSt
a
t
();
return
P
.
parseDeferSt
m
t
();
case
token
.
RETURN
:
return
P
.
parseReturnSt
a
t
();
return
P
.
parseReturnSt
m
t
();
case
token
.
BREAK
,
token
.
CONTINUE
,
token
.
GOTO
,
token
.
FALLTHROUGH
:
return
P
.
parse
ControlFlowSta
t
(
P
.
tok
);
return
P
.
parse
BranchStm
t
(
P
.
tok
);
case
token
.
LBRACE
:
return
&
ast
.
CompositeStat
{
P
.
parseBlock
(
token
.
LBRACE
)}
;
return
P
.
parseBlockStmt
()
;
case
token
.
IF
:
return
P
.
parseIfSt
a
t
();
return
P
.
parseIfSt
m
t
();
case
token
.
FOR
:
return
P
.
parseForSt
a
t
();
return
P
.
parseForSt
m
t
();
case
token
.
SWITCH
:
return
P
.
parseSwitchSt
a
t
();
return
P
.
parseSwitchSt
m
t
();
case
token
.
SELECT
:
return
P
.
parseSelectSt
a
t
();
return
P
.
parseSelectSt
m
t
();
case
token
.
SEMICOLON
,
token
.
RBRACE
:
// don't consume the ";", it is the separator following the empty statement
return
&
ast
.
EmptySt
a
t
{
P
.
pos
};
return
&
ast
.
EmptySt
m
t
{
P
.
pos
};
}
// no statement found
P
.
error
(
P
.
pos
,
"statement expected"
);
return
&
ast
.
BadSt
a
t
{
P
.
pos
};
return
&
ast
.
BadSt
m
t
{
P
.
pos
};
}
...
...
@@ -1543,9 +1557,9 @@ func (P *Parser) parseImportSpec(pos Position, doc ast.Comments) *ast.ImportDecl
ident
=
P
.
parseIdent
();
}
var
path
*
ast
.
StringLit
;
var
path
[]
*
ast
.
StringLit
;
if
P
.
tok
==
token
.
STRING
{
path
=
P
.
parseStringLit
(
nil
);
path
=
P
.
parseStringLi
s
t
(
nil
);
}
else
{
P
.
expect
(
token
.
STRING
);
// use expect() error handling
}
...
...
@@ -1677,14 +1691,14 @@ func (P *Parser) parseFunctionDecl() *ast.FuncDecl {
}
ident
:=
P
.
parseIdent
();
sig
:=
P
.
parseSignature
();
params
,
results
:=
P
.
parseSignature
();
var
body
*
ast
.
Block
;
var
body
*
ast
.
Block
Stmt
;
if
P
.
tok
==
token
.
LBRACE
{
body
=
P
.
parseBlock
(
token
.
LBRACE
);
body
=
P
.
parseBlock
Stmt
(
);
}
return
&
ast
.
FuncDecl
{
doc
,
pos
,
recv
,
ident
,
sig
,
body
};
return
&
ast
.
FuncDecl
{
doc
,
recv
,
ident
,
&
ast
.
FunctionType
{
pos
,
params
,
results
}
,
body
};
}
...
...
usr/gri/pretty/printer.go
View file @
ba620d50
...
...
@@ -486,7 +486,7 @@ func (P *Printer) Parameters(list []*ast.Field) {
if
n
>
0
{
P
.
separator
=
blank
};
P
.
Expr
(
par
.
Typ
);
P
.
Expr
(
par
.
Typ
e
);
}
}
P
.
Token
(
nopos
,
token
.
RPAREN
);
...
...
@@ -495,22 +495,22 @@ func (P *Printer) Parameters(list []*ast.Field) {
// Returns the separator (semicolon or none) required if
// the type is terminating a declaration or statement.
func
(
P
*
Printer
)
Signature
(
sig
*
ast
.
Signature
)
{
P
.
Parameters
(
sig
.
P
arams
);
if
sig
.
R
esult
!=
nil
{
func
(
P
*
Printer
)
Signature
(
params
,
result
[]
*
ast
.
Field
)
{
P
.
Parameters
(
p
arams
);
if
r
esult
!=
nil
{
P
.
separator
=
blank
;
if
len
(
sig
.
Result
)
==
1
&&
sig
.
R
esult
[
0
]
.
Names
==
nil
{
if
len
(
result
)
==
1
&&
r
esult
[
0
]
.
Names
==
nil
{
// single anonymous result
// => no parentheses needed unless it's a function type
fld
:=
sig
.
R
esult
[
0
];
if
dummy
,
is_ftyp
:=
fld
.
Typ
.
(
*
ast
.
FunctionType
);
!
is_ftyp
{
P
.
Expr
(
fld
.
Typ
);
fld
:=
r
esult
[
0
];
if
dummy
,
is_ftyp
:=
fld
.
Typ
e
.
(
*
ast
.
FunctionType
);
!
is_ftyp
{
P
.
Expr
(
fld
.
Typ
e
);
return
;
}
}
P
.
Parameters
(
sig
.
R
esult
);
P
.
Parameters
(
r
esult
);
}
}
...
...
@@ -535,16 +535,16 @@ func (P *Printer) Fields(lbrace scanner.Location, list []*ast.Field, rbrace scan
if
n
>
0
||
len
(
fld
.
Names
)
==
0
{
// at least one identifier or anonymous field
if
is_interface
{
if
ftyp
,
is_ftyp
:=
fld
.
Typ
.
(
*
ast
.
FunctionType
);
is_ftyp
{
P
.
Signature
(
ftyp
.
Sig
);
if
ftyp
,
is_ftyp
:=
fld
.
Typ
e
.
(
*
ast
.
FunctionType
);
is_ftyp
{
P
.
Signature
(
ftyp
.
Params
,
ftyp
.
Results
);
}
else
{
P
.
Expr
(
fld
.
Typ
);
P
.
Expr
(
fld
.
Typ
e
);
}
}
else
{
P
.
Expr
(
fld
.
Typ
);
P
.
Expr
(
fld
.
Typ
e
);
if
fld
.
Tag
!=
nil
{
P
.
separator
=
tab
;
P
.
Expr
(
fld
.
Tag
);
P
.
Expr
(
&
ast
.
StringList
{
fld
.
Tag
}
);
}
}
}
...
...
@@ -561,8 +561,8 @@ func (P *Printer) Fields(lbrace scanner.Location, list []*ast.Field, rbrace scan
// ----------------------------------------------------------------------------
// Expressions
func
(
P
*
Printer
)
Block
(
b
*
ast
.
Block
,
indent
bool
)
func
(
P
*
Printer
)
Expr1
(
x
ast
.
Expr
,
prec1
int
)
func
(
P
*
Printer
)
Stmt
(
s
ast
.
Stmt
)
func
(
P
*
Printer
)
DoBadExpr
(
x
*
ast
.
BadExpr
)
{
...
...
@@ -613,27 +613,46 @@ func (P *Printer) DoUnaryExpr(x *ast.UnaryExpr) {
}
func
(
P
*
Printer
)
DoBasicLit
(
x
*
ast
.
BasicLit
)
{
func
(
P
*
Printer
)
DoIntLit
(
x
*
ast
.
IntLit
)
{
// TODO get rid of string conversion here
P
.
String
(
x
.
Pos_
,
string
(
x
.
Lit
));
}
func
(
P
*
Printer
)
DoFloatLit
(
x
*
ast
.
FloatLit
)
{
// TODO get rid of string conversion here
P
.
String
(
x
.
Pos_
,
string
(
x
.
Lit
));
}
func
(
P
*
Printer
)
DoCharLit
(
x
*
ast
.
CharLit
)
{
// TODO get rid of string conversion here
P
.
String
(
x
.
Pos_
,
string
(
x
.
Lit
));
}
func
(
P
*
Printer
)
DoStringLit
(
x
*
ast
.
StringLit
)
{
// TODO get rid of string conversion here
P
.
String
(
x
.
Pos_
,
string
(
x
.
Lit
));
}
func
(
P
*
Printer
)
DoStringList
(
x
*
ast
.
StringList
)
{
for
i
,
x
:=
range
x
.
Strings
{
if
i
>
0
{
P
.
separator
=
blank
;
}
P
.
Do
Basic
Lit
(
x
);
P
.
Do
String
Lit
(
x
);
}
}
func
(
P
*
Printer
)
DoFunctionType
(
x
*
ast
.
FunctionType
)
func
(
P
*
Printer
)
DoFunctionLit
(
x
*
ast
.
FunctionLit
)
{
P
.
Token
(
x
.
Func
,
token
.
FUNC
);
P
.
Signature
(
x
.
Typ
);
P
.
DoFunctionType
(
x
.
Type
);
P
.
separator
=
blank
;
P
.
Block
(
x
.
Body
,
true
);
P
.
Stmt
(
x
.
Body
);
P
.
newlines
=
0
;
}
...
...
@@ -656,7 +675,7 @@ func (P *Printer) DoTypeAssertExpr(x *ast.TypeAssertExpr) {
P
.
Expr1
(
x
.
X
,
token
.
HighestPrec
);
P
.
Token
(
nopos
,
token
.
PERIOD
);
P
.
Token
(
nopos
,
token
.
LPAREN
);
P
.
Expr
(
x
.
Typ
);
P
.
Expr
(
x
.
Typ
e
);
P
.
Token
(
nopos
,
token
.
RPAREN
);
}
...
...
@@ -688,7 +707,7 @@ func (P *Printer) DoCallExpr(x *ast.CallExpr) {
func
(
P
*
Printer
)
DoCompositeLit
(
x
*
ast
.
CompositeLit
)
{
P
.
Expr1
(
x
.
Typ
,
token
.
HighestPrec
);
P
.
Expr1
(
x
.
Typ
e
,
token
.
HighestPrec
);
P
.
Token
(
x
.
Lbrace
,
token
.
LBRACE
);
P
.
Exprs
(
x
.
Elts
);
P
.
Token
(
x
.
Rbrace
,
token
.
RBRACE
);
...
...
@@ -720,7 +739,7 @@ func (P *Printer) DoStructType(x *ast.StructType) {
func
(
P
*
Printer
)
DoFunctionType
(
x
*
ast
.
FunctionType
)
{
P
.
Token
(
x
.
Func
,
token
.
FUNC
);
P
.
Signature
(
x
.
Sig
);
P
.
Signature
(
x
.
Params
,
x
.
Results
);
}
...
...
@@ -784,51 +803,51 @@ func (P *Printer) Expr(x ast.Expr) {
// ----------------------------------------------------------------------------
// Statements
func
(
P
*
Printer
)
St
at
(
s
ast
.
Sta
t
)
{
func
(
P
*
Printer
)
St
mt
(
s
ast
.
Stm
t
)
{
s
.
Visit
(
P
);
}
func
(
P
*
Printer
)
DoBadSt
at
(
s
*
ast
.
BadSta
t
)
{
func
(
P
*
Printer
)
DoBadSt
mt
(
s
*
ast
.
BadStm
t
)
{
panic
();
}
func
(
P
*
Printer
)
Decl
(
d
ast
.
Decl
);
func
(
P
*
Printer
)
DoDeclSt
at
(
s
*
ast
.
DeclSta
t
)
{
func
(
P
*
Printer
)
DoDeclSt
mt
(
s
*
ast
.
DeclStm
t
)
{
P
.
Decl
(
s
.
Decl
);
}
func
(
P
*
Printer
)
DoEmptySt
at
(
s
*
ast
.
EmptySta
t
)
{
func
(
P
*
Printer
)
DoEmptySt
mt
(
s
*
ast
.
EmptyStm
t
)
{
P
.
String
(
s
.
Semicolon
,
""
);
}
func
(
P
*
Printer
)
DoLabeledSt
at
(
s
*
ast
.
LabeledSta
t
)
{
func
(
P
*
Printer
)
DoLabeledSt
mt
(
s
*
ast
.
LabeledStm
t
)
{
P
.
indentation
--
;
P
.
Expr
(
s
.
Label
);
P
.
Token
(
nopos
,
token
.
COLON
);
P
.
indentation
++
;
// TODO be more clever if s.St
a
t is a labeled stat as well
// TODO be more clever if s.St
m
t is a labeled stat as well
P
.
separator
=
tab
;
P
.
St
at
(
s
.
Sta
t
);
P
.
St
mt
(
s
.
Stm
t
);
}
func
(
P
*
Printer
)
DoExprSt
at
(
s
*
ast
.
ExprSta
t
)
{
func
(
P
*
Printer
)
DoExprSt
mt
(
s
*
ast
.
ExprStm
t
)
{
P
.
Expr
(
s
.
X
);
}
func
(
P
*
Printer
)
DoIncDecSt
at
(
s
*
ast
.
IncDecSta
t
)
{
func
(
P
*
Printer
)
DoIncDecSt
mt
(
s
*
ast
.
IncDecStm
t
)
{
P
.
Expr
(
s
.
X
);
P
.
Token
(
nopos
,
s
.
Tok
);
}
func
(
P
*
Printer
)
DoAssign
mentStat
(
s
*
ast
.
AssignmentSta
t
)
{
func
(
P
*
Printer
)
DoAssign
Stmt
(
s
*
ast
.
AssignStm
t
)
{
P
.
Exprs
(
s
.
Lhs
);
P
.
separator
=
blank
;
P
.
Token
(
s
.
Pos_
,
s
.
Tok
);
...
...
@@ -837,28 +856,28 @@ func (P *Printer) DoAssignmentStat(s *ast.AssignmentStat) {
}
func
(
P
*
Printer
)
DoGoSt
at
(
s
*
ast
.
GoSta
t
)
{
func
(
P
*
Printer
)
DoGoSt
mt
(
s
*
ast
.
GoStm
t
)
{
P
.
Token
(
s
.
Go
,
token
.
GO
);
P
.
separator
=
blank
;
P
.
Expr
(
s
.
Call
);
}
func
(
P
*
Printer
)
DoDeferSt
at
(
s
*
ast
.
DeferSta
t
)
{
func
(
P
*
Printer
)
DoDeferSt
mt
(
s
*
ast
.
DeferStm
t
)
{
P
.
Token
(
s
.
Defer
,
token
.
DEFER
);
P
.
separator
=
blank
;
P
.
Expr
(
s
.
Call
);
}
func
(
P
*
Printer
)
DoReturnSt
at
(
s
*
ast
.
ReturnSta
t
)
{
func
(
P
*
Printer
)
DoReturnSt
mt
(
s
*
ast
.
ReturnStm
t
)
{
P
.
Token
(
s
.
Return
,
token
.
RETURN
);
P
.
separator
=
blank
;
P
.
Exprs
(
s
.
Results
);
}
func
(
P
*
Printer
)
Do
ControlFlowStat
(
s
*
ast
.
ControlFlowSta
t
)
{
func
(
P
*
Printer
)
Do
BranchStmt
(
s
*
ast
.
BranchStm
t
)
{
P
.
Token
(
s
.
Pos_
,
s
.
Tok
);
if
s
.
Label
!=
nil
{
P
.
separator
=
blank
;
...
...
@@ -867,7 +886,8 @@ func (P *Printer) DoControlFlowStat(s *ast.ControlFlowStat) {
}
func
(
P
*
Printer
)
StatementList
(
list
[]
ast
.
Stat
)
{
func
(
P
*
Printer
)
StatementList
(
list
[]
ast
.
Stmt
)
{
if
list
!=
nil
{
for
i
,
s
:=
range
list
{
if
i
==
0
{
P
.
newlines
=
1
;
...
...
@@ -877,14 +897,16 @@ func (P *Printer) StatementList(list []ast.Stat) {
P
.
separator
=
semicolon
;
}
}
P
.
Sta
t
(
s
);
P
.
Stm
t
(
s
);
P
.
newlines
=
1
;
P
.
state
=
inside_list
;
}
}
}
func
(
P
*
Printer
)
Block
(
b
*
ast
.
Block
,
indent
bool
)
{
/*
func (P *Printer) Block(list []ast.Stmt, indent bool) {
P.state = opening_scope;
P.Token(b.Pos_, b.Tok);
if !indent {
...
...
@@ -899,20 +921,29 @@ func (P *Printer) Block(b *ast.Block, indent bool) {
}
P.state = closing_scope;
if b.Tok == token.LBRACE {
P
.
Token
(
b
.
R
paren
,
token
.
RBRACE
);
P.Token(b.R
brace
, token.RBRACE);
P.opt_semi = true;
} else {
P.String(nopos, ""); // process closing_scope state transition!
}
}
*/
func
(
P
*
Printer
)
DoCompositeStat
(
s
*
ast
.
CompositeStat
)
{
P
.
Block
(
s
.
Body
,
true
);
func
(
P
*
Printer
)
DoBlockStmt
(
s
*
ast
.
BlockStmt
)
{
P
.
state
=
opening_scope
;
P
.
Token
(
s
.
Lbrace
,
token
.
LBRACE
);
P
.
StatementList
(
s
.
List
);
if
!*
optsemicolons
{
P
.
separator
=
none
;
}
P
.
state
=
closing_scope
;
P
.
Token
(
s
.
Rbrace
,
token
.
RBRACE
);
P
.
opt_semi
=
true
;
}
func
(
P
*
Printer
)
ControlClause
(
isForSt
at
bool
,
init
ast
.
Stat
,
expr
ast
.
Expr
,
post
ast
.
Sta
t
)
{
func
(
P
*
Printer
)
ControlClause
(
isForSt
mt
bool
,
init
ast
.
Stmt
,
expr
ast
.
Expr
,
post
ast
.
Stm
t
)
{
P
.
separator
=
blank
;
if
init
==
nil
&&
post
==
nil
{
// no semicolons required
...
...
@@ -923,7 +954,7 @@ func (P *Printer) ControlClause(isForStat bool, init ast.Stat, expr ast.Expr, po
// all semicolons required
// (they are not separators, print them explicitly)
if
init
!=
nil
{
P
.
St
a
t
(
init
);
P
.
St
m
t
(
init
);
P
.
separator
=
none
;
}
P
.
Token
(
nopos
,
token
.
SEMICOLON
);
...
...
@@ -932,11 +963,11 @@ func (P *Printer) ControlClause(isForStat bool, init ast.Stat, expr ast.Expr, po
P
.
Expr
(
expr
);
P
.
separator
=
none
;
}
if
isForSt
a
t
{
if
isForSt
m
t
{
P
.
Token
(
nopos
,
token
.
SEMICOLON
);
P
.
separator
=
blank
;
if
post
!=
nil
{
P
.
St
a
t
(
post
);
P
.
St
m
t
(
post
);
}
}
}
...
...
@@ -944,15 +975,15 @@ func (P *Printer) ControlClause(isForStat bool, init ast.Stat, expr ast.Expr, po
}
func
(
P
*
Printer
)
DoIfSt
at
(
s
*
ast
.
IfSta
t
)
{
func
(
P
*
Printer
)
DoIfSt
mt
(
s
*
ast
.
IfStm
t
)
{
P
.
Token
(
s
.
If
,
token
.
IF
);
P
.
ControlClause
(
false
,
s
.
Init
,
s
.
Cond
,
nil
);
P
.
Block
(
s
.
Body
,
true
);
P
.
Stmt
(
s
.
Body
);
if
s
.
Else
!=
nil
{
P
.
separator
=
blank
;
P
.
Token
(
nopos
,
token
.
ELSE
);
P
.
separator
=
blank
;
P
.
St
a
t
(
s
.
Else
);
P
.
St
m
t
(
s
.
Else
);
}
}
...
...
@@ -965,53 +996,49 @@ func (P *Printer) DoCaseClause(s *ast.CaseClause) {
}
else
{
P
.
Token
(
s
.
Case
,
token
.
DEFAULT
);
}
// TODO: try to use P.Block instead
// P.Block(s.Body, true);
P
.
Token
(
s
.
Body
.
Pos_
,
token
.
COLON
);
P
.
Token
(
s
.
Colon
,
token
.
COLON
);
P
.
indentation
++
;
P
.
StatementList
(
s
.
Body
.
List
);
P
.
StatementList
(
s
.
Body
);
P
.
indentation
--
;
P
.
newlines
=
1
;
}
func
(
P
*
Printer
)
DoSwitchSt
at
(
s
*
ast
.
SwitchSta
t
)
{
func
(
P
*
Printer
)
DoSwitchSt
mt
(
s
*
ast
.
SwitchStm
t
)
{
P
.
Token
(
s
.
Switch
,
token
.
SWITCH
);
P
.
ControlClause
(
false
,
s
.
Init
,
s
.
Tag
,
nil
);
P
.
Block
(
s
.
Body
,
false
);
P
.
Stmt
(
s
.
Body
);
}
func
(
P
*
Printer
)
DoTypeCaseClause
(
s
*
ast
.
TypeCaseClause
)
{
if
s
.
Typ
!=
nil
{
if
s
.
Typ
e
!=
nil
{
P
.
Token
(
s
.
Case
,
token
.
CASE
);
P
.
separator
=
blank
;
P
.
Expr
(
s
.
Typ
);
P
.
Expr
(
s
.
Typ
e
);
}
else
{
P
.
Token
(
s
.
Case
,
token
.
DEFAULT
);
}
// TODO: try to use P.Block instead
// P.Block(s.Body, true);
P
.
Token
(
s
.
Body
.
Pos_
,
token
.
COLON
);
P
.
Token
(
s
.
Colon
,
token
.
COLON
);
P
.
indentation
++
;
P
.
StatementList
(
s
.
Body
.
List
);
P
.
StatementList
(
s
.
Body
);
P
.
indentation
--
;
P
.
newlines
=
1
;
}
func
(
P
*
Printer
)
DoTypeSwitchSt
at
(
s
*
ast
.
TypeSwitchSta
t
)
{
func
(
P
*
Printer
)
DoTypeSwitchSt
mt
(
s
*
ast
.
TypeSwitchStm
t
)
{
P
.
Token
(
s
.
Switch
,
token
.
SWITCH
);
P
.
separator
=
blank
;
if
s
.
Init
!=
nil
{
P
.
St
a
t
(
s
.
Init
);
P
.
St
m
t
(
s
.
Init
);
P
.
separator
=
none
;
P
.
Token
(
nopos
,
token
.
SEMICOLON
);
}
P
.
separator
=
blank
;
P
.
St
a
t
(
s
.
Assign
);
P
.
St
m
t
(
s
.
Assign
);
P
.
separator
=
blank
;
P
.
Block
(
s
.
Body
,
false
);
P
.
Stmt
(
s
.
Body
);
}
...
...
@@ -1029,36 +1056,46 @@ func (P *Printer) DoCommClause(s *ast.CommClause) {
}
else
{
P
.
Token
(
s
.
Case
,
token
.
DEFAULT
);
}
// TODO: try to use P.Block instead
// P.Block(s.Body, true);
P
.
Token
(
s
.
Body
.
Pos_
,
token
.
COLON
);
P
.
Token
(
s
.
Colon
,
token
.
COLON
);
P
.
indentation
++
;
P
.
StatementList
(
s
.
Body
.
List
);
P
.
StatementList
(
s
.
Body
);
P
.
indentation
--
;
P
.
newlines
=
1
;
}
func
(
P
*
Printer
)
DoSelectSt
at
(
s
*
ast
.
SelectSta
t
)
{
func
(
P
*
Printer
)
DoSelectSt
mt
(
s
*
ast
.
SelectStm
t
)
{
P
.
Token
(
s
.
Select
,
token
.
SELECT
);
P
.
separator
=
blank
;
P
.
Block
(
s
.
Body
,
false
);
P
.
Stmt
(
s
.
Body
);
}
func
(
P
*
Printer
)
DoForSt
at
(
s
*
ast
.
ForSta
t
)
{
func
(
P
*
Printer
)
DoForSt
mt
(
s
*
ast
.
ForStm
t
)
{
P
.
Token
(
s
.
For
,
token
.
FOR
);
P
.
ControlClause
(
true
,
s
.
Init
,
s
.
Cond
,
s
.
Post
);
P
.
Block
(
s
.
Body
,
true
);
P
.
Stmt
(
s
.
Body
);
}
func
(
P
*
Printer
)
DoRangeSt
at
(
s
*
ast
.
RangeSta
t
)
{
func
(
P
*
Printer
)
DoRangeSt
mt
(
s
*
ast
.
RangeStm
t
)
{
P
.
Token
(
s
.
For
,
token
.
FOR
);
P
.
separator
=
blank
;
P
.
Stat
(
s
.
Range
);
P
.
Expr
(
s
.
Key
);
if
s
.
Value
!=
nil
{
P
.
Token
(
nopos
,
token
.
COMMA
);
P
.
separator
=
blank
;
P
.
state
=
inside_list
;
P
.
Expr
(
s
.
Value
);
}
P
.
separator
=
blank
;
P
.
Token
(
s
.
Pos_
,
s
.
Tok
);
P
.
separator
=
blank
;
P
.
Token
(
nopos
,
token
.
RANGE
);
P
.
separator
=
blank
;
P
.
Expr
(
s
.
X
);
P
.
separator
=
blank
;
P
.
Block
(
s
.
Body
,
true
);
P
.
Stmt
(
s
.
Body
);
}
...
...
@@ -1078,14 +1115,14 @@ func (P *Printer) DoImportDecl(d *ast.ImportDecl) {
if
d
.
Name
!=
nil
{
P
.
Expr
(
d
.
Name
);
}
else
{
P
.
String
(
d
.
Path
.
Pos
(),
""
);
// flush pending ';' separator/newlines
P
.
String
(
d
.
Path
[
0
]
.
Pos
(),
""
);
// flush pending ';' separator/newlines
}
P
.
separator
=
tab
;
// TODO fix for longer package names
if
len
(
d
.
Path
.
Strings
)
>
1
{
if
len
(
d
.
Path
)
>
1
{
panic
();
}
P
.
HtmlPackageName
(
d
.
Path
.
Pos
(),
string
(
d
.
Path
.
Strings
[
0
]
.
Lit
));
P
.
HtmlPackageName
(
d
.
Path
[
0
]
.
Pos
(),
string
(
d
.
Path
[
0
]
.
Lit
));
P
.
newlines
=
2
;
}
...
...
@@ -1096,9 +1133,9 @@ func (P *Printer) DoConstDecl(d *ast.ConstDecl) {
P
.
separator
=
blank
;
}
P
.
Idents
(
d
.
Names
,
P
.
full
);
if
d
.
Typ
!=
nil
{
if
d
.
Typ
e
!=
nil
{
P
.
separator
=
blank
;
// TODO switch to tab? (indentation problem with structs)
P
.
Expr
(
d
.
Typ
);
P
.
Expr
(
d
.
Typ
e
);
}
if
d
.
Values
!=
nil
{
P
.
separator
=
tab
;
...
...
@@ -1111,13 +1148,13 @@ func (P *Printer) DoConstDecl(d *ast.ConstDecl) {
func
(
P
*
Printer
)
DoTypeDecl
(
d
*
ast
.
TypeDecl
)
{
if
d
.
Type
.
Pos
>
0
{
P
.
Token
(
d
.
Type
,
token
.
TYPE
);
if
d
.
Pos_
.
Pos
>
0
{
P
.
Token
(
d
.
Pos_
,
token
.
TYPE
);
P
.
separator
=
blank
;
}
P
.
Expr
(
d
.
Name
);
P
.
separator
=
blank
;
// TODO switch to tab? (but indentation problem with structs)
P
.
Expr
(
d
.
Typ
);
P
.
Expr
(
d
.
Typ
e
);
P
.
newlines
=
2
;
}
...
...
@@ -1128,10 +1165,10 @@ func (P *Printer) DoVarDecl(d *ast.VarDecl) {
P
.
separator
=
blank
;
}
P
.
Idents
(
d
.
Names
,
P
.
full
);
if
d
.
Typ
!=
nil
{
if
d
.
Typ
e
!=
nil
{
P
.
separator
=
blank
;
// TODO switch to tab? (indentation problem with structs)
P
.
Expr
(
d
.
Typ
);
//P.separator = P.Type(d.Typ);
P
.
Expr
(
d
.
Typ
e
);
//P.separator = P.Type(d.Typ
e
);
}
if
d
.
Values
!=
nil
{
P
.
separator
=
tab
;
...
...
@@ -1144,7 +1181,7 @@ func (P *Printer) DoVarDecl(d *ast.VarDecl) {
func
(
P
*
Printer
)
DoFuncDecl
(
d
*
ast
.
FuncDecl
)
{
P
.
Token
(
d
.
Func
,
token
.
FUNC
);
P
.
Token
(
d
.
Type
.
Func
,
token
.
FUNC
);
P
.
separator
=
blank
;
if
recv
:=
d
.
Recv
;
recv
!=
nil
{
// method: print receiver
...
...
@@ -1153,15 +1190,15 @@ func (P *Printer) DoFuncDecl(d *ast.FuncDecl) {
P
.
Expr
(
recv
.
Names
[
0
]);
P
.
separator
=
blank
;
}
P
.
Expr
(
recv
.
Typ
);
P
.
Expr
(
recv
.
Typ
e
);
P
.
Token
(
nopos
,
token
.
RPAREN
);
P
.
separator
=
blank
;
}
P
.
Expr
(
d
.
Name
);
P
.
Signature
(
d
.
Sig
);
P
.
Signature
(
d
.
Type
.
Params
,
d
.
Type
.
Results
);
if
P
.
full
&&
d
.
Body
!=
nil
{
P
.
separator
=
blank
;
P
.
Block
(
d
.
Body
,
true
);
P
.
Stmt
(
d
.
Body
);
}
P
.
newlines
=
3
;
}
...
...
@@ -1288,7 +1325,7 @@ func (P *Printer) Interface(p *ast.Package) {
if
isExported
(
d
.
Name
)
{
if
d
.
Recv
!=
nil
{
P
.
Printf
(
"<h3>func ("
);
P
.
Expr
(
d
.
Recv
.
Typ
);
P
.
Expr
(
d
.
Recv
.
Typ
e
);
P
.
Printf
(
") %s</h3>
\n
"
,
d
.
Name
.
Lit
);
}
else
{
P
.
Printf
(
"<h2>func %s</h2>
\n
"
,
d
.
Name
.
Lit
);
...
...
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