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
c9859e7b
Commit
c9859e7b
authored
Dec 12, 2008
by
Robert Griesemer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
- support for range clauses
R=r OCL=21030 CL=21030
parent
a3155bdb
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
93 additions
and
11 deletions
+93
-11
parser.go
usr/gri/pretty/parser.go
+45
-9
printer.go
usr/gri/pretty/printer.go
+3
-0
selftest2.go
usr/gri/pretty/selftest2.go
+45
-2
No files found.
usr/gri/pretty/parser.go
View file @
c9859e7b
...
@@ -971,12 +971,25 @@ func (P *Parser) ParseExpression(prec int) *AST.Expr {
...
@@ -971,12 +971,25 @@ func (P *Parser) ParseExpression(prec int) *AST.Expr {
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Statements
// Statements
func
(
P
*
Parser
)
ParseSimpleStat
()
*
AST
.
Stat
{
func
(
P
*
Parser
)
ParseSimpleStat
(
range_ok
bool
)
*
AST
.
Stat
{
P
.
Trace
(
"SimpleStat"
);
P
.
Trace
(
"SimpleStat"
);
s
:=
AST
.
BadStat
;
s
:=
AST
.
BadStat
;
x
:=
P
.
ParseExpressionList
();
x
:=
P
.
ParseExpressionList
();
is_range
:=
false
;
if
range_ok
&&
P
.
tok
==
Scanner
.
COLON
{
pos
:=
P
.
pos
;
P
.
Next
();
y
:=
P
.
ParseExpression
(
1
);
if
x
.
Len
()
==
1
{
x
=
P
.
NewExpr
(
pos
,
Scanner
.
COLON
,
x
,
y
);
is_range
=
true
;
}
else
{
P
.
Error
(
pos
,
"expected initialization, found ':'"
);
}
}
switch
P
.
tok
{
switch
P
.
tok
{
case
Scanner
.
COLON
:
case
Scanner
.
COLON
:
// label declaration
// label declaration
...
@@ -987,22 +1000,44 @@ func (P *Parser) ParseSimpleStat() *AST.Stat {
...
@@ -987,22 +1000,44 @@ func (P *Parser) ParseSimpleStat() *AST.Stat {
}
}
P
.
Next
();
// consume ":"
P
.
Next
();
// consume ":"
P
.
opt_semi
=
true
;
P
.
opt_semi
=
true
;
case
case
Scanner
.
DEFINE
,
Scanner
.
ASSIGN
,
Scanner
.
ADD_ASSIGN
,
Scanner
.
DEFINE
,
Scanner
.
ASSIGN
,
Scanner
.
ADD_ASSIGN
,
Scanner
.
SUB_ASSIGN
,
Scanner
.
MUL_ASSIGN
,
Scanner
.
QUO_ASSIGN
,
Scanner
.
SUB_ASSIGN
,
Scanner
.
MUL_ASSIGN
,
Scanner
.
QUO_ASSIGN
,
Scanner
.
REM_ASSIGN
,
Scanner
.
AND_ASSIGN
,
Scanner
.
OR_ASSIGN
,
Scanner
.
REM_ASSIGN
,
Scanner
.
AND_ASSIGN
,
Scanner
.
OR_ASSIGN
,
Scanner
.
XOR_ASSIGN
,
Scanner
.
SHL_ASSIGN
,
Scanner
.
SHR_ASSIGN
:
Scanner
.
XOR_ASSIGN
,
Scanner
.
SHL_ASSIGN
,
Scanner
.
SHR_ASSIGN
:
// assignment
//
declaration/
assignment
pos
,
tok
:=
P
.
pos
,
P
.
tok
;
pos
,
tok
:=
P
.
pos
,
P
.
tok
;
P
.
Next
();
P
.
Next
();
y
:=
P
.
ParseExpressionList
();
y
:=
AST
.
BadExpr
;
if
xl
,
yl
:=
x
.
Len
(),
y
.
Len
();
xl
>
1
&&
yl
>
1
&&
xl
!=
yl
{
if
P
.
tok
==
Scanner
.
RANGE
{
P
.
Error
(
x
.
pos
,
"arity of lhs doesn't match rhs"
);
range_pos
:=
P
.
pos
;
P
.
Next
();
y
=
P
.
ParseExpression
(
1
);
y
=
P
.
NewExpr
(
range_pos
,
Scanner
.
RANGE
,
nil
,
y
);
if
tok
!=
Scanner
.
DEFINE
&&
tok
!=
Scanner
.
ASSIGN
{
P
.
Error
(
pos
,
"expected '=' or ':=', found '"
+
Scanner
.
TokenString
(
tok
)
+
"'"
);
}
}
else
{
y
=
P
.
ParseExpressionList
();
if
is_range
{
P
.
Error
(
y
.
pos
,
"expected 'range', found expression"
);
}
if
xl
,
yl
:=
x
.
Len
(),
y
.
Len
();
xl
>
1
&&
yl
>
1
&&
xl
!=
yl
{
P
.
Error
(
x
.
pos
,
"arity of lhs doesn't match rhs"
);
}
}
}
s
=
AST
.
NewStat
(
x
.
pos
,
Scanner
.
EXPRSTAT
);
s
=
AST
.
NewStat
(
x
.
pos
,
Scanner
.
EXPRSTAT
);
s
.
expr
=
AST
.
NewExpr
(
pos
,
tok
,
x
,
y
);
s
.
expr
=
AST
.
NewExpr
(
pos
,
tok
,
x
,
y
);
case
Scanner
.
RANGE
:
pos
:=
P
.
pos
;
P
.
Next
();
y
:=
P
.
ParseExpression
(
1
);
y
=
P
.
NewExpr
(
pos
,
Scanner
.
RANGE
,
nil
,
y
);
s
=
AST
.
NewStat
(
x
.
pos
,
Scanner
.
EXPRSTAT
);
s
.
expr
=
AST
.
NewExpr
(
pos
,
Scanner
.
DEFINE
,
x
,
y
);
default
:
default
:
var
pos
,
tok
int
;
var
pos
,
tok
int
;
if
P
.
tok
==
Scanner
.
INC
||
P
.
tok
==
Scanner
.
DEC
{
if
P
.
tok
==
Scanner
.
INC
||
P
.
tok
==
Scanner
.
DEC
{
...
@@ -1072,7 +1107,8 @@ func (P *Parser) ParseControlClause(keyword int) *AST.Stat {
...
@@ -1072,7 +1107,8 @@ func (P *Parser) ParseControlClause(keyword int) *AST.Stat {
prev_lev
:=
P
.
expr_lev
;
prev_lev
:=
P
.
expr_lev
;
P
.
expr_lev
=
-
1
;
P
.
expr_lev
=
-
1
;
if
P
.
tok
!=
Scanner
.
SEMICOLON
{
if
P
.
tok
!=
Scanner
.
SEMICOLON
{
s
.
init
=
P
.
ParseSimpleStat
();
s
.
init
=
P
.
ParseSimpleStat
(
keyword
==
Scanner
.
FOR
);
// TODO check for range clause and exit if found
}
}
if
P
.
tok
==
Scanner
.
SEMICOLON
{
if
P
.
tok
==
Scanner
.
SEMICOLON
{
P
.
Next
();
P
.
Next
();
...
@@ -1082,7 +1118,7 @@ func (P *Parser) ParseControlClause(keyword int) *AST.Stat {
...
@@ -1082,7 +1118,7 @@ func (P *Parser) ParseControlClause(keyword int) *AST.Stat {
if
keyword
==
Scanner
.
FOR
{
if
keyword
==
Scanner
.
FOR
{
P
.
Expect
(
Scanner
.
SEMICOLON
);
P
.
Expect
(
Scanner
.
SEMICOLON
);
if
P
.
tok
!=
Scanner
.
LBRACE
{
if
P
.
tok
!=
Scanner
.
LBRACE
{
s
.
post
=
P
.
ParseSimpleStat
();
s
.
post
=
P
.
ParseSimpleStat
(
false
);
}
}
}
}
}
else
{
}
else
{
...
@@ -1284,7 +1320,7 @@ func (P *Parser) ParseStatement() *AST.Stat {
...
@@ -1284,7 +1320,7 @@ func (P *Parser) ParseStatement() *AST.Stat {
Scanner
.
IDENT
,
Scanner
.
INT
,
Scanner
.
FLOAT
,
Scanner
.
STRING
,
Scanner
.
LPAREN
,
// operand
Scanner
.
IDENT
,
Scanner
.
INT
,
Scanner
.
FLOAT
,
Scanner
.
STRING
,
Scanner
.
LPAREN
,
// operand
Scanner
.
LBRACK
,
Scanner
.
STRUCT
,
// composite type
Scanner
.
LBRACK
,
Scanner
.
STRUCT
,
// composite type
Scanner
.
MUL
,
Scanner
.
AND
,
Scanner
.
ARROW
:
// unary
Scanner
.
MUL
,
Scanner
.
AND
,
Scanner
.
ARROW
:
// unary
s
=
P
.
ParseSimpleStat
();
s
=
P
.
ParseSimpleStat
(
false
);
case
Scanner
.
GO
:
case
Scanner
.
GO
:
s
=
P
.
ParseGoStat
();
s
=
P
.
ParseGoStat
();
case
Scanner
.
RETURN
:
case
Scanner
.
RETURN
:
...
...
usr/gri/pretty/printer.go
View file @
c9859e7b
...
@@ -582,6 +582,9 @@ func (P *Printer) Expr1(x *AST.Expr, prec1 int) {
...
@@ -582,6 +582,9 @@ func (P *Printer) Expr1(x *AST.Expr, prec1 int) {
if
x
.
x
==
nil
{
if
x
.
x
==
nil
{
// unary expression
// unary expression
P
.
Token
(
x
.
pos
,
x
.
tok
);
P
.
Token
(
x
.
pos
,
x
.
tok
);
if
x
.
tok
==
Scanner
.
RANGE
{
P
.
separator
=
blank
;
}
}
else
{
}
else
{
// binary expression
// binary expression
P
.
Expr1
(
x
.
x
,
prec
);
P
.
Expr1
(
x
.
x
,
prec
);
...
...
usr/gri/pretty/selftest2.go
View file @
c9859e7b
...
@@ -11,7 +11,7 @@ import (
...
@@ -11,7 +11,7 @@ import (
)
)
const
/* enum */
(
const
/* enum
1
*/
(
EnumTag0
=
iota
;
EnumTag0
=
iota
;
EnumTag1
;
EnumTag1
;
EnumTag2
;
EnumTag2
;
...
@@ -25,6 +25,13 @@ const /* enum */ (
...
@@ -25,6 +25,13 @@ const /* enum */ (
)
)
const
/* enum2 */
(
a
,
b
=
iota
*
2
+
1
,
iota
*
2
;
c
,
d
;
e
,
f
;
)
type
S
struct
{}
type
S
struct
{}
...
@@ -37,7 +44,7 @@ type T struct {
...
@@ -37,7 +44,7 @@ type T struct {
var
(
var
(
A
=
5
;
A
=
5
;
a
,
b
,
c
int
=
0
,
0
,
0
;
u
,
v
,
w
int
=
0
,
0
,
0
;
foo
=
"foo"
;
foo
=
"foo"
;
)
)
...
@@ -66,6 +73,41 @@ func f2(tag int) {
...
@@ -66,6 +73,41 @@ func f2(tag int) {
}
}
func
f3
(
a
*
[]
int
,
m
*
map
[
string
]
int
)
{
println
(
"A1"
);
for
i
:=
range
a
{
println
(
i
);
}
println
(
"A2"
);
for
i
,
x
:=
range
a
{
println
(
i
,
x
);
}
println
(
"A3"
);
for
i
:
x
:=
range
a
{
println
(
i
,
x
);
}
println
(
"M1"
);
for
i
range
m
{
println
(
i
);
}
println
(
"M2"
);
for
i
,
x
range
m
{
println
(
i
,
x
);
}
println
(
"M3"
);
var
i
string
;
var
x
int
;
for
i
:
x
=
range
m
{
println
(
i
,
x
);
}
}
func
main
()
{
func
main
()
{
// the prologue
// the prologue
for
i
:=
0
;
i
<=
10
/* limit */
;
i
++
{
for
i
:=
0
;
i
<=
10
/* limit */
;
i
++
{
...
@@ -74,6 +116,7 @@ func main() {
...
@@ -74,6 +116,7 @@ func main() {
println
(
i
+
1000
);
// the index + 1000
println
(
i
+
1000
);
// the index + 1000
println
();
println
();
}
}
f3
(
&
[]
int
{
2
,
3
,
5
,
7
},
map
[
string
]
int
{
"two"
:
2
,
"three"
:
3
,
"five"
:
5
,
"seven"
:
7
});
// the epilogue
// the epilogue
println
(
"foo"
);
// foo
println
(
"foo"
);
// foo
println
(
"foobar"
);
// foobar
println
(
"foobar"
);
// foobar
...
...
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