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
b705ac6c
Commit
b705ac6c
authored
Oct 16, 2008
by
Robert Griesemer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
- composites, receivers, various add. checks
R=r OCL=17295 CL=17295
parent
082f116b
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
138 additions
and
129 deletions
+138
-129
usr/gri/pretty/node.go
usr/gri/pretty/node.go
+46
-32
usr/gri/pretty/parser.go
usr/gri/pretty/parser.go
+69
-56
usr/gri/pretty/printer.go
usr/gri/pretty/printer.go
+23
-41
No files found.
usr/gri/pretty/node.go
View file @
b705ac6c
...
...
@@ -68,38 +68,8 @@ export func NewList() *List {
}
// ----------------------------------------------------------------------------
// Types
export
const
/* channel mode */
(
FULL
=
iota
;
SEND
;
RECV
;
)
export
type
Type
struct
{
pos
,
tok
int
;
expr
*
Expr
;
// type name, array length
mode
int
;
// channel mode
key
*
Type
;
// map key
elt
*
Type
;
// array element, map or channel value, or pointer base type
list
*
List
;
// struct fields, interface methods, function parameters
}
export
func
NewType
(
pos
,
tok
int
)
*
Type
{
t
:=
new
(
Type
);
t
.
pos
,
t
.
tok
=
pos
,
tok
;
return
t
;
}
// ----------------------------------------------------------------------------
// Expressions
//
// Expression pairs are represented as binary expressions with operator ":"
// Expression lists are represented as binary expressions with operator ","
export
type
Expr
struct
{
pos
,
tok
int
;
...
...
@@ -135,9 +105,53 @@ export func NewLit(pos, tok int, s string) *Expr {
}
export
func
NewTypeExpr
(
pos
int
,
t
*
Type
)
*
Expr
{
// ----------------------------------------------------------------------------
// Types
export
const
/* channel mode */
(
FULL
=
iota
;
SEND
;
RECV
;
)
export
type
Type
struct
{
pos
,
tok
int
;
expr
*
Expr
;
// type name, array length
mode
int
;
// channel mode
key
*
Type
;
// receiver type, map key
elt
*
Type
;
// array element, map or channel value, or pointer base type, result type
list
*
List
;
// struct fields, interface methods, function parameters
}
func
(
t
*
Type
)
nfields
()
int
{
nx
,
nt
:=
0
,
0
;
for
i
,
n
:=
0
,
t
.
list
.
len
();
i
<
n
;
i
++
{
if
t
.
list
.
at
(
i
)
.
(
*
Expr
)
.
tok
==
Scanner
.
TYPE
{
nt
++
;
}
else
{
nx
++
;
}
}
if
nx
==
0
{
return
nt
;
}
return
nx
;
}
export
func
NewType
(
pos
,
tok
int
)
*
Type
{
t
:=
new
(
Type
);
t
.
pos
,
t
.
tok
=
pos
,
tok
;
return
t
;
}
// requires complete Type type
export
func
NewTypeExpr
(
t
*
Type
)
*
Expr
{
e
:=
new
(
Expr
);
e
.
pos
,
e
.
tok
,
e
.
t
=
pos
,
Scanner
.
TYPE
,
t
;
e
.
pos
,
e
.
tok
,
e
.
t
=
t
.
pos
,
Scanner
.
TYPE
,
t
;
return
e
;
}
...
...
usr/gri/pretty/parser.go
View file @
b705ac6c
...
...
@@ -131,18 +131,19 @@ func (P *Parser) ParseIdent() *Node.Expr {
}
func
(
P
*
Parser
)
ParseIdentList
()
*
Node
.
List
{
func
(
P
*
Parser
)
ParseIdentList
()
*
Node
.
Expr
{
P
.
Trace
(
"IdentList"
);
list
:=
Node
.
NewLis
t
();
list
.
Add
(
P
.
ParseIdent
());
for
P
.
tok
==
Scanner
.
COMMA
{
x
:=
P
.
ParseIden
t
();
if
P
.
tok
==
Scanner
.
COMMA
{
pos
:=
P
.
pos
;
P
.
Next
();
list
.
Add
(
P
.
ParseIdent
());
y
:=
P
.
ParseIdentList
();
x
:=
Node
.
NewExpr
(
pos
,
Scanner
.
COMMA
,
x
,
y
);
}
P
.
Ecart
();
return
list
;
return
x
;
}
...
...
@@ -241,6 +242,7 @@ func (P *Parser) ParseChannelType() *Node.Type {
func
(
P
*
Parser
)
ParseVarDeclList
(
list
*
Node
.
List
)
{
P
.
Trace
(
"VarDeclList"
);
// parse a list of types
i0
:=
list
.
len
();
list
.
Add
(
P
.
ParseType
());
for
P
.
tok
==
Scanner
.
COMMA
{
...
...
@@ -250,6 +252,7 @@ func (P *Parser) ParseVarDeclList(list *Node.List) {
typ
:=
P
.
TryType
();
// convert the list into a list of (type) expressions
if
typ
!=
nil
{
// all list entries must be identifiers
// convert the type entries into identifiers
...
...
@@ -263,14 +266,14 @@ func (P *Parser) ParseVarDeclList(list *Node.List) {
}
}
// add type
list
.
Add
(
Node
.
NewTypeExpr
(
typ
.
pos
,
typ
));
list
.
Add
(
Node
.
NewTypeExpr
(
typ
));
}
else
{
// all list entries are types
// convert all type entries into type expressions
for
i
,
n
:=
i0
,
list
.
len
();
i
<
n
;
i
++
{
t
:=
list
.
at
(
i
)
.
(
*
Node
.
Type
);
list
.
set
(
i
,
Node
.
NewTypeExpr
(
t
.
pos
,
t
));
list
.
set
(
i
,
Node
.
NewTypeExpr
(
t
));
}
if
P
.
tok
==
Scanner
.
COMMA
{
...
...
@@ -339,7 +342,7 @@ func (P *Parser) ParseResult() *Node.Type {
if
typ
!=
nil
{
t
=
Node
.
NewType
(
P
.
pos
,
Scanner
.
STRUCT
);
t
.
list
=
Node
.
NewList
();
t
.
list
.
Add
(
Node
.
NewTypeExpr
(
typ
.
pos
,
typ
));
t
.
list
.
Add
(
Node
.
NewTypeExpr
(
typ
));
}
}
...
...
@@ -572,7 +575,7 @@ func (P *Parser) ParseOperand() *Node.Expr {
default
:
t
:=
P
.
TryType
();
if
t
!=
nil
{
x
=
Node
.
NewTypeExpr
(
t
.
pos
,
t
);
x
=
Node
.
NewTypeExpr
(
t
);
}
else
{
P
.
Error
(
P
.
pos
,
"operand expected"
);
P
.
Next
();
// make progress
...
...
@@ -653,31 +656,42 @@ func (P *Parser) ParseCall(x *Node.Expr) *Node.Expr {
}
func
(
P
*
Parser
)
ParseExpressionPairList
(
mode
int
)
*
Node
.
Expr
{
P
.
Trace
(
"ExpressionPairList"
);
x
:=
P
.
ParseExpressionPair
(
mode
);
if
mode
==
0
{
// first expression determines mode
if
x
.
tok
==
Scanner
.
COLON
{
mode
=
2
;
}
else
{
mode
=
1
;
}
}
if
P
.
tok
==
Scanner
.
COMMA
{
pos
:=
P
.
pos
;
P
.
Next
();
if
P
.
tok
!=
Scanner
.
RBRACE
&&
P
.
tok
!=
Scanner
.
EOF
{
y
:=
P
.
ParseExpressionPairList
(
mode
);
x
=
Node
.
NewExpr
(
pos
,
Scanner
.
COMMA
,
x
,
y
);
}
}
P
.
Ecart
();
return
x
;
}
func
(
P
*
Parser
)
ParseCompositeLit
(
t
*
Node
.
Type
)
*
Node
.
Expr
{
P
.
Trace
(
"CompositeLit"
);
mode
:=
0
;
pos
:=
P
.
pos
;
P
.
Expect
(
Scanner
.
LBRACE
);
for
P
.
tok
!=
Scanner
.
RBRACE
&&
P
.
tok
!=
Scanner
.
EOF
{
x
:=
P
.
ParseExpressionPair
(
mode
);
if
mode
==
0
{
// first expression determines mode
if
x
.
tok
==
Scanner
.
COLON
{
mode
=
2
;
}
else
{
mode
=
1
;
}
}
if
P
.
tok
==
Scanner
.
COMMA
{
P
.
Next
();
}
else
{
break
;
}
}
x
:=
P
.
ParseExpressionPairList
(
0
);
P
.
Expect
(
Scanner
.
RBRACE
);
P
.
Ecart
();
return
Node
.
New
Lit
(
P
.
pos
,
Scanner
.
INT
,
"0"
);
// "null" expr
return
Node
.
New
Expr
(
pos
,
Scanner
.
LBRACE
,
Node
.
NewTypeExpr
(
t
),
x
);
}
...
...
@@ -780,16 +794,16 @@ func (P *Parser) ParseSimpleStat() *Node.Stat {
P
.
Trace
(
"SimpleStat"
);
var
s
*
Node
.
Stat
;
x
:=
P
.
ParseExpressionList
();
switch
P
.
tok
{
case
Scanner
.
COLON
:
// label declaration
if
x
.
len
()
==
1
{
s
=
Node
.
NewStat
(
P
.
pos
,
Scanner
.
COLON
);
s
.
expr
=
x
;
}
else
{
P
.
Error
(
P
.
pos
,
"illegal label declaration"
);
s
=
Node
.
NewStat
(
P
.
pos
,
Scanner
.
COLON
);
s
.
expr
=
x
;
if
x
.
len
()
!=
1
{
P
.
Error
(
x
.
pos
,
"illegal label declaration"
);
}
P
.
Next
();
// consume ":"
P
.
opt_semi
=
true
;
...
...
@@ -803,23 +817,22 @@ func (P *Parser) ParseSimpleStat() *Node.Stat {
P
.
Next
();
s
.
lhs
=
x
;
s
.
expr
=
P
.
ParseExpressionList
();
if
l
,
r
:=
x
.
len
(),
s
.
expr
.
len
();
l
>
1
&&
r
>
1
&&
l
!=
r
{
P
.
Error
(
x
.
pos
,
"arity of lhs doesn't match rhs"
);
}
default
:
var
pos
,
tok
int
;
if
P
.
tok
==
Scanner
.
INC
||
P
.
tok
==
Scanner
.
DEC
{
s
=
Node
.
NewStat
(
P
.
pos
,
P
.
tok
);
if
x
.
len
()
==
1
{
s
.
expr
=
x
;
}
else
{
P
.
Error
(
P
.
pos
,
"more then one operand"
);
}
P
.
Next
();
// consume "++" or "--"
pos
,
tok
=
P
.
pos
,
P
.
tok
;
P
.
Next
();
}
else
{
s
=
Node
.
NewStat
(
P
.
pos
,
0
)
;
// TODO give this a token value
if
x
.
len
()
==
1
{
s
.
expr
=
x
;
}
else
{
P
.
Error
(
P
.
pos
,
"syntax error"
);
}
pos
,
tok
=
x
.
pos
,
0
;
// TODO give this a token value
}
s
=
Node
.
NewStat
(
pos
,
tok
)
;
s
.
expr
=
x
;
if
x
.
len
()
!=
1
{
P
.
Error
(
x
.
pos
,
"only one expression allowed"
);
}
}
...
...
@@ -1173,15 +1186,15 @@ func (P *Parser) ParseVarSpec(exported bool) *Node.Decl {
P
.
Trace
(
"VarSpec"
);
d
:=
Node
.
NewDecl
(
P
.
pos
,
Scanner
.
VAR
,
exported
);
P
.
ParseIdentList
();
d
.
ident
=
P
.
ParseIdentList
();
if
P
.
tok
==
Scanner
.
ASSIGN
{
P
.
Next
();
P
.
ParseExpressionList
();
d
.
val
=
P
.
ParseExpressionList
();
}
else
{
P
.
ParseVarType
();
d
.
typ
=
P
.
ParseVarType
();
if
P
.
tok
==
Scanner
.
ASSIGN
{
P
.
Next
();
P
.
ParseExpressionList
();
d
.
val
=
P
.
ParseExpressionList
();
}
}
...
...
@@ -1246,20 +1259,20 @@ func (P *Parser) ParseFunctionDecl(exported bool) *Node.Decl {
d
:=
Node
.
NewDecl
(
P
.
pos
,
Scanner
.
FUNC
,
exported
);
P
.
Expect
(
Scanner
.
FUNC
);
var
recv
*
Node
.
Type
;
if
P
.
tok
==
Scanner
.
LPAREN
{
pos
:=
P
.
pos
;
recv
:=
P
.
ParseParameters
();
// TODO: fix this
/*
if recv.list.len() != 1 {
recv
=
P
.
ParseParameters
();
if
recv
.
nfields
()
!=
1
{
P
.
Error
(
pos
,
"must have exactly one receiver"
);
}
*/
}
d
.
ident
=
P
.
ParseIdent
();
d
.
typ
=
P
.
ParseFunctionType
();
d
.
typ
.
key
=
recv
;
if
P
.
tok
==
Scanner
.
LBRACE
{
P
.
scope_lev
++
;
d
.
list
=
P
.
ParseBlock
();
...
...
usr/gri/pretty/printer.go
View file @
b705ac6c
...
...
@@ -70,7 +70,8 @@ func (P *Printer) CloseScope(paren string) {
func
(
P
*
Printer
)
Type
(
t
*
Node
.
Type
)
func
(
P
*
Printer
)
Expr
(
x
*
Node
.
Expr
)
func
(
P
*
Printer
)
Parameters
(
list
*
Node
.
List
)
{
func
(
P
*
Printer
)
Parameters
(
pos
int
,
list
*
Node
.
List
)
{
P
.
String
(
pos
,
"("
);
var
prev
int
;
for
i
,
n
:=
0
,
list
.
len
();
i
<
n
;
i
++
{
x
:=
list
.
at
(
i
)
.
(
*
Node
.
Expr
);
...
...
@@ -84,6 +85,7 @@ func (P *Printer) Parameters(list *Node.List) {
P
.
Expr
(
x
);
prev
=
x
.
tok
;
}
P
.
String
(
0
,
")"
);
}
...
...
@@ -123,7 +125,7 @@ func (P *Printer) Type(t *Node.Type) {
if
t
.
expr
!=
nil
{
P
.
Expr
(
t
.
expr
);
}
P
.
String
(
0
,
"]
"
);
P
.
String
(
0
,
"]"
);
P
.
Type
(
t
.
elt
);
case
Scanner
.
STRUCT
:
...
...
@@ -137,7 +139,7 @@ func (P *Printer) Type(t *Node.Type) {
case
Scanner
.
MAP
:
P
.
String
(
t
.
pos
,
"["
);
P
.
Type
(
t
.
key
);
P
.
String
(
0
,
"]
"
);
P
.
String
(
0
,
"]"
);
P
.
Type
(
t
.
elt
);
case
Scanner
.
CHAN
:
...
...
@@ -168,13 +170,10 @@ func (P *Printer) Type(t *Node.Type) {
P
.
Type
(
t
.
elt
);
case
Scanner
.
LPAREN
:
P
.
String
(
t
.
pos
,
"("
);
P
.
Parameters
(
t
.
list
);
P
.
String
(
0
,
")"
);
P
.
Parameters
(
t
.
pos
,
t
.
list
);
if
t
.
elt
!=
nil
{
P
.
String
(
0
,
" ("
);
P
.
Parameters
(
t
.
elt
.
list
);
P
.
String
(
0
,
")"
);
P
.
Blank
();
P
.
Parameters
(
0
,
t
.
elt
.
list
);
}
default
:
...
...
@@ -192,9 +191,6 @@ func (P *Printer) Expr1(x *Node.Expr, prec1 int) {
}
switch
x
.
tok
{
case
Scanner
.
VAR
:
panic
(
"UNIMPLEMENTED (VAR)"
);
case
Scanner
.
TYPE
:
P
.
Type
(
x
.
t
);
...
...
@@ -222,6 +218,12 @@ func (P *Printer) Expr1(x *Node.Expr, prec1 int) {
P
.
String
(
x
.
pos
,
"("
);
P
.
Expr1
(
x
.
y
,
0
);
P
.
String
(
0
,
")"
);
case
Scanner
.
LBRACE
:
P
.
Expr1
(
x
.
x
,
8
);
P
.
String
(
x
.
pos
,
"{"
);
P
.
Expr1
(
x
.
y
,
0
);
P
.
String
(
0
,
"}"
);
default
:
if
x
.
x
==
nil
{
...
...
@@ -396,35 +398,6 @@ func (P *Printer) Stat(s *Node.Stat) {
// Declarations
/*
func (P *Printer) DoFuncDecl(x *AST.FuncDecl) {
P.String("func ");
if x.typ.recv != nil {
P.String("(");
P.DoVarDeclList(x.typ.recv);
P.String(") ");
}
P.DoIdent(x.ident);
P.DoFunctionType(x.typ);
if x.body != nil {
P.String(" ");
P.DoBlock(x.body);
} else {
P.String(" ;");
}
P.NewLine();
P.NewLine();
}
func (P *Printer) DoMethodDecl(x *AST.MethodDecl) {
//P.DoIdent(x.ident);
//P.DoFunctionType(x.typ);
}
*/
func
(
P
*
Printer
)
Declaration
(
d
*
Node
.
Decl
,
parenthesized
bool
)
{
if
d
==
nil
{
// TODO remove this check
P
.
String
(
0
,
"<nil decl>"
);
...
...
@@ -448,6 +421,11 @@ func (P *Printer) Declaration(d *Node.Decl, parenthesized bool) {
P
.
CloseScope
(
")"
);
}
else
{
if
d
.
tok
==
Scanner
.
FUNC
&&
d
.
typ
.
key
!=
nil
{
P
.
Parameters
(
0
,
d
.
typ
.
key
.
list
);
P
.
Blank
();
}
P
.
Expr
(
d
.
ident
);
if
d
.
typ
!=
nil
{
...
...
@@ -471,6 +449,10 @@ func (P *Printer) Declaration(d *Node.Decl, parenthesized bool) {
P
.
Blank
();
P
.
Block
(
d
.
list
,
true
);
}
if
d
.
tok
!=
Scanner
.
TYPE
{
P
.
semi
=
true
;
}
}
P
.
newl
=
1
;
...
...
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