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
26097317
Commit
26097317
authored
Aug 05, 2009
by
Russ Cox
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
delay range processing. old2new is gone
R=ken OCL=32780 CL=32780
parent
54b40372
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
286 additions
and
363 deletions
+286
-363
src/cmd/gc/Makefile
src/cmd/gc/Makefile
+1
-0
src/cmd/gc/dcl.c
src/cmd/gc/dcl.c
+27
-34
src/cmd/gc/go.h
src/cmd/gc/go.h
+5
-4
src/cmd/gc/go.y
src/cmd/gc/go.y
+11
-28
src/cmd/gc/range.c
src/cmd/gc/range.c
+216
-0
src/cmd/gc/select.c
src/cmd/gc/select.c
+0
-26
src/cmd/gc/subr.c
src/cmd/gc/subr.c
+8
-10
src/cmd/gc/typecheck.c
src/cmd/gc/typecheck.c
+10
-2
src/cmd/gc/walk.c
src/cmd/gc/walk.c
+8
-259
No files found.
src/cmd/gc/Makefile
View file @
26097317
...
@@ -30,6 +30,7 @@ OFILES=\
...
@@ -30,6 +30,7 @@ OFILES=\
mparith3.
$O
\
mparith3.
$O
\
obj.
$O
\
obj.
$O
\
print.
$O
\
print.
$O
\
range.
$O
\
reflect.
$O
\
reflect.
$O
\
select
.
$O
\
select
.
$O
\
sinit.
$O
\
sinit.
$O
\
...
...
src/cmd/gc/dcl.c
View file @
26097317
...
@@ -594,39 +594,12 @@ colasname(Node *n)
...
@@ -594,39 +594,12 @@ colasname(Node *n)
return
0
;
return
0
;
}
}
Node
*
void
old2new
(
Node
*
n
,
Type
*
t
,
NodeList
**
init
)
colasdefn
(
NodeList
*
left
,
Node
*
defn
)
{
Node
*
l
;
if
(
!
colasname
(
n
))
{
yyerror
(
"left side of := must be a name"
);
return
n
;
}
if
(
t
!=
T
&&
t
->
funarg
)
{
yyerror
(
"use of multi func value as single value in :="
);
return
n
;
}
l
=
newname
(
n
->
sym
);
dodclvar
(
l
,
t
,
init
);
return
l
;
}
Node
*
colas
(
NodeList
*
left
,
NodeList
*
right
)
{
{
int
nnew
;
int
nnew
;
Node
*
n
,
*
as
;
NodeList
*
l
;
NodeList
*
l
;
Node
*
n
;
if
(
count
(
left
)
==
1
&&
count
(
right
)
==
1
)
as
=
nod
(
OAS
,
left
->
n
,
right
->
n
);
else
{
as
=
nod
(
OAS2
,
N
,
N
);
as
->
list
=
left
;
as
->
rlist
=
right
;
}
as
->
colas
=
1
;
nnew
=
0
;
nnew
=
0
;
for
(
l
=
left
;
l
;
l
=
l
->
next
)
{
for
(
l
=
left
;
l
;
l
=
l
->
next
)
{
...
@@ -640,14 +613,34 @@ colas(NodeList *left, NodeList *right)
...
@@ -640,14 +613,34 @@ colas(NodeList *left, NodeList *right)
nnew
++
;
nnew
++
;
n
=
newname
(
n
->
sym
);
n
=
newname
(
n
->
sym
);
declare
(
n
,
dclcontext
);
declare
(
n
,
dclcontext
);
if
(
as
->
op
==
OAS
)
n
->
defn
=
defn
;
as
->
left
=
n
;
defn
->
ninit
=
list
(
defn
->
ninit
,
nod
(
ODCL
,
n
,
N
));
n
->
defn
=
as
;
as
->
ninit
=
list
(
as
->
ninit
,
nod
(
ODCL
,
n
,
N
));
l
->
n
=
n
;
l
->
n
=
n
;
}
}
if
(
nnew
==
0
)
if
(
nnew
==
0
)
yyerror
(
"no new variables on left side of :="
);
yyerror
(
"no new variables on left side of :="
);
}
Node
*
colas
(
NodeList
*
left
,
NodeList
*
right
)
{
Node
*
as
;
as
=
nod
(
OAS2
,
N
,
N
);
as
->
list
=
left
;
as
->
rlist
=
right
;
as
->
colas
=
1
;
colasdefn
(
left
,
as
);
// make the tree prettier; not necessary
if
(
count
(
left
)
==
1
&&
count
(
right
)
==
1
)
{
as
->
left
=
as
->
list
->
n
;
as
->
right
=
as
->
rlist
->
n
;
as
->
list
=
nil
;
as
->
rlist
=
nil
;
as
->
op
=
OAS
;
}
return
as
;
return
as
;
}
}
...
...
src/cmd/gc/go.h
View file @
26097317
...
@@ -332,7 +332,7 @@ enum
...
@@ -332,7 +332,7 @@ enum
OCOMPSLICE
,
OCOMPMAP
,
OCOMPSLICE
,
OCOMPMAP
,
OCONV
,
OCONVNOP
,
OCONVA2S
,
OCONVIFACE
,
OCONVSLICE
,
OCONV
,
OCONVNOP
,
OCONVA2S
,
OCONVIFACE
,
OCONVSLICE
,
ODCL
,
ODCLFUNC
,
ODCLFIELD
,
ODCLARG
,
ODCL
,
ODCLFUNC
,
ODCLFIELD
,
ODCLARG
,
ODOT
,
ODOTPTR
,
ODOTMETH
,
ODOTINTER
,
ODOT
,
ODOTPTR
,
ODOTMETH
,
ODOTINTER
,
OXDOT
,
ODOTTYPE
,
ODOTTYPE
,
OEQ
,
ONE
,
OLT
,
OLE
,
OGE
,
OGT
,
OEQ
,
ONE
,
OLT
,
OLE
,
OGE
,
OGT
,
OFUNC
,
OFUNC
,
...
@@ -948,6 +948,7 @@ void walkconv(Node**, NodeList**);
...
@@ -948,6 +948,7 @@ void walkconv(Node**, NodeList**);
void
walkdottype
(
Node
*
,
NodeList
**
);
void
walkdottype
(
Node
*
,
NodeList
**
);
void
walkas
(
Node
*
);
void
walkas
(
Node
*
);
void
walkswitch
(
Node
*
);
void
walkswitch
(
Node
*
);
void
walkrange
(
Node
*
);
void
walkselect
(
Node
*
);
void
walkselect
(
Node
*
);
void
walkdot
(
Node
*
,
NodeList
**
);
void
walkdot
(
Node
*
,
NodeList
**
);
void
walkexpr
(
Node
**
,
NodeList
**
);
void
walkexpr
(
Node
**
,
NodeList
**
);
...
@@ -967,22 +968,22 @@ void ifacecheck(Type*, Type*, int, int);
...
@@ -967,22 +968,22 @@ void ifacecheck(Type*, Type*, int, int);
void
runifacechecks
(
void
);
void
runifacechecks
(
void
);
Node
*
convas
(
Node
*
,
NodeList
**
);
Node
*
convas
(
Node
*
,
NodeList
**
);
Node
*
colas
(
NodeList
*
,
NodeList
*
);
Node
*
colas
(
NodeList
*
,
NodeList
*
);
Node
*
dorange
(
Node
*
);
void
colasdefn
(
NodeList
*
,
Node
*
);
NodeList
*
reorder1
(
NodeList
*
);
NodeList
*
reorder1
(
NodeList
*
);
NodeList
*
reorder3
(
NodeList
*
);
NodeList
*
reorder3
(
NodeList
*
);
NodeList
*
reorder4
(
NodeList
*
);
NodeList
*
reorder4
(
NodeList
*
);
Node
*
structlit
(
Node
*
,
Node
*
,
NodeList
**
);
Node
*
structlit
(
Node
*
,
Node
*
,
NodeList
**
);
Node
*
arraylit
(
Node
*
,
Node
*
,
NodeList
**
);
Node
*
arraylit
(
Node
*
,
Node
*
,
NodeList
**
);
Node
*
maplit
(
Node
*
,
Node
*
,
NodeList
**
);
Node
*
maplit
(
Node
*
,
Node
*
,
NodeList
**
);
Node
*
selectas
(
Node
*
,
Node
*
,
NodeList
**
);
Node
*
old2new
(
Node
*
,
Type
*
,
NodeList
**
);
void
heapmoves
(
void
);
void
heapmoves
(
void
);
void
walkdeflist
(
NodeList
*
);
void
walkdeflist
(
NodeList
*
);
void
walkdef
(
Node
*
);
void
walkdef
(
Node
*
);
void
typechecklist
(
NodeList
*
,
int
);
void
typechecklist
(
NodeList
*
,
int
);
void
typecheckswitch
(
Node
*
);
void
typecheckswitch
(
Node
*
);
void
typecheckselect
(
Node
*
);
void
typecheckselect
(
Node
*
);
void
typecheckrange
(
Node
*
);
Node
*
typecheckconv
(
Node
*
,
Node
*
,
Type
*
,
int
);
Node
*
typecheckconv
(
Node
*
,
Node
*
,
Type
*
,
int
);
int
checkconv
(
Type
*
,
Type
*
,
int
,
int
*
,
int
*
);
Node
*
typecheck
(
Node
**
,
int
);
Node
*
typecheck
(
Node
**
,
int
);
/*
/*
...
...
src/cmd/gc/go.y
View file @
26097317
...
@@ -464,8 +464,7 @@ simple_stmt:
...
@@ -464,8 +464,7 @@ simple_stmt:
case:
case:
LCASE expr_or_type_list '
:
'
LCASE expr_or_type_list '
:
'
{
{
int e;
Node *n, *ntype;
Node *n;
// will be converted to OCASE
// will be converted to OCASE
// right will point to next case
// right will point to next case
...
@@ -474,29 +473,18 @@ case:
...
@@ -474,29 +473,18 @@ case:
$$ = nod(OXCASE, N, N);
$$ = nod(OXCASE, N, N);
if(typeswvar != N && typeswvar->right != N) {
if(typeswvar != N && typeswvar->right != N) {
// type switch
// type switch
n = $2->n;
n
type
= $2->n;
if($2->next != nil)
if($2->next != nil)
yyerror("type switch case cannot be list");
yyerror("type switch case cannot be list");
if(n
->op == OLITERAL && n
->val.ctype == CTNIL) {
if(n
type->op == OLITERAL && ntype
->val.ctype == CTNIL) {
// case nil
// case nil
$$->list = list1(nod(OTYPECASE, N, N));
$$->list = list1(nod(OTYPECASE, N, N));
break;
break;
}
}
n = newname(typeswvar->right->sym);
// TODO: move
declare(n, dclcontext);
e = nerrors;
n->ntype = ntype;
typecheck(&n, Etype | Erv);
$$->list = list1(nod(OTYPECASE, n, N));
if(n->op == OTYPE) {
n = old2new(typeswvar->right, n->type, &$$->ninit);
$$->list = list1(nod(OTYPECASE, n, N));
break;
}
// maybe typecheck found problems that keep
// e from being valid even outside a type switch.
// only complain if typecheck didn'
t
print
new
errors
.
if
(
nerrors
==
e
)
yyerror
(
"non-type case in type switch"
);
$$->
diag
=
1
;
} else {
} else {
// expr switch
// expr switch
$$->list = $2;
$$->list = $2;
...
@@ -519,7 +507,6 @@ case:
...
@@ -519,7 +507,6 @@ case:
// done in casebody()
// done in casebody()
poptodcl();
poptodcl();
$$ = nod(OXCASE, N, N);
$$ = nod(OXCASE, N, N);
//
$$->
list
=
list1
(
nod
(
OAS
,
selectas
($
2
,
$
4
,
&$$->
ninit
),
$
4
));
$$->list = list1(colas(list1($2), list1($4)));
$$->list = list1(colas(list1($2), list1($4)));
}
}
| LDEFAULT '
:
'
| LDEFAULT '
:
'
...
@@ -590,7 +577,8 @@ range_stmt:
...
@@ -590,7 +577,8 @@ range_stmt:
{
{
$$ = nod(ORANGE, N, $4);
$$ = nod(ORANGE, N, $4);
$$->list = $1;
$$->list = $1;
$$->
etype
=
1
;
$$->colas = 1;
colasdefn($1, $$);
}
}
for_header:
for_header:
...
@@ -612,9 +600,6 @@ for_header:
...
@@ -612,9 +600,6 @@ for_header:
$$->ntest = $1;
$$->ntest = $1;
}
}
| range_stmt
| range_stmt
{
$$
=
dorange
($
1
);
}
for_body:
for_body:
for_header loop_body
for_header loop_body
...
@@ -850,8 +835,7 @@ pexpr:
...
@@ -850,8 +835,7 @@ pexpr:
$$
=
oldname
(
s
);
$$
=
oldname
(
s
);
break
;
break
;
}
}
$$
=
nod
(
ODOT
,
$
1
,
newname
($
3
));
$$
=
nod
(
OXDOT
,
$
1
,
newname
($
3
));
$$
=
adddot
($$);
}
}
|
'('
expr_or_type
')'
|
'('
expr_or_type
')'
{
{
...
@@ -1041,8 +1025,7 @@ dotname:
...
@@ -1041,8 +1025,7 @@ dotname:
$$ = oldname(s);
$$ = oldname(s);
break;
break;
}
}
$$ = nod(ODOT, $1, newname($3));
$$ = nod(OXDOT, $1, newname($3));
$$ = adddot($$);
}
}
othertype:
othertype:
...
...
src/cmd/gc/range.c
0 → 100644
View file @
26097317
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
/*
* range
*/
#include "go.h"
void
typecheckrange
(
Node
*
n
)
{
int
op
,
et
;
Type
*
t
,
*
t1
,
*
t2
;
Node
*
v1
,
*
v2
;
NodeList
*
ll
;
// delicate little dance. see typecheckas2
for
(
ll
=
n
->
list
;
ll
;
ll
=
ll
->
next
)
if
(
ll
->
n
->
defn
!=
n
)
typecheck
(
&
ll
->
n
,
Erv
);
typecheck
(
&
n
->
right
,
Erv
);
if
((
t
=
n
->
right
->
type
)
==
T
)
goto
out
;
n
->
type
=
t
;
switch
(
t
->
etype
)
{
default:
yyerror
(
"cannot range over %+N"
,
n
->
right
);
goto
out
;
case
TARRAY
:
t1
=
types
[
TINT
];
t2
=
t
->
type
;
break
;
case
TMAP
:
t1
=
t
->
down
;
t2
=
t
->
type
;
break
;
case
TCHAN
:
t1
=
t
->
type
;
t2
=
nil
;
if
(
count
(
n
->
list
)
==
2
)
goto
toomany
;
break
;
case
TSTRING
:
t1
=
types
[
TINT
];
t2
=
types
[
TINT
];
break
;
}
if
(
count
(
n
->
list
)
>
2
)
{
toomany:
yyerror
(
"too many variables in range"
);
}
v1
=
n
->
list
->
n
;
v2
=
N
;
if
(
n
->
list
->
next
)
v2
=
n
->
list
->
next
->
n
;
if
(
v1
->
defn
==
n
)
v1
->
type
=
t1
;
else
if
(
v1
->
type
!=
T
&&
checkconv
(
t1
,
v1
->
type
,
0
,
&
op
,
&
et
)
<
0
)
yyerror
(
"cannot assign type %T to %+N"
,
t1
,
v1
);
if
(
v2
)
{
if
(
v2
->
defn
==
n
)
v2
->
type
=
t2
;
else
if
(
v2
->
type
!=
T
&&
checkconv
(
t2
,
v2
->
type
,
0
,
&
op
,
&
et
)
<
0
)
yyerror
(
"cannot assign type %T to %+N"
,
t1
,
v1
);
}
out:
typechecklist
(
n
->
nbody
,
Etop
);
// second half of dance
n
->
typecheck
=
1
;
for
(
ll
=
n
->
list
;
ll
;
ll
=
ll
->
next
)
if
(
ll
->
n
->
typecheck
==
0
)
typecheck
(
&
ll
->
n
,
Erv
);
}
void
walkrange
(
Node
*
n
)
{
Node
*
ohv1
,
*
hv1
,
*
hv2
;
// hidden (old) val 1, 2
Node
*
ha
,
*
hit
;
// hidden aggregate, iterator
Node
*
a
,
*
v1
,
*
v2
;
// not hidden aggregate, val 1, 2
Node
*
fn
;
NodeList
*
body
,
*
init
;
Type
*
th
,
*
t
;
t
=
n
->
type
;
init
=
nil
;
a
=
n
->
right
;
if
(
t
->
etype
==
TSTRING
&&
!
eqtype
(
t
,
types
[
TSTRING
]))
{
a
=
nod
(
OCONV
,
n
->
right
,
N
);
a
->
type
=
types
[
TSTRING
];
}
ha
=
nod
(
OXXX
,
N
,
N
);
tempname
(
ha
,
a
->
type
);
init
=
list
(
init
,
nod
(
OAS
,
ha
,
a
));
v1
=
n
->
list
->
n
;
hv1
=
N
;
v2
=
N
;
if
(
n
->
list
->
next
)
v2
=
n
->
list
->
next
->
n
;
hv2
=
N
;
switch
(
t
->
etype
)
{
default:
fatal
(
"walkrange"
);
case
TARRAY
:
hv1
=
nod
(
OXXX
,
N
,
n
);
tempname
(
hv1
,
v1
->
type
);
init
=
list
(
init
,
nod
(
OAS
,
hv1
,
N
));
n
->
ntest
=
nod
(
OLT
,
hv1
,
nod
(
OLEN
,
ha
,
N
));
n
->
nincr
=
nod
(
OASOP
,
hv1
,
nodintconst
(
1
));
n
->
nincr
->
etype
=
OADD
;
body
=
list1
(
nod
(
OAS
,
v1
,
hv1
));
if
(
v2
)
body
=
list
(
body
,
nod
(
OAS
,
v2
,
nod
(
OINDEX
,
ha
,
hv1
)));
break
;
case
TMAP
:
th
=
typ
(
TARRAY
);
th
->
type
=
ptrto
(
types
[
TUINT8
]);
th
->
bound
=
(
sizeof
(
struct
Hiter
)
+
widthptr
-
1
)
/
widthptr
;
hit
=
nod
(
OXXX
,
N
,
N
);
tempname
(
hit
,
th
);
fn
=
syslook
(
"mapiterinit"
,
1
);
argtype
(
fn
,
t
->
down
);
argtype
(
fn
,
t
->
type
);
argtype
(
fn
,
th
);
init
=
list
(
init
,
mkcall1
(
fn
,
T
,
nil
,
ha
,
nod
(
OADDR
,
hit
,
N
)));
n
->
ntest
=
nod
(
ONE
,
nod
(
OINDEX
,
hit
,
nodintconst
(
0
)),
nodnil
());
fn
=
syslook
(
"mapiternext"
,
1
);
argtype
(
fn
,
th
);
n
->
nincr
=
mkcall1
(
fn
,
T
,
nil
,
nod
(
OADDR
,
hit
,
N
));
if
(
v2
==
N
)
{
fn
=
syslook
(
"mapiter1"
,
1
);
argtype
(
fn
,
th
);
argtype
(
fn
,
t
->
down
);
a
=
nod
(
OAS
,
v1
,
mkcall1
(
fn
,
t
->
down
,
nil
,
nod
(
OADDR
,
hit
,
N
)));
}
else
{
fn
=
syslook
(
"mapiter2"
,
1
);
argtype
(
fn
,
th
);
argtype
(
fn
,
t
->
down
);
argtype
(
fn
,
t
->
type
);
a
=
nod
(
OAS2
,
N
,
N
);
a
->
list
=
list
(
list1
(
v1
),
v2
);
a
->
rlist
=
list1
(
mkcall1
(
fn
,
getoutargx
(
fn
->
type
),
nil
,
nod
(
OADDR
,
hit
,
N
)));
}
body
=
list1
(
a
);
break
;
case
TCHAN
:
hv1
=
nod
(
OXXX
,
N
,
n
);
tempname
(
hv1
,
v1
->
type
);
n
->
ntest
=
nod
(
ONOT
,
nod
(
OCLOSED
,
ha
,
N
),
N
);
n
->
ntest
->
ninit
=
list1
(
nod
(
OAS
,
hv1
,
nod
(
ORECV
,
ha
,
N
)));
body
=
list1
(
nod
(
OAS
,
v1
,
hv1
));
break
;
case
TSTRING
:
ohv1
=
nod
(
OXXX
,
N
,
N
);
tempname
(
ohv1
,
types
[
TINT
]);
hv1
=
nod
(
OXXX
,
N
,
N
);
tempname
(
hv1
,
types
[
TINT
]);
init
=
list
(
init
,
nod
(
OAS
,
hv1
,
N
));
if
(
v2
==
N
)
a
=
nod
(
OAS
,
hv1
,
mkcall
(
"stringiter"
,
types
[
TINT
],
nil
,
ha
,
hv1
));
else
{
hv2
=
nod
(
OXXX
,
N
,
N
);
tempname
(
hv2
,
types
[
TINT
]);
a
=
nod
(
OAS2
,
N
,
N
);
a
->
list
=
list
(
list1
(
hv1
),
hv2
);
fn
=
syslook
(
"stringiter2"
,
0
);
a
->
rlist
=
list1
(
mkcall1
(
fn
,
getoutargx
(
fn
->
type
),
nil
,
ha
,
hv1
));
}
n
->
ntest
=
nod
(
ONE
,
hv1
,
nodintconst
(
0
));
n
->
ntest
->
ninit
=
list
(
list1
(
nod
(
OAS
,
ohv1
,
hv1
)),
a
);
body
=
list1
(
nod
(
OAS
,
v1
,
ohv1
));
if
(
v2
!=
N
)
body
=
list
(
body
,
nod
(
OAS
,
v2
,
hv2
));
break
;
}
n
->
op
=
OFOR
;
typechecklist
(
init
,
Etop
);
n
->
ninit
=
concat
(
n
->
ninit
,
init
);
typechecklist
(
n
->
ntest
->
ninit
,
Etop
);
typecheck
(
&
n
->
ntest
,
Erv
);
typecheck
(
&
n
->
nincr
,
Etop
);
typechecklist
(
body
,
Etop
);
n
->
nbody
=
concat
(
body
,
n
->
nbody
);
walkstmt
(
&
n
);
}
src/cmd/gc/select.c
View file @
26097317
...
@@ -8,32 +8,6 @@
...
@@ -8,32 +8,6 @@
#include "go.h"
#include "go.h"
/*
* declare v in
* case v := <-chan // select and switch
* called during parse
*/
Node
*
selectas
(
Node
*
name
,
Node
*
expr
,
NodeList
**
init
)
{
Type
*
t
;
if
(
expr
==
N
||
expr
->
op
!=
ORECV
)
goto
bad
;
walkexpr
(
&
expr
->
left
,
init
);
t
=
expr
->
left
->
type
;
if
(
t
==
T
)
goto
bad
;
if
(
t
->
etype
!=
TCHAN
)
goto
bad
;
t
=
t
->
type
;
return
old2new
(
name
,
t
,
init
);
bad:
return
name
;
}
void
void
typecheckselect
(
Node
*
sel
)
typecheckselect
(
Node
*
sel
)
{
{
...
...
src/cmd/gc/subr.c
View file @
26097317
...
@@ -582,11 +582,6 @@ dodump(Node *n, int dep)
...
@@ -582,11 +582,6 @@ dodump(Node *n, int dep)
print
(
"%O-ntype
\n
"
,
n
->
op
);
print
(
"%O-ntype
\n
"
,
n
->
op
);
dodump
(
n
->
ntype
,
dep
+
1
);
dodump
(
n
->
ntype
,
dep
+
1
);
}
}
if
(
n
->
defn
!=
nil
&&
n
->
defn
->
op
!=
OAS
&&
n
->
defn
->
op
!=
OAS2
)
{
indent
(
dep
);
print
(
"%O-defn
\n
"
,
n
->
op
);
dodump
(
n
->
defn
,
dep
+
1
);
}
if
(
n
->
list
!=
nil
)
{
if
(
n
->
list
!=
nil
)
{
indent
(
dep
);
indent
(
dep
);
print
(
"%O-list
\n
"
,
n
->
op
);
print
(
"%O-list
\n
"
,
n
->
op
);
...
@@ -597,6 +592,11 @@ dodump(Node *n, int dep)
...
@@ -597,6 +592,11 @@ dodump(Node *n, int dep)
print
(
"%O-rlist
\n
"
,
n
->
op
);
print
(
"%O-rlist
\n
"
,
n
->
op
);
dodumplist
(
n
->
rlist
,
dep
+
1
);
dodumplist
(
n
->
rlist
,
dep
+
1
);
}
}
if
(
n
->
nbody
!=
nil
)
{
indent
(
dep
);
print
(
"%O-nbody
\n
"
,
n
->
op
);
dodumplist
(
n
->
nbody
,
dep
+
1
);
}
}
}
void
void
...
@@ -2466,10 +2466,8 @@ out:
...
@@ -2466,10 +2466,8 @@ out:
yyerror
(
"ambiguous DOT reference %T.%S"
,
t
,
s
);
yyerror
(
"ambiguous DOT reference %T.%S"
,
t
,
s
);
// rebuild elided dots
// rebuild elided dots
for
(
c
=
d
-
1
;
c
>=
0
;
c
--
)
{
for
(
c
=
d
-
1
;
c
>=
0
;
c
--
)
n
=
nod
(
ODOT
,
n
,
n
->
right
);
n
->
left
=
nod
(
ODOT
,
n
->
left
,
newname
(
dotlist
[
c
].
field
->
sym
));
n
->
left
->
right
=
newname
(
dotlist
[
c
].
field
->
sym
);
}
ret:
ret:
return
n
;
return
n
;
}
}
...
@@ -2705,7 +2703,7 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam)
...
@@ -2705,7 +2703,7 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam)
args
=
list
(
args
,
l
->
n
->
left
);
args
=
list
(
args
,
l
->
n
->
left
);
// generate call
// generate call
call
=
nod
(
OCALL
,
adddot
(
nod
(
ODOT
,
this
->
left
,
newname
(
method
->
sym
))),
N
);
call
=
nod
(
OCALL
,
adddot
(
nod
(
O
X
DOT
,
this
->
left
,
newname
(
method
->
sym
))),
N
);
call
->
list
=
args
;
call
->
list
=
args
;
fn
->
nbody
=
list1
(
call
);
fn
->
nbody
=
list1
(
call
);
if
(
method
->
type
->
outtuple
>
0
)
{
if
(
method
->
type
->
outtuple
>
0
)
{
...
...
src/cmd/gc/typecheck.c
View file @
26097317
...
@@ -12,7 +12,6 @@
...
@@ -12,7 +12,6 @@
*
*
* TODO:
* TODO:
* trailing ... section of function calls
* trailing ... section of function calls
* range
*/
*/
#include "go.h"
#include "go.h"
...
@@ -376,6 +375,10 @@ reswitch:
...
@@ -376,6 +375,10 @@ reswitch:
goto
error
;
goto
error
;
goto
ret
;
goto
ret
;
case
OXDOT
:
n
=
adddot
(
n
);
n
->
op
=
ODOT
;
// fall through
case
ODOT
:
case
ODOT
:
l
=
typecheck
(
&
n
->
left
,
Erv
);
l
=
typecheck
(
&
n
->
left
,
Erv
);
if
((
t
=
l
->
type
)
==
T
)
if
((
t
=
l
->
type
)
==
T
)
...
@@ -882,6 +885,11 @@ reswitch:
...
@@ -882,6 +885,11 @@ reswitch:
typecheckswitch
(
n
);
typecheckswitch
(
n
);
goto
ret
;
goto
ret
;
case
ORANGE
:
ok
|=
Etop
;
typecheckrange
(
n
);
goto
ret
;
case
OTYPECASE
:
case
OTYPECASE
:
ok
|=
Etop
|
Erv
;
ok
|=
Etop
|
Erv
;
typecheck
(
&
n
->
left
,
Erv
);
typecheck
(
&
n
->
left
,
Erv
);
...
@@ -1069,7 +1077,7 @@ nokeys(NodeList *l)
...
@@ -1069,7 +1077,7 @@ nokeys(NodeList *l)
return
1
;
return
1
;
}
}
static
int
int
checkconv
(
Type
*
nt
,
Type
*
t
,
int
explicit
,
int
*
op
,
int
*
et
)
checkconv
(
Type
*
nt
,
Type
*
t
,
int
explicit
,
int
*
op
,
int
*
et
)
{
{
*
op
=
OCONV
;
*
op
=
OCONV
;
...
...
src/cmd/gc/walk.c
View file @
26097317
...
@@ -285,7 +285,10 @@ walkstmt(Node **np)
...
@@ -285,7 +285,10 @@ walkstmt(Node **np)
case
OFOR
:
case
OFOR
:
walkstmtlist
(
n
->
ninit
);
walkstmtlist
(
n
->
ninit
);
walkexpr
(
&
n
->
ntest
,
&
n
->
ntest
->
ninit
);
if
(
n
->
ntest
!=
N
)
{
walkstmtlist
(
n
->
ntest
->
ninit
);
walkexpr
(
&
n
->
ntest
,
&
n
->
ntest
->
ninit
);
}
walkstmt
(
&
n
->
nincr
);
walkstmt
(
&
n
->
nincr
);
walkstmtlist
(
n
->
nbody
);
walkstmtlist
(
n
->
nbody
);
break
;
break
;
...
@@ -319,6 +322,10 @@ walkstmt(Node **np)
...
@@ -319,6 +322,10 @@ walkstmt(Node **np)
walkswitch
(
n
);
walkswitch
(
n
);
break
;
break
;
case
ORANGE
:
walkrange
(
n
);
break
;
case
OXFALL
:
case
OXFALL
:
yyerror
(
"fallthrough statement out of place"
);
yyerror
(
"fallthrough statement out of place"
);
n
->
op
=
OFALL
;
n
->
op
=
OFALL
;
...
@@ -1702,264 +1709,6 @@ out:
...
@@ -1702,264 +1709,6 @@ out:
return
n
;
return
n
;
}
}
/*
* rewrite a range statement
* k and v are names/new_names
* m is an array or map
* local is 0 (meaning =) or 1 (meaning :=)
*/
Node
*
dorange
(
Node
*
nn
)
{
Node
*
k
,
*
v
,
*
m
;
Node
*
n
,
*
hv
,
*
hc
,
*
ha
,
*
hk
,
*
ohk
,
*
on
,
*
r
,
*
a
,
*
as
;
NodeList
*
init
,
*
args
;
Type
*
t
,
*
th
;
int
local
;
NodeList
*
nl
;
if
(
nn
->
op
!=
ORANGE
)
fatal
(
"dorange not ORANGE"
);
nl
=
nn
->
list
;
k
=
nl
->
n
;
if
((
nl
=
nl
->
next
)
!=
nil
)
{
v
=
nl
->
n
;
nl
=
nl
->
next
;
}
else
v
=
N
;
if
(
nl
!=
nil
)
yyerror
(
"too many variables in range"
);
n
=
nod
(
OFOR
,
N
,
N
);
init
=
nil
;
typecheck
(
&
nn
->
right
,
Erv
);
m
=
nn
->
right
;
local
=
nn
->
etype
;
t
=
m
->
type
;
if
(
t
==
T
)
goto
out
;
if
(
t
->
etype
==
TARRAY
)
goto
ary
;
if
(
t
->
etype
==
TMAP
)
goto
map
;
if
(
t
->
etype
==
TCHAN
)
goto
chan
;
if
(
t
->
etype
==
TSTRING
)
goto
strng
;
yyerror
(
"range must be over map/array/chan/string"
);
goto
out
;
ary:
hk
=
nod
(
OXXX
,
N
,
N
);
// hidden key
tempname
(
hk
,
types
[
TINT
]);
ha
=
nod
(
OXXX
,
N
,
N
);
// hidden array
tempname
(
ha
,
t
);
a
=
nod
(
OAS
,
hk
,
nodintconst
(
0
));
init
=
list
(
init
,
a
);
a
=
nod
(
OAS
,
ha
,
m
);
init
=
list
(
init
,
a
);
n
->
ntest
=
nod
(
OLT
,
hk
,
nod
(
OLEN
,
ha
,
N
));
n
->
nincr
=
nod
(
OASOP
,
hk
,
nodintconst
(
1
));
n
->
nincr
->
etype
=
OADD
;
if
(
local
)
k
=
old2new
(
k
,
hk
->
type
,
&
init
);
n
->
nbody
=
list1
(
nod
(
OAS
,
k
,
hk
));
if
(
v
!=
N
)
{
if
(
local
)
v
=
old2new
(
v
,
t
->
type
,
&
init
);
n
->
nbody
=
list
(
n
->
nbody
,
nod
(
OAS
,
v
,
nod
(
OINDEX
,
ha
,
hk
))
);
}
goto
out
;
map:
th
=
typ
(
TARRAY
);
th
->
type
=
ptrto
(
types
[
TUINT8
]);
th
->
bound
=
(
sizeof
(
struct
Hiter
)
+
types
[
tptr
]
->
width
-
1
)
/
types
[
tptr
]
->
width
;
hk
=
nod
(
OXXX
,
N
,
N
);
// hidden iterator
tempname
(
hk
,
th
);
// hashmap hash_iter
on
=
syslook
(
"mapiterinit"
,
1
);
argtype
(
on
,
t
->
down
);
argtype
(
on
,
t
->
type
);
argtype
(
on
,
th
);
a
=
nod
(
OADDR
,
hk
,
N
);
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
list
(
list1
(
m
),
a
);
init
=
list
(
init
,
r
);
r
=
nod
(
OINDEX
,
hk
,
nodintconst
(
0
));
a
=
nod
(
OLITERAL
,
N
,
N
);
a
->
val
.
ctype
=
CTNIL
;
a
->
type
=
types
[
TNIL
];
r
=
nod
(
ONE
,
r
,
a
);
n
->
ntest
=
r
;
on
=
syslook
(
"mapiternext"
,
1
);
argtype
(
on
,
th
);
r
=
nod
(
OADDR
,
hk
,
N
);
args
=
list1
(
r
);
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
args
;
n
->
nincr
=
r
;
if
(
local
)
k
=
old2new
(
k
,
t
->
down
,
&
init
);
if
(
v
==
N
)
{
on
=
syslook
(
"mapiter1"
,
1
);
argtype
(
on
,
th
);
argtype
(
on
,
t
->
down
);
r
=
nod
(
OADDR
,
hk
,
N
);
args
=
list1
(
r
);
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
args
;
n
->
nbody
=
list1
(
nod
(
OAS
,
k
,
r
));
goto
out
;
}
if
(
local
)
v
=
old2new
(
v
,
t
->
type
,
&
init
);
on
=
syslook
(
"mapiter2"
,
1
);
argtype
(
on
,
th
);
argtype
(
on
,
t
->
down
);
argtype
(
on
,
t
->
type
);
r
=
nod
(
OADDR
,
hk
,
N
);
args
=
list1
(
r
);
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
args
;
as
=
nod
(
OAS2
,
N
,
N
);
as
->
list
=
list
(
list1
(
k
),
v
);
as
->
rlist
=
list1
(
r
);
n
->
nbody
=
list1
(
as
);
goto
out
;
chan:
if
(
v
!=
N
)
yyerror
(
"chan range can only have one variable"
);
hc
=
nod
(
OXXX
,
N
,
N
);
// hidden chan
tempname
(
hc
,
t
);
hv
=
nod
(
OXXX
,
N
,
N
);
// hidden value
tempname
(
hv
,
t
->
type
);
a
=
nod
(
OAS
,
hc
,
m
);
init
=
list
(
init
,
a
);
a
=
nod
(
ORECV
,
hc
,
N
);
a
=
nod
(
OAS
,
hv
,
a
);
init
=
list
(
init
,
a
);
a
=
nod
(
OCLOSED
,
N
,
N
);
a
->
list
=
list1
(
hc
);
n
->
ntest
=
nod
(
ONOT
,
a
,
N
);
n
->
nincr
=
nod
(
OAS
,
hv
,
nod
(
ORECV
,
hc
,
N
));
if
(
local
)
k
=
old2new
(
k
,
hv
->
type
,
&
init
);
n
->
nbody
=
list1
(
nod
(
OAS
,
k
,
hv
));
goto
out
;
strng:
hk
=
nod
(
OXXX
,
N
,
N
);
// hidden key
tempname
(
hk
,
types
[
TINT
]);
ohk
=
nod
(
OXXX
,
N
,
N
);
// old hidden key
tempname
(
ohk
,
types
[
TINT
]);
ha
=
nod
(
OXXX
,
N
,
N
);
// hidden string
tempname
(
ha
,
types
[
TSTRING
]);
hv
=
N
;
if
(
v
!=
N
)
{
hv
=
nod
(
OXXX
,
N
,
N
);
// hidden value
tempname
(
hv
,
types
[
TINT
]);
}
if
(
local
)
{
k
=
old2new
(
k
,
types
[
TINT
],
&
init
);
if
(
v
!=
N
)
v
=
old2new
(
v
,
types
[
TINT
],
&
init
);
}
// ha = s
a
=
nod
(
OCONV
,
m
,
N
);
a
->
type
=
ha
->
type
;
a
=
nod
(
OAS
,
ha
,
a
);
init
=
list
(
init
,
a
);
// ohk = 0
a
=
nod
(
OAS
,
ohk
,
nodintconst
(
0
));
init
=
list
(
init
,
a
);
// hk[,hv] = stringiter(ha,hk)
if
(
v
!=
N
)
{
// hk,v = stringiter2(ha, hk)
on
=
syslook
(
"stringiter2"
,
0
);
a
=
nod
(
OCALL
,
on
,
N
);
a
->
list
=
list
(
list1
(
ha
),
nodintconst
(
0
));
as
=
nod
(
OAS2
,
N
,
N
);
as
->
list
=
list
(
list1
(
hk
),
hv
);
as
->
rlist
=
list1
(
a
);
a
=
as
;
}
else
{
// hk = stringiter(ha, hk)
on
=
syslook
(
"stringiter"
,
0
);
a
=
nod
(
OCALL
,
on
,
N
);
a
->
list
=
list
(
list1
(
ha
),
nodintconst
(
0
));
a
=
nod
(
OAS
,
hk
,
a
);
}
init
=
list
(
init
,
a
);
// while(hk != 0)
n
->
ntest
=
nod
(
ONE
,
hk
,
nodintconst
(
0
));
// hk[,hv] = stringiter(ha,hk)
if
(
v
!=
N
)
{
// hk,hv = stringiter2(ha, hk)
on
=
syslook
(
"stringiter2"
,
0
);
a
=
nod
(
OCALL
,
on
,
N
);
a
->
list
=
list
(
list1
(
ha
),
hk
);
as
=
nod
(
OAS2
,
N
,
N
);
as
->
list
=
list
(
list1
(
hk
),
hv
);
as
->
rlist
=
list1
(
a
);
a
=
as
;
}
else
{
// hk = stringiter(ha, hk)
on
=
syslook
(
"stringiter"
,
0
);
a
=
nod
(
OCALL
,
on
,
N
);
a
->
list
=
list
(
list1
(
ha
),
hk
);
a
=
nod
(
OAS
,
hk
,
a
);
}
n
->
nincr
=
a
;
// k,ohk[,v] = ohk,hk,[,hv]
a
=
nod
(
OAS
,
k
,
ohk
);
n
->
nbody
=
list1
(
a
);
a
=
nod
(
OAS
,
ohk
,
hk
);
n
->
nbody
=
list
(
n
->
nbody
,
a
);
if
(
v
!=
N
)
{
a
=
nod
(
OAS
,
v
,
hv
);
n
->
nbody
=
list
(
n
->
nbody
,
a
);
}
out:
n
->
ninit
=
concat
(
n
->
ninit
,
init
);
return
n
;
}
/*
/*
* from ascompat[te]
* from ascompat[te]
* evaluating actual function arguments.
* evaluating actual function arguments.
...
...
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