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
a2b8e387
Commit
a2b8e387
authored
Jul 31, 2009
by
Russ Cox
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
checkpoint; still plenty to clean up
R=ken OCL=32576 CL=32580
parent
9299ae46
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
490 additions
and
1039 deletions
+490
-1039
src/cmd/gc/Makefile
src/cmd/gc/Makefile
+5
-0
src/cmd/gc/builtin.c.boot
src/cmd/gc/builtin.c.boot
+1
-1
src/cmd/gc/dcl.c
src/cmd/gc/dcl.c
+1
-1
src/cmd/gc/go.h
src/cmd/gc/go.h
+69
-40
src/cmd/gc/mkbuiltin
src/cmd/gc/mkbuiltin
+1
-1
src/cmd/gc/mkbuiltin1.c
src/cmd/gc/mkbuiltin1.c
+1
-1
src/cmd/gc/subr.c
src/cmd/gc/subr.c
+4
-124
src/cmd/gc/swt.c
src/cmd/gc/swt.c
+3
-3
src/cmd/gc/sys.go
src/cmd/gc/sys.go
+1
-2
src/cmd/gc/typecheck.c
src/cmd/gc/typecheck.c
+15
-4
src/cmd/gc/walk.c
src/cmd/gc/walk.c
+389
-862
No files found.
src/cmd/gc/Makefile
View file @
a2b8e387
...
...
@@ -52,6 +52,11 @@ builtin.c: sys.go unsafe.go mkbuiltin1.c mkbuiltin
./mkbuiltin
>
builtin.c
||
\
(
echo
'mkbuiltin failed; using bootstrap copy of builtin.c'
;
cp
builtin.c.boot builtin.c
)
subr.$O
:
opnames.h
opnames.h
:
mkopnames go.h
./mkopnames go.h
>
opnames.h
clean
:
rm
-f
$(OFILES)
*
.6 enam.c 6.out a.out y.tab.h y.tab.c
$(LIB)
mkbuiltin1 builtin.c _builtin.c
...
...
src/cmd/gc/builtin.c.boot
View file @
a2b8e387
...
...
@@ -4,7 +4,7 @@ char *sysimport =
"func sys.throwindex ()\n"
"func sys.throwreturn ()\n"
"func sys.throwinit ()\n"
"func sys.panicl (
? int32
)\n"
"func sys.panicl ()\n"
"func sys.printbool (? bool)\n"
"func sys.printfloat (? float64)\n"
"func sys.printint (? int64)\n"
...
...
src/cmd/gc/dcl.c
View file @
a2b8e387
...
...
@@ -1670,7 +1670,7 @@ variter(NodeList *vl, Node *nt, NodeList *el)
v
=
vl
->
n
;
tv
=
t
;
if
(
t
==
T
)
{
gettype
(
&
e
,
&
r
);
typecheck
(
&
e
,
Erv
);
defaultlit
(
&
e
,
T
);
tv
=
e
->
type
;
}
...
...
src/cmd/gc/go.h
View file @
a2b8e387
...
...
@@ -320,43 +320,75 @@ enum
{
OXXX
,
ONAME
,
ONONAME
,
OTYPE
,
OPACK
,
OLITERAL
,
ODCL
,
ODOT
,
ODOTPTR
,
ODOTMETH
,
ODOTINTER
,
ODCLFUNC
,
ODCLFIELD
,
ODCLARG
,
OCMP
,
OPTR
,
OARRAY
,
ORANGE
,
ORETURN
,
OFOR
,
OIF
,
OSWITCH
,
ODEFER
,
OAS
,
OAS2
,
OASOP
,
OCASE
,
OXCASE
,
OFALL
,
OXFALL
,
OGOTO
,
OPROC
,
OMAKE
,
ONEW
,
OEMPTY
,
OSELECT
,
OLEN
,
OCAP
,
OPANIC
,
OPANICN
,
OPRINT
,
OPRINTN
,
OTYPEOF
,
OCLOSE
,
OCLOSED
,
OBLOCK
,
OOROR
,
// names
ONAME
,
ONONAME
,
OTYPE
,
OPACK
,
OLITERAL
,
// exprs
OADD
,
OSUB
,
OOR
,
OXOR
,
OADDR
,
OANDAND
,
OARRAY
,
OAS
,
OAS2
,
OASOP
,
OBAD
,
OCALL
,
OCALLFUNC
,
OCALLMETH
,
OCALLINTER
,
OCAP
,
OCLOSE
,
OCLOSED
,
OCOMPOS
,
OCOMPSLICE
,
OCOMPMAP
,
OCONV
,
OCONVNOP
,
OCONVRUNE
,
OCONVSTRB
,
OCONVSTRI
,
OCONVA2S
,
ODCL
,
ODCLFUNC
,
ODCLFIELD
,
ODCLARG
,
ODOT
,
ODOTPTR
,
ODOTMETH
,
ODOTINTER
,
ODOTTYPE
,
OEQ
,
ONE
,
OLT
,
OLE
,
OGE
,
OGT
,
OADD
,
OSUB
,
OOR
,
OXOR
,
OMUL
,
ODIV
,
OMOD
,
OLSH
,
ORSH
,
OAND
,
OANDNOT
,
OINC
,
ODEC
,
OFUNC
,
OLABEL
,
OBREAK
,
OCONTINUE
,
OADDR
,
OIND
,
OCALL
,
OCALLFUNC
,
OCALLMETH
,
OCALLINTER
,
OINDEX
,
OSLICE
,
ONOT
,
OCOM
,
OPLUS
,
OMINUS
,
OSEND
,
ORECV
,
OREGISTER
,
OINDREG
,
OINDEX
,
OINDEXSTR
,
OINDEXMAP
,
OINDEXARR
,
OKEY
,
OPARAM
,
OCOMPOS
,
OCOMPSLICE
,
OCOMPMAP
,
OCONV
,
OCONVNOP
,
OCONVRUNE
,
OCONVSTRB
,
OCONVSTRI
,
OCONVA2S
,
ODOTTYPE
,
OTYPESW
,
OTYPECASE
,
OBAD
,
OTCHAN
,
OTMAP
,
OTSTRUCT
,
OTINTER
,
OTFUNC
,
OTARRAY
,
OLEN
,
OMAKE
,
OMUL
,
ODIV
,
OMOD
,
OLSH
,
ORSH
,
OAND
,
OANDNOT
,
ONEW
,
ONOT
,
OCOM
,
OPLUS
,
OMINUS
,
OOROR
,
OPANIC
,
OPANICN
,
OPRINT
,
OPRINTN
,
OSEND
,
OSLICE
,
OSLICESTR
,
OSLICEARR
,
ORECV
,
OEXTEND
,
// 6g internal
// stmts
OBLOCK
,
OBREAK
,
OCASE
,
OXCASE
,
OCONTINUE
,
ODEFER
,
OEMPTY
,
OFALL
,
OXFALL
,
OFOR
,
OGOTO
,
OIF
,
OLABEL
,
OPROC
,
ORANGE
,
ORETURN
,
OSELECT
,
OSWITCH
,
OTYPECASE
,
OTYPESW
,
// types
OTCHAN
,
OTMAP
,
OTSTRUCT
,
OTINTER
,
OTFUNC
,
OTARRAY
,
// for back ends
OCMP
,
ODEC
,
OEXTEND
,
OINC
,
OREGISTER
,
OINDREG
,
OEND
,
};
...
...
@@ -936,12 +968,10 @@ Type* pkgtype(Sym*);
/*
* walk.c
*/
void
gettype
(
Node
**
,
NodeList
**
);
void
walk
(
Node
*
);
void
walkstmt
(
Node
**
);
void
walkstmtlist
(
NodeList
*
);
void
walkexpr
(
Node
**
,
int
,
NodeList
**
);
void
walkexprlist
(
NodeList
*
,
int
,
NodeList
**
);
void
walkexprlist
(
NodeList
*
,
NodeList
**
);
void
walkconv
(
Node
**
,
NodeList
**
);
void
walkdottype
(
Node
*
,
NodeList
**
);
void
walkas
(
Node
*
);
...
...
@@ -949,21 +979,20 @@ void walkbool(Node**);
void
walkswitch
(
Node
*
);
void
walkselect
(
Node
*
);
void
walkdot
(
Node
*
,
NodeList
**
);
void
walkexpr
(
Node
**
,
NodeList
**
);
Node
*
ascompatee1
(
int
,
Node
*
,
Node
*
,
NodeList
**
);
NodeList
*
ascompatee
(
int
,
NodeList
*
,
NodeList
*
,
NodeList
**
);
NodeList
*
ascompatet
(
int
,
NodeList
*
,
Type
**
,
int
,
NodeList
**
);
NodeList
*
ascompatte
(
int
,
Type
**
,
NodeList
*
,
int
,
NodeList
**
);
int
ascompat
(
Type
*
,
Type
*
);
Node
*
prcompat
(
NodeList
*
,
int
,
int
);
Node
*
nodpanic
(
int32
);
Node
*
newcompat
(
Node
*
);
Node
*
makecompat
(
Node
*
);
Node
*
stringop
(
Node
*
,
int
,
NodeList
**
);
Node
*
stringop
(
Node
*
,
NodeList
**
);
Type
*
fixmap
(
Type
*
);
Node
*
mapop
(
Node
*
,
int
,
NodeList
**
);
Node
*
mapop
(
Node
*
,
NodeList
**
);
Type
*
fixchan
(
Type
*
);
Node
*
chanop
(
Node
*
,
int
,
NodeList
**
);
Node
*
arrayop
(
Node
*
,
int
);
Node
*
chanop
(
Node
*
,
NodeList
**
);
Node
*
arrayop
(
Node
*
);
Node
*
ifacecvt
(
Type
*
,
Node
*
,
int
);
Node
*
ifaceop
(
Node
*
);
int
ifaceas
(
Type
*
,
Type
*
,
int
);
...
...
src/cmd/gc/mkbuiltin
View file @
a2b8e387
...
...
@@ -16,7 +16,7 @@ rm -f _builtin.c
for
i
in
sys unsafe
do
$GC
-A
$i
.go
./mkbuiltin1
$i
>>
_builtin.c
O
=
$O
./mkbuiltin1
$i
>>
_builtin.c
done
# If _builtin.c has changed vs builtin.c.boot,
...
...
src/cmd/gc/mkbuiltin1.c
View file @
a2b8e387
...
...
@@ -26,7 +26,7 @@ main(int argc, char **argv)
name
=
argv
[
1
];
snprintf
(
initfunc
,
sizeof
(
initfunc
),
"init_%s_function"
,
name
);
snprintf
(
buf
,
sizeof
(
buf
),
"%s.
6"
,
name
);
snprintf
(
buf
,
sizeof
(
buf
),
"%s.
%s"
,
name
,
getenv
(
"O"
)
);
if
((
fin
=
fopen
(
buf
,
"r"
))
==
NULL
)
{
fprintf
(
stderr
,
"open %s: %s
\n
"
,
buf
,
strerror
(
errno
));
exit
(
1
);
...
...
src/cmd/gc/subr.c
View file @
a2b8e387
...
...
@@ -4,6 +4,7 @@
#include "go.h"
#include "y.tab.h"
#include "opnames.h"
void
errorexit
(
void
)
...
...
@@ -612,127 +613,6 @@ dump(char *s, Node *n)
dodump
(
n
,
1
);
}
/*
s%,%,\n%g
s%\n+%\n%g
s%^[ ]*O%%g
s%,.*%%g
s%.+% [O&] = "&",%g
s%^ ........*\]%&~%g
s%~ %%g
|sort
*/
static
char
*
opnames
[]
=
{
[
OADDR
]
=
"ADDR"
,
[
OADD
]
=
"ADD"
,
[
OANDAND
]
=
"ANDAND"
,
[
OANDNOT
]
=
"ANDNOT"
,
[
OAND
]
=
"AND"
,
[
OARRAY
]
=
"ARRAY"
,
[
OASOP
]
=
"ASOP"
,
[
OAS
]
=
"AS"
,
[
OAS2
]
=
"AS2"
,
[
OBAD
]
=
"BAD"
,
[
OBLOCK
]
=
"BLOCK"
,
[
OBREAK
]
=
"BREAK"
,
[
OCALLFUNC
]
=
"CALLFUNC"
,
[
OCALLINTER
]
=
"CALLINTER"
,
[
OCALLMETH
]
=
"CALLMETH"
,
[
OCALL
]
=
"CALL"
,
[
OCAP
]
=
"CAP"
,
[
OCASE
]
=
"CASE"
,
[
OCLOSED
]
=
"CLOSED"
,
[
OCLOSE
]
=
"CLOSE"
,
[
OCMP
]
=
"CMP"
,
[
OCOMPMAP
]
=
"COMPMAP"
,
[
OCOMPOS
]
=
"COMPOS"
,
[
OCOMPSLICE
]
=
"COMPSLICE"
,
[
OCOM
]
=
"COM"
,
[
OCONTINUE
]
=
"CONTINUE"
,
[
OCONV
]
=
"CONV"
,
[
OCONVNOP
]
=
"CONVNOP"
,
[
ODCLARG
]
=
"DCLARG"
,
[
ODCLFIELD
]
=
"DCLFIELD"
,
[
ODCLFUNC
]
=
"DCLFUNC"
,
[
ODCL
]
=
"DCL"
,
[
ODEC
]
=
"DEC"
,
[
ODEFER
]
=
"DEFER"
,
[
ODIV
]
=
"DIV"
,
[
ODOTINTER
]
=
"DOTINTER"
,
[
ODOTMETH
]
=
"DOTMETH"
,
[
ODOTPTR
]
=
"DOTPTR"
,
[
ODOTTYPE
]
=
"DOTTYPE"
,
[
ODOT
]
=
"DOT"
,
[
OEMPTY
]
=
"EMPTY"
,
[
OEND
]
=
"END"
,
[
OEQ
]
=
"EQ"
,
[
OEXTEND
]
=
"EXTEND"
,
[
OFALL
]
=
"FALL"
,
[
OFOR
]
=
"FOR"
,
[
OFUNC
]
=
"FUNC"
,
[
OGE
]
=
"GE"
,
[
OGOTO
]
=
"GOTO"
,
[
OGT
]
=
"GT"
,
[
OIF
]
=
"IF"
,
[
OINC
]
=
"INC"
,
[
OINDEX
]
=
"INDEX"
,
[
OINDREG
]
=
"INDREG"
,
[
OIND
]
=
"IND"
,
[
OKEY
]
=
"KEY"
,
[
OLABEL
]
=
"LABEL"
,
[
OLEN
]
=
"LEN"
,
[
OLE
]
=
"LE"
,
[
OLITERAL
]
=
"LITERAL"
,
[
OLSH
]
=
"LSH"
,
[
OLT
]
=
"LT"
,
[
OMAKE
]
=
"MAKE"
,
[
OMINUS
]
=
"MINUS"
,
[
OMOD
]
=
"MOD"
,
[
OMUL
]
=
"MUL"
,
[
ONAME
]
=
"NAME"
,
[
ONEW
]
=
"NEW"
,
[
ONE
]
=
"NE"
,
[
ONONAME
]
=
"NONAME"
,
[
ONOT
]
=
"NOT"
,
[
OOROR
]
=
"OROR"
,
[
OOR
]
=
"OR"
,
[
OPANICN
]
=
"PANICN"
,
[
OPANIC
]
=
"PANIC"
,
[
OPACK
]
=
"PACK"
,
[
OPARAM
]
=
"PARAM"
,
[
OPLUS
]
=
"PLUS"
,
[
OPRINTN
]
=
"PRINTN"
,
[
OPRINT
]
=
"PRINT"
,
[
OPROC
]
=
"PROC"
,
[
OPTR
]
=
"PTR"
,
[
ORANGE
]
=
"RANGE"
,
[
ORECV
]
=
"RECV"
,
[
OREGISTER
]
=
"REGISTER"
,
[
ORETURN
]
=
"RETURN"
,
[
ORSH
]
=
"RSH"
,
[
OSELECT
]
=
"SELECT"
,
[
OSEND
]
=
"SEND"
,
[
OSLICE
]
=
"SLICE"
,
[
OSUB
]
=
"SUB"
,
[
OSWITCH
]
=
"SWITCH"
,
[
OTCHAN
]
=
"TCHAN"
,
[
OTMAP
]
=
"TMAP"
,
[
OTSTRUCT
]
=
"TSTRUCT"
,
[
OTINTER
]
=
"TINTER"
,
[
OTFUNC
]
=
"TFUNC"
,
[
OTARRAY
]
=
"TARRAY"
,
[
OTYPEOF
]
=
"TYPEOF"
,
[
OTYPESW
]
=
"TYPESW"
,
[
OTYPE
]
=
"TYPE"
,
[
OXCASE
]
=
"XCASE"
,
[
OXFALL
]
=
"XFALL"
,
[
OXOR
]
=
"XOR"
,
[
OXXX
]
=
"XXX"
,
};
static
char
*
goopnames
[]
=
{
...
...
@@ -2395,7 +2275,7 @@ saferef(Node *n, NodeList **init)
*
r
=
*
n
;
r
->
left
=
l
;
typecheck
(
&
r
,
Elv
);
walkexpr
(
&
r
,
Elv
,
init
);
walkexpr
(
&
r
,
init
);
return
r
;
case
OINDEX
:
...
...
@@ -2405,11 +2285,11 @@ saferef(Node *n, NodeList **init)
tempname
(
l
,
ptrto
(
n
->
type
));
a
=
nod
(
OAS
,
l
,
nod
(
OADDR
,
n
,
N
));
typecheck
(
&
a
,
Etop
);
walkexpr
(
&
a
,
Etop
,
init
);
walkexpr
(
&
a
,
init
);
*
init
=
list
(
*
init
,
a
);
r
=
nod
(
OIND
,
l
,
N
);
typecheck
(
&
r
,
Elv
);
walkexpr
(
&
r
,
Elv
,
init
);
walkexpr
(
&
r
,
init
);
return
r
;
}
fatal
(
"saferef %N"
,
n
);
...
...
src/cmd/gc/swt.c
View file @
a2b8e387
...
...
@@ -250,7 +250,7 @@ sw0(Node **cp, Type *place, int arg)
yyerror
(
"expression case in a type switch"
);
return
T
;
}
walkexpr
(
cp
,
Erv
,
nil
);
walkexpr
(
cp
,
nil
);
break
;
case
OTYPESW
:
case
OTYPECASE
:
...
...
@@ -596,7 +596,7 @@ exprswitch(Node *sw)
if
(
sw
->
ntest
->
val
.
u
.
bval
==
0
)
arg
=
Sfalse
;
}
walkexpr
(
&
sw
->
ntest
,
Erv
,
&
sw
->
ninit
);
walkexpr
(
&
sw
->
ntest
,
&
sw
->
ninit
);
/*
* pass 0,1,2,3
...
...
@@ -780,7 +780,7 @@ typeswitch(Node *sw)
yyerror
(
"type switch must have an assignment"
);
return
;
}
walkexpr
(
&
sw
->
ntest
->
right
,
Erv
,
&
sw
->
ninit
);
walkexpr
(
&
sw
->
ntest
->
right
,
&
sw
->
ninit
);
if
(
!
istype
(
sw
->
ntest
->
right
->
type
,
TINTER
))
{
yyerror
(
"type switch must be on an interface"
);
return
;
...
...
src/cmd/gc/sys.go
View file @
a2b8e387
...
...
@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
PACKAGE
// emitted by compiler, not referred to by go programs
...
...
@@ -11,7 +10,7 @@ func mal(int32) *any;
func
throwindex
();
func
throwreturn
();
func
throwinit
();
func
panicl
(
int32
);
func
panicl
();
func
printbool
(
bool
);
func
printfloat
(
float64
);
...
...
src/cmd/gc/typecheck.c
View file @
a2b8e387
...
...
@@ -315,7 +315,9 @@ reswitch:
* exprs
*/
case
OADDR
:
l
=
typecheck
(
&
n
->
left
,
Elv
);
typecheck
(
&
n
->
left
,
Elv
);
defaultlit
(
&
n
->
left
,
T
);
l
=
n
->
left
;
if
((
t
=
l
->
type
)
==
T
)
goto
error
;
n
->
type
=
ptrto
(
t
);
...
...
@@ -452,6 +454,9 @@ reswitch:
break
;
case
TMAP
:
n
->
etype
=
0
;
if
(
top
&
Elv
)
n
->
etype
=
1
;
// clumsy hack
ok
|=
Erv
|
Elv
;
defaultlit
(
&
n
->
right
,
t
->
down
);
n
->
type
=
t
->
type
;
...
...
@@ -499,6 +504,9 @@ reswitch:
if
((
t
=
r
->
type
)
==
T
)
goto
error
;
// TODO: more aggressive
n
->
etype
=
0
;
if
(
top
&
Erv
)
n
->
etype
=
1
;
// clumsy hack
ok
|=
Etop
|
Erv
;
n
->
type
=
types
[
TBOOL
];
goto
ret
;
...
...
@@ -539,12 +547,15 @@ reswitch:
goto
error
;
case
TARRAY
:
ok
|=
Elv
;
n
=
arrayop
(
n
,
Erv
);
n
->
type
=
typ
(
TARRAY
);
n
->
type
->
type
=
t
;
n
->
type
->
bound
=
-
1
;
n
=
arrayop
(
n
);
break
;
case
TSTRING
:
n
=
stringop
(
n
,
Erv
,
nil
);
n
->
type
=
t
;
n
=
stringop
(
n
,
nil
);
break
;
}
goto
ret
;
...
...
src/cmd/gc/walk.c
View file @
a2b8e387
...
...
@@ -6,6 +6,13 @@
static
Node
*
curfn
;
static
Node
*
prcompat
(
Node
*
);
static
Node
*
mkcall
(
char
*
,
Type
*
,
NodeList
**
,
...);
static
Node
*
mkcall1
(
Node
*
,
Type
*
,
NodeList
**
,
...);
static
Node
*
conv
(
Node
*
,
Type
*
);
static
Node
*
chanfn
(
char
*
,
int
,
Type
*
);
static
Node
*
mapfn
(
char
*
,
Type
*
);
enum
{
Inone
,
...
...
@@ -72,6 +79,7 @@ void
walk
(
Node
*
fn
)
{
char
s
[
50
];
// int nerr;
curfn
=
fn
;
if
(
debug
[
'W'
])
{
...
...
@@ -81,7 +89,12 @@ walk(Node *fn)
if
(
curfn
->
type
->
outtuple
)
if
(
walkret
(
curfn
->
nbody
))
yyerror
(
"function ends without a return statement"
);
// nerr = nerrors;
typechecklist
(
curfn
->
nbody
,
Etop
);
/* TODO(rsc)
if(nerrors != nerr)
return;
*/
walkstmtlist
(
curfn
->
nbody
);
if
(
debug
[
'W'
])
{
snprint
(
s
,
sizeof
(
s
),
"after walk %S"
,
curfn
->
nname
->
sym
);
...
...
@@ -228,7 +241,7 @@ walkstmt(Node **np)
case
OEMPTY
:
init
=
n
->
ninit
;
n
->
ninit
=
nil
;
walkexpr
(
&
n
,
Etop
,
&
init
);
walkexpr
(
&
n
,
&
init
);
n
->
ninit
=
concat
(
init
,
n
->
ninit
);
break
;
...
...
@@ -253,7 +266,7 @@ walkstmt(Node **np)
case
ODEFER
:
hasdefer
=
1
;
walkexpr
(
&
n
->
left
,
Etop
,
&
n
->
ninit
);
walkexpr
(
&
n
->
left
,
&
n
->
ninit
);
break
;
case
OFOR
:
...
...
@@ -271,11 +284,11 @@ walkstmt(Node **np)
break
;
case
OPROC
:
walkexpr
(
&
n
->
left
,
Etop
,
&
n
->
ninit
);
walkexpr
(
&
n
->
left
,
&
n
->
ninit
);
break
;
case
ORETURN
:
walkexprlist
(
n
->
list
,
Erv
,
&
n
->
ninit
);
walkexprlist
(
n
->
list
,
&
n
->
ninit
);
if
(
curfn
->
type
->
outnamed
&&
n
->
list
==
nil
)
{
// print("special return\n");
break
;
...
...
@@ -311,20 +324,20 @@ walkstmt(Node **np)
*/
void
walkexprlist
(
NodeList
*
l
,
int
top
,
NodeList
**
init
)
walkexprlist
(
NodeList
*
l
,
NodeList
**
init
)
{
for
(;
l
;
l
=
l
->
next
)
walkexpr
(
&
l
->
n
,
top
,
init
);
walkexpr
(
&
l
->
n
,
init
);
}
void
walkexpr
(
Node
**
np
,
int
top
,
NodeList
**
init
)
walkexpr
(
Node
**
np
,
NodeList
**
init
)
{
Node
*
r
,
*
l
;
NodeList
*
ll
,
*
lr
;
Type
*
t
;
Sym
*
s
;
int
et
,
cl
,
cr
,
typeok
,
op
;
int
et
,
cl
,
cr
;
int32
lno
;
Node
*
n
;
...
...
@@ -334,10 +347,8 @@ walkexpr(Node **np, int top, NodeList **init)
return
;
lno
=
setlineno
(
n
);
typeok
=
top
&
Etype
;
top
&=
~
Etype
;
if
(
debug
[
'w'
]
>
1
&&
top
==
Etop
)
if
(
debug
[
'w'
]
>
1
)
dump
(
"walk-before"
,
n
);
if
(
n
->
typecheck
!=
1
)
{
...
...
@@ -377,51 +388,36 @@ reswitch:
case
ODOTPTR
:
case
ODOTMETH
:
case
ODOTINTER
:
walkexpr
(
&
n
->
left
,
Erv
,
init
);
goto
ret
;
case
OIND
:
walkexpr
(
&
n
->
left
,
Erv
|
Etype
,
init
);
walkexpr
(
&
n
->
left
,
init
);
goto
ret
;
case
OPRINT
:
if
(
top
!=
Etop
)
goto
nottop
;
walkexprlist
(
n
->
list
,
Erv
,
init
);
n
=
prcompat
(
n
->
list
,
0
,
0
);
//dump("prcompat", n);
case
OLSH
:
case
ORSH
:
case
OAND
:
case
OOR
:
case
OXOR
:
case
OANDAND
:
case
OOROR
:
case
OSUB
:
case
OMUL
:
walkexpr
(
&
n
->
left
,
init
);
walkexpr
(
&
n
->
right
,
init
);
goto
ret
;
case
OPRINT
:
case
OPRINTN
:
if
(
top
!=
Etop
)
goto
nottop
;
walkexprlist
(
n
->
list
,
Erv
,
init
);
n
=
prcompat
(
n
->
list
,
1
,
0
);
goto
ret
;
case
OPANIC
:
if
(
top
!=
Etop
)
goto
nottop
;
walkexprlist
(
n
->
list
,
Erv
,
init
);
n
=
prcompat
(
n
->
list
,
0
,
1
);
goto
ret
;
case
OPANICN
:
if
(
top
!=
Etop
)
goto
nottop
;
walkexprlist
(
n
->
list
,
Erv
,
init
);
n
=
prcompat
(
n
->
list
,
2
,
1
);
walkexprlist
(
n
->
list
,
init
);
n
=
prcompat
(
n
);
goto
ret
;
case
OLITERAL
:
if
(
!
(
top
&
Erv
))
goto
nottop
;
n
->
addable
=
1
;
goto
ret
;
case
ONAME
:
if
(
top
==
Etop
)
goto
nottop
;
if
(
!
(
n
->
class
&
PHEAP
)
&&
n
->
class
!=
PPARAMREF
)
n
->
addable
=
1
;
if
(
n
->
type
==
T
)
{
...
...
@@ -437,9 +433,6 @@ reswitch:
goto
ret
;
case
OCALL
:
if
(
top
==
Elv
)
goto
nottop
;
if
(
n
->
left
==
N
)
goto
ret
;
...
...
@@ -450,7 +443,7 @@ reswitch:
goto
reswitch
;
}
walkexpr
(
&
n
->
left
,
Erv
|
Etype
|
Ecall
,
init
);
walkexpr
(
&
n
->
left
,
init
);
defaultlit
(
&
n
->
left
,
T
);
t
=
n
->
left
->
type
;
...
...
@@ -466,8 +459,6 @@ reswitch:
break
;
case
OTYPE
:
n
->
op
=
OCONV
;
if
(
!
(
top
&
Erv
))
goto
nottop
;
// turn CALL(type, arg) into CONV(arg) w/ type.
n
->
type
=
n
->
left
->
type
;
if
(
n
->
list
==
nil
)
{
...
...
@@ -492,22 +483,7 @@ reswitch:
}
dowidth
(
t
);
n
->
type
=
*
getoutarg
(
t
);
switch
(
t
->
outtuple
)
{
case
0
:
if
(
top
==
Erv
)
{
yyerror
(
"function requires a return type"
);
n
->
type
=
types
[
TINT
];
}
break
;
case
1
:
if
(
n
->
type
!=
T
&&
n
->
type
->
type
!=
T
&&
n
->
type
->
type
->
type
!=
T
)
n
->
type
=
n
->
type
->
type
->
type
;
break
;
}
walkexprlist
(
n
->
list
,
Erv
,
init
);
walkexprlist
(
n
->
list
,
init
);
switch
(
n
->
op
)
{
default:
...
...
@@ -545,12 +521,10 @@ reswitch:
goto
ret
;
case
OAS
:
if
(
top
!=
Etop
)
goto
nottop
;
*
init
=
concat
(
*
init
,
n
->
ninit
);
n
->
ninit
=
nil
;
walkexpr
(
&
n
->
left
,
Elv
,
init
);
walkexpr
(
&
n
->
right
,
Erv
,
init
);
walkexpr
(
&
n
->
left
,
init
);
walkexpr
(
&
n
->
right
,
init
);
l
=
n
->
left
;
r
=
n
->
right
;
if
(
l
==
N
||
r
==
N
)
...
...
@@ -561,18 +535,16 @@ reswitch:
goto
ret
;
case
OAS2
:
if
(
top
!=
Etop
)
goto
nottop
;
*
init
=
concat
(
*
init
,
n
->
ninit
);
n
->
ninit
=
nil
;
walkexprlist
(
n
->
list
,
Elv
,
init
);
walkexprlist
(
n
->
list
,
init
);
cl
=
count
(
n
->
list
);
cr
=
count
(
n
->
rlist
);
if
(
cl
==
cr
)
{
multias:
walkexprlist
(
n
->
rlist
,
Erv
,
init
);
walkexprlist
(
n
->
rlist
,
init
);
ll
=
ascompatee
(
OAS
,
n
->
list
,
n
->
rlist
,
init
);
ll
=
reorder3
(
ll
);
n
=
liststmt
(
ll
);
...
...
@@ -590,7 +562,7 @@ reswitch:
case
OCALL
:
if
(
cr
==
1
)
{
// a,b,... = fn()
walkexpr
(
&
r
,
Erv
,
init
);
walkexpr
(
&
r
,
init
);
if
(
r
->
type
==
T
||
r
->
type
->
etype
!=
TSTRUCT
)
break
;
ll
=
ascompatet
(
n
->
op
,
n
->
list
,
&
r
->
type
,
0
,
init
);
...
...
@@ -602,10 +574,10 @@ reswitch:
case
OINDEX
:
if
(
cl
==
2
&&
cr
==
1
)
{
// a,b = map[] - mapaccess2
walkexpr
(
&
r
->
left
,
Erv
,
init
);
walkexpr
(
&
r
->
left
,
init
);
if
(
!
istype
(
r
->
left
->
type
,
TMAP
))
break
;
l
=
mapop
(
n
,
top
,
init
);
l
=
mapop
(
n
,
init
);
if
(
l
==
N
)
break
;
n
=
l
;
...
...
@@ -616,10 +588,10 @@ reswitch:
case
ORECV
:
if
(
cl
==
2
&&
cr
==
1
)
{
// a,b = <chan - chanrecv2
walkexpr
(
&
r
->
left
,
Erv
,
init
);
walkexpr
(
&
r
->
left
,
init
);
if
(
!
istype
(
r
->
left
->
type
,
TCHAN
))
break
;
l
=
chanop
(
n
,
top
,
init
);
l
=
chanop
(
n
,
init
);
if
(
l
==
N
)
break
;
n
=
l
;
...
...
@@ -676,7 +648,7 @@ reswitch:
// map[] = a,b - mapassign2
if
(
!
istype
(
l
->
left
->
type
,
TMAP
))
break
;
l
=
mapop
(
n
,
top
,
init
);
l
=
mapop
(
n
,
init
);
if
(
l
==
N
)
break
;
n
=
l
;
...
...
@@ -694,13 +666,11 @@ reswitch:
walkdottype
(
n
,
init
);
// fall through
case
OCONV
:
if
(
!
(
top
&
Erv
))
goto
nottop
;
walkconv
(
&
n
,
init
);
goto
ret
;
case
OCOMPOS
:
walkexpr
(
&
n
->
right
,
Etype
,
init
);
walkexpr
(
&
n
->
right
,
init
);
t
=
n
->
right
->
type
;
n
->
type
=
t
;
if
(
t
==
T
)
...
...
@@ -727,47 +697,43 @@ reswitch:
goto
ret
;
case
OASOP
:
if
(
top
!=
Etop
)
goto
nottop
;
walkexpr
(
&
n
->
left
,
Elv
,
init
);
walkexpr
(
&
n
->
left
,
init
);
l
=
n
->
left
;
if
(
l
->
op
==
OINDEX
&&
istype
(
l
->
left
->
type
,
TMAP
))
n
=
mapop
(
n
,
top
,
init
);
if
(
n
->
etype
==
OLSH
||
n
->
etype
==
ORSH
)
goto
shft
;
goto
com
;
case
OLSH
:
case
ORSH
:
if
(
!
(
top
&
Erv
))
goto
nottop
;
walkexpr
(
&
n
->
left
,
Erv
,
init
);
shft:
walkexpr
(
&
n
->
right
,
Erv
,
init
);
if
(
n
->
left
==
N
||
n
->
right
==
N
)
goto
ret
;
evconst
(
n
);
if
(
n
->
op
==
OLITERAL
)
n
=
mapop
(
n
,
init
);
walkexpr
(
&
n
->
right
,
init
);
if
(
n
->
etype
==
OANDNOT
)
{
n
->
etype
=
OAND
;
n
->
right
=
nod
(
OCOM
,
n
->
right
,
N
);
n
->
right
->
type
=
n
->
right
->
left
->
type
;
goto
ret
;
// do NOT defaultlit n->left.
// let parent defaultlit or convlit instead.
defaultlit
(
&
n
->
right
,
types
[
TUINT
]);
if
(
n
->
left
->
type
==
T
||
n
->
right
->
type
==
T
)
}
if
(
istype
(
n
->
left
->
type
,
TSTRING
))
{
n
=
stringop
(
n
,
init
);
goto
ret
;
et
=
n
->
right
->
type
->
etype
;
if
(
issigned
[
et
]
||
!
isint
[
et
])
goto
badt
;
// check of n->left->type happens in second switch.
}
/*
* on 32-bit arch, rewrite 64-bit ops into l = l op r
*/
et
=
n
->
left
->
type
->
etype
;
if
(
widthptr
==
4
&&
(
et
==
TUINT64
||
et
==
TINT64
))
{
l
=
saferef
(
n
->
left
,
init
);
r
=
nod
(
OAS
,
l
,
nod
(
n
->
etype
,
l
,
n
->
right
));
typecheck
(
&
r
,
Etop
);
walkexpr
(
&
r
,
init
);
n
=
r
;
}
goto
ret
;
case
OMOD
:
case
OAND
:
case
OANDNOT
:
case
OOR
:
case
OXOR
:
case
OANDAND
:
case
OOROR
:
walkexpr
(
&
n
->
left
,
init
);
walkexpr
(
&
n
->
right
,
init
);
n
->
op
=
OAND
;
n
->
right
=
nod
(
OCOM
,
n
->
right
,
N
);
n
->
right
->
type
=
n
->
right
->
left
->
type
;
goto
ret
;
case
OEQ
:
case
ONE
:
case
OLT
:
...
...
@@ -775,233 +741,93 @@ reswitch:
case
OGE
:
case
OGT
:
case
OADD
:
case
OSUB
:
case
OMUL
:
case
ODIV
:
if
(
!
(
top
&
Erv
))
goto
nottop
;
walkexpr
(
&
n
->
left
,
Erv
,
init
);
com:
walkexpr
(
&
n
->
right
,
Erv
,
init
);
if
(
n
->
left
==
N
||
n
->
right
==
N
)
walkexpr
(
&
n
->
left
,
init
);
walkexpr
(
&
n
->
right
,
init
);
if
(
istype
(
n
->
left
->
type
,
TSTRING
))
{
n
=
stringop
(
n
,
nil
);
goto
ret
;
if
(
n
->
left
->
type
==
T
||
n
->
right
->
type
==
T
)
goto
ret
;
switch
(
n
->
op
)
{
case
OANDNOT
:
n
->
op
=
OAND
;
n
->
right
=
nod
(
OCOM
,
n
->
right
,
N
);
n
->
right
->
type
=
n
->
right
->
left
->
type
;
break
;
case
OASOP
:
if
(
n
->
etype
==
OANDNOT
)
{
n
->
etype
=
OAND
;
n
->
right
=
nod
(
OCOM
,
n
->
right
,
N
);
n
->
right
->
type
=
n
->
right
->
left
->
type
;
break
;
}
if
(
istype
(
n
->
left
->
type
,
TSTRING
))
{
n
=
stringop
(
n
,
top
,
init
);
goto
ret
;
}
break
;
case
OEQ
:
case
ONE
:
case
OLT
:
case
OLE
:
case
OGE
:
case
OGT
:
case
OADD
:
if
(
istype
(
n
->
left
->
type
,
TSTRING
))
{
n
=
stringop
(
n
,
top
,
nil
);
goto
ret
;
}
break
;
}
switch
(
n
->
op
)
{
case
OEQ
:
case
ONE
:
if
(
isinter
(
n
->
left
->
type
))
{
n
=
ifaceop
(
n
);
goto
ret
;
}
break
;
if
(
isinter
(
n
->
left
->
type
))
{
n
=
ifaceop
(
n
);
goto
ret
;
}
goto
ret
;
case
ODIV
:
case
OMOD
:
/*
* rewrite div and mod into function calls
* on 32-bit architectures.
*/
switch
(
n
->
op
)
{
case
ODIV
:
case
OMOD
:
et
=
n
->
left
->
type
->
etype
;
if
(
widthptr
>
4
||
(
et
!=
TUINT64
&&
et
!=
TINT64
))
break
;
if
(
et
==
TINT64
)
strcpy
(
namebuf
,
"int64"
);
else
strcpy
(
namebuf
,
"uint64"
);
if
(
n
->
op
==
ODIV
)
strcat
(
namebuf
,
"div"
);
else
strcat
(
namebuf
,
"mod"
);
l
=
syslook
(
namebuf
,
0
);
n
->
left
=
nod
(
OCONV
,
n
->
left
,
N
);
n
->
left
->
type
=
types
[
et
];
n
->
right
=
nod
(
OCONV
,
n
->
right
,
N
);
n
->
right
->
type
=
types
[
et
];
r
=
nod
(
OCALL
,
l
,
N
);
r
->
list
=
list
(
list1
(
n
->
left
),
n
->
right
);
r
=
nod
(
OCONV
,
r
,
N
);
r
->
type
=
n
->
left
->
left
->
type
;
typecheck
(
&
r
,
Erv
);
walkexpr
(
&
r
,
Erv
,
init
);
n
=
r
;
break
;
case
OASOP
:
et
=
n
->
left
->
type
->
etype
;
if
(
widthptr
>
4
||
(
et
!=
TUINT64
&&
et
!=
TINT64
))
break
;
l
=
saferef
(
n
->
left
,
init
);
r
=
nod
(
OAS
,
l
,
nod
(
n
->
etype
,
l
,
n
->
right
));
typecheck
(
&
r
,
Etop
);
walkexpr
(
&
r
,
Etop
,
init
);
n
=
r
;
break
;
}
walkexpr
(
&
n
->
left
,
init
);
walkexpr
(
&
n
->
right
,
init
);
et
=
n
->
left
->
type
->
etype
;
if
(
widthptr
>
4
||
(
et
!=
TUINT64
&&
et
!=
TINT64
))
goto
ret
;
if
(
et
==
TINT64
)
strcpy
(
namebuf
,
"int64"
);
else
strcpy
(
namebuf
,
"uint64"
);
if
(
n
->
op
==
ODIV
)
strcat
(
namebuf
,
"div"
);
else
strcat
(
namebuf
,
"mod"
);
n
=
mkcall
(
namebuf
,
n
->
type
,
init
,
conv
(
n
->
left
,
types
[
et
]),
conv
(
n
->
right
,
types
[
et
]));
goto
ret
;
case
OINDEX
:
if
(
top
==
Etop
)
goto
nottop
;
walkexpr
(
&
n
->
left
,
Erv
,
init
);
walkexpr
(
&
n
->
right
,
Erv
,
init
);
walkexpr
(
&
n
->
left
,
init
);
walkexpr
(
&
n
->
right
,
init
);
if
(
n
->
left
==
N
||
n
->
right
==
N
)
goto
ret
;
defaultlit
(
&
n
->
left
,
T
);
t
=
n
->
left
->
type
;
if
(
t
==
T
)
goto
ret
;
switch
(
t
->
etype
)
{
default:
defaultlit
(
&
n
->
right
,
T
);
goto
badt
;
case
TSTRING
:
// right side must be an int
if
(
!
(
top
&
Erv
))
goto
nottop
;
defaultlit
(
&
n
->
right
,
types
[
TINT
]);
if
(
n
->
right
->
type
==
T
)
break
;
if
(
!
isint
[
n
->
right
->
type
->
etype
])
goto
badt
;
n
=
stringop
(
n
,
top
,
nil
);
n
=
stringop
(
n
,
nil
);
break
;
case
TMAP
:
// right side must be map type
defaultlit
(
&
n
->
right
,
t
->
down
);
if
(
n
->
right
->
type
==
T
)
break
;
if
(
!
eqtype
(
n
->
right
->
type
,
t
->
down
))
goto
badt
;
n
->
type
=
t
->
type
;
if
(
top
==
Erv
)
n
=
mapop
(
n
,
top
,
nil
);
break
;
case
TARRAY
:
// right side must be an int
defaultlit
(
&
n
->
right
,
types
[
TINT
]);
if
(
n
->
right
->
type
==
T
)
break
;
if
(
!
isint
[
n
->
right
->
type
->
etype
])
goto
badt
;
n
->
type
=
t
->
type
;
if
(
n
->
etype
!=
1
)
// clumsy hack
n
=
mapop
(
n
,
nil
);
break
;
}
goto
ret
;
case
OCLOSE
:
if
(
top
!=
Etop
)
goto
nottop
;
walkexpr
(
&
n
->
left
,
Erv
,
init
);
// chan
n
=
chanop
(
n
,
top
,
nil
);
goto
ret
;
case
OCLOSED
:
if
(
top
==
Elv
)
goto
nottop
;
walkexpr
(
&
n
->
left
,
Erv
,
init
);
// chan
n
=
chanop
(
n
,
top
,
nil
);
goto
ret
;
case
OSEND
:
if
(
top
==
Elv
)
goto
nottop
;
walkexpr
(
&
n
->
left
,
Erv
,
init
);
// chan
walkexpr
(
&
n
->
right
,
Erv
,
init
);
// e
n
=
chanop
(
n
,
top
,
nil
);
goto
ret
;
case
ORECV
:
if
(
top
==
Elv
)
goto
nottop
;
if
(
n
->
right
==
N
)
{
walkexpr
(
&
n
->
left
,
Erv
,
init
);
// chan
n
=
chanop
(
n
,
top
,
init
);
// returns e blocking
goto
ret
;
}
walkexpr
(
&
n
->
left
,
Elv
,
init
);
// e
walkexpr
(
&
n
->
right
,
Erv
,
init
);
// chan
n
=
chanop
(
n
,
top
,
nil
);
// returns bool non-blocking
walkexpr
(
&
n
->
left
,
init
);
walkexpr
(
&
n
->
right
,
init
);
n
=
chanop
(
n
,
init
);
goto
ret
;
case
OSLICE
:
if
(
top
==
Etop
)
goto
nottop
;
walkexpr
(
&
n
->
left
,
top
,
init
);
walkexpr
(
&
n
->
right
->
left
,
Erv
,
init
);
walkexpr
(
&
n
->
right
->
right
,
Erv
,
init
);
walkexpr
(
&
n
->
left
,
init
);
walkexpr
(
&
n
->
right
->
left
,
init
);
walkexpr
(
&
n
->
right
->
right
,
init
);
if
(
n
->
left
==
N
||
n
->
right
==
N
)
goto
ret
;
defaultlit
(
&
n
->
left
,
T
);
defaultlit
(
&
n
->
right
->
left
,
types
[
TUINT
]);
defaultlit
(
&
n
->
right
->
right
,
types
[
TUINT
]);
t
=
n
->
left
->
type
;
if
(
t
==
T
)
goto
ret
;
if
(
t
->
etype
==
TSTRING
)
{
n
=
stringop
(
n
,
top
,
nil
);
n
=
stringop
(
n
,
nil
);
goto
ret
;
}
if
(
t
->
etype
==
TARRAY
)
{
n
=
arrayop
(
n
,
top
);
n
=
arrayop
(
n
);
goto
ret
;
}
badtype
(
OSLICE
,
n
->
left
->
type
,
T
);
goto
ret
;
case
OADDR
:
if
(
!
(
top
&
Erv
))
goto
nottop
;
defaultlit
(
&
n
->
left
,
T
);
if
(
n
->
left
->
op
==
OCOMPOS
)
{
walkexpr
(
&
n
->
left
->
right
,
Etype
,
init
);
walkexpr
(
&
n
->
left
->
right
,
init
);
n
->
left
->
type
=
n
->
left
->
right
->
type
;
if
(
n
->
left
->
type
==
T
)
goto
ret
;
...
...
@@ -1019,7 +845,7 @@ reswitch:
nas
=
nod
(
OAS
,
nvar
,
callnew
(
n
->
left
->
type
));
typecheck
(
&
nas
,
Etop
);
walkexpr
(
&
nas
,
Etop
,
init
);
walkexpr
(
&
nas
,
init
);
*
init
=
list
(
*
init
,
nas
);
nstar
=
nod
(
OIND
,
nvar
,
N
);
...
...
@@ -1039,7 +865,7 @@ reswitch:
goto
badlit
;
}
// walkexpr(&n->left->left,
Erv,
init);
// walkexpr(&n->left->left, init);
n
=
nvar
;
goto
ret
;
}
...
...
@@ -1053,7 +879,7 @@ reswitch:
}
if
(
n
->
left
==
N
)
goto
ret
;
walkexpr
(
&
n
->
left
,
Elv
,
init
);
walkexpr
(
&
n
->
left
,
init
);
t
=
n
->
left
->
type
;
if
(
t
==
T
)
goto
ret
;
...
...
@@ -1062,21 +888,17 @@ reswitch:
goto
ret
;
case
OMAKE
:
if
(
!
(
top
&
Erv
))
goto
nottop
;
n
=
makecompat
(
n
);
goto
ret
;
case
ONEW
:
if
(
!
(
top
&
Erv
))
goto
nottop
;
if
(
n
->
list
==
nil
)
{
yyerror
(
"missing argument to new"
);
goto
ret
;
}
if
(
n
->
list
->
next
)
yyerror
(
"too many arguments to new"
);
walkexpr
(
&
n
->
list
->
n
,
Etype
,
init
);
walkexpr
(
&
n
->
list
->
n
,
init
);
l
=
n
->
list
->
n
;
if
((
t
=
l
->
type
)
==
T
)
;
...
...
@@ -1084,69 +906,12 @@ reswitch:
n
=
callnew
(
t
);
goto
ret
;
}
fatal
(
"missing switch %#O"
,
n
->
op
);
nottop:
if
(
n
->
diag
)
goto
ret
;
n
->
diag
=
1
;
switch
(
top
|
typeok
)
{
default:
yyerror
(
"didn't expect %O here [top=%d]"
,
n
->
op
,
top
);
break
;
case
Etype
:
yyerror
(
"operation %O not allowed in type context"
,
n
->
op
);
break
;
case
Etop
:
yyerror
(
"operation %O not allowed in statement context"
,
n
->
op
);
break
;
case
Elv
:
yyerror
(
"operation %O not allowed in assignment context"
,
n
->
op
);
break
;
case
Erv
:
case
Erv
|
Etype
:
yyerror
(
"operation %O not allowed in expression context"
,
n
->
op
);
break
;
}
goto
ret
;
badt:
if
(
n
->
diag
)
goto
ret
;
n
->
diag
=
1
;
if
(
n
->
right
==
N
)
{
if
(
n
->
left
==
N
)
{
badtype
(
n
->
op
,
T
,
T
);
goto
ret
;
}
badtype
(
n
->
op
,
n
->
left
->
type
,
T
);
goto
ret
;
}
op
=
n
->
op
;
if
(
op
==
OASOP
)
op
=
n
->
etype
;
badtype
(
op
,
n
->
left
->
type
,
n
->
right
->
type
);
goto
ret
;
fatal
(
"missing switch %O"
,
n
->
op
);
ret:
if
(
debug
[
'w'
]
&&
top
==
Etop
&&
n
!=
N
)
if
(
debug
[
'w'
]
&&
n
!=
N
)
dump
(
"walk"
,
n
);
if
(
typeok
&&
top
==
0
)
{
// must be type
if
(
n
->
op
!=
OTYPE
)
{
if
(
n
->
sym
)
{
if
(
!
n
->
sym
->
undef
)
yyerror
(
"%S is not a type"
,
n
->
sym
);
}
else
{
yyerror
(
"expr %O is not type"
,
n
->
op
);
n
->
op
=
OTYPE
;
// leads to fewer errors later
n
->
type
=
T
;
}
}
}
if
(
!
typeok
&&
n
->
op
==
OTYPE
)
yyerror
(
"cannot use type %T as expr"
,
n
->
type
);
ullmancalc
(
n
);
lineno
=
lno
;
*
np
=
n
;
...
...
@@ -1160,7 +925,7 @@ walkbool(Node **np)
n
=
*
np
;
if
(
n
==
N
)
return
;
walkexpr
(
np
,
Erv
,
&
n
->
ninit
);
walkexpr
(
np
,
&
n
->
ninit
);
defaultlit
(
np
,
T
);
n
=
*
np
;
if
(
n
->
type
!=
T
&&
!
eqtype
(
n
->
type
,
types
[
TBOOL
]))
...
...
@@ -1170,14 +935,11 @@ walkbool(Node **np)
void
walkdottype
(
Node
*
n
,
NodeList
**
init
)
{
walkexpr
(
&
n
->
left
,
Erv
,
init
);
walkexpr
(
&
n
->
left
,
init
);
if
(
n
->
left
==
N
)
return
;
defaultlit
(
&
n
->
left
,
T
);
if
(
!
isinter
(
n
->
left
->
type
))
yyerror
(
"type assertion requires interface on left, have %T"
,
n
->
left
->
type
);
if
(
n
->
right
!=
N
)
{
walkexpr
(
&
n
->
right
,
Etype
,
init
);
walkexpr
(
&
n
->
right
,
init
);
n
->
type
=
n
->
right
->
type
;
n
->
right
=
N
;
}
...
...
@@ -1197,7 +959,7 @@ walkconv(Node **np, NodeList **init)
if
(
t
==
T
)
return
;
typecheck
(
&
n
->
left
,
Erv
);
walkexpr
(
&
n
->
left
,
Erv
,
init
);
walkexpr
(
&
n
->
left
,
init
);
l
=
n
->
left
;
if
(
l
==
N
)
return
;
...
...
@@ -1259,7 +1021,7 @@ walkconv(Node **np, NodeList **init)
if
(
istype
(
t
,
TSTRING
))
{
et
=
l
->
type
->
etype
;
if
(
isint
[
et
])
{
n
=
stringop
(
n
,
Erv
,
nil
);
n
=
stringop
(
n
,
nil
);
*
np
=
n
;
return
;
}
...
...
@@ -1268,7 +1030,7 @@ walkconv(Node **np, NodeList **init)
if
((
isptr
[
et
]
&&
isfixedarray
(
l
->
type
->
type
)
&&
istype
(
l
->
type
->
type
->
type
,
TUINT8
))
||
(
isslice
(
l
->
type
)
&&
istype
(
l
->
type
->
type
,
TUINT8
)))
{
n
->
op
=
OARRAY
;
n
=
stringop
(
n
,
Erv
,
nil
);
n
=
stringop
(
n
,
nil
);
*
np
=
n
;
return
;
}
...
...
@@ -1277,7 +1039,7 @@ walkconv(Node **np, NodeList **init)
if
((
isptr
[
et
]
&&
isfixedarray
(
l
->
type
->
type
)
&&
istype
(
l
->
type
->
type
->
type
,
TINT
))
||
(
isslice
(
l
->
type
)
&&
istype
(
l
->
type
->
type
,
TINT
)))
{
n
->
op
=
OARRAY
;
n
=
stringop
(
n
,
Erv
,
nil
);
n
=
stringop
(
n
,
nil
);
*
np
=
n
;
return
;
}
...
...
@@ -1290,7 +1052,7 @@ walkconv(Node **np, NodeList **init)
// convert static array to dynamic array
if
(
isslice
(
t
)
&&
isptr
[
l
->
type
->
etype
]
&&
isfixedarray
(
l
->
type
->
type
))
{
if
(
eqtype
(
t
->
type
->
type
,
l
->
type
->
type
->
type
->
type
))
{
n
=
arrayop
(
n
,
Erv
);
n
=
arrayop
(
n
);
*
np
=
n
;
return
;
}
...
...
@@ -1327,9 +1089,8 @@ bad:
Node
*
selcase
(
Node
*
n
,
Node
*
var
,
NodeList
**
init
)
{
Node
*
a
,
*
r
,
*
on
,
*
c
;
Node
*
a
,
*
r
,
*
c
;
Type
*
t
;
NodeList
*
args
;
if
(
n
->
list
==
nil
)
goto
dflt
;
...
...
@@ -1337,8 +1098,8 @@ selcase(Node *n, Node *var, NodeList **init)
if
(
c
->
op
==
ORECV
)
goto
recv
;
walkexpr
(
&
c
->
left
,
Erv
,
init
);
// chan
walkexpr
(
&
c
->
right
,
Erv
,
init
);
// elem
walkexpr
(
&
c
->
left
,
init
);
// chan
walkexpr
(
&
c
->
right
,
init
);
// elem
t
=
fixchan
(
c
->
left
->
type
);
if
(
t
==
T
)
...
...
@@ -1356,23 +1117,14 @@ selcase(Node *n, Node *var, NodeList **init)
}
// selectsend(sel *byte, hchan *chan any, elem any) (selected bool);
on
=
syslook
(
"selectsend"
,
1
);
argtype
(
on
,
t
->
type
);
argtype
(
on
,
t
->
type
);
a
=
var
;
// sel-var
args
=
list1
(
a
);
a
=
c
->
left
;
// chan
args
=
list
(
args
,
a
);
a
=
c
->
right
;
// elem
args
=
list
(
args
,
a
);
a
=
mkcall1
(
chanfn
(
"selectsend"
,
2
,
t
),
types
[
TBOOL
],
init
,
var
,
c
->
left
,
c
->
right
);
goto
out
;
recv:
if
(
c
->
right
!=
N
)
goto
recv2
;
walkexpr
(
&
c
->
left
,
Erv
,
init
);
// chan
walkexpr
(
&
c
->
left
,
init
);
// chan
t
=
fixchan
(
c
->
left
->
type
);
if
(
t
==
T
)
...
...
@@ -1384,25 +1136,11 @@ recv:
}
// selectrecv(sel *byte, hchan *chan any, elem *any) (selected bool);
on
=
syslook
(
"selectrecv"
,
1
);
argtype
(
on
,
t
->
type
);
argtype
(
on
,
t
->
type
);
a
=
var
;
// sel-var
args
=
list1
(
a
);
a
=
c
->
left
;
// chan
args
=
list
(
args
,
a
);
a
=
c
->
left
;
// nil elem
a
=
nod
(
OLITERAL
,
N
,
N
);
a
->
val
.
ctype
=
CTNIL
;
a
->
type
=
types
[
TNIL
];
args
=
list
(
args
,
a
);
a
=
mkcall1
(
chanfn
(
"selectrecv"
,
2
,
t
),
types
[
TBOOL
],
init
,
var
,
c
->
left
,
nodnil
());
goto
out
;
recv2:
walkexpr
(
&
c
->
right
,
Erv
,
init
);
// chan
walkexpr
(
&
c
->
right
,
init
);
// chan
t
=
fixchan
(
c
->
right
->
type
);
if
(
t
==
T
)
...
...
@@ -1413,39 +1151,18 @@ recv2:
return
N
;
}
walkexpr
(
&
c
->
left
,
Elv
,
init
);
// check elem
convlit
(
&
c
->
left
,
t
->
type
);
if
(
!
ascompat
(
t
->
type
,
c
->
left
->
type
))
{
badtype
(
c
->
op
,
t
->
type
,
c
->
left
->
type
);
return
N
;
}
walkexpr
(
&
c
->
left
,
init
);
// selectrecv(sel *byte, hchan *chan any, elem *any) (selected bool);
on
=
syslook
(
"selectrecv"
,
1
);
argtype
(
on
,
t
->
type
);
argtype
(
on
,
t
->
type
);
a
=
var
;
// sel-var
args
=
list1
(
a
);
a
=
c
->
right
;
// chan
args
=
list
(
args
,
a
);
a
=
c
->
left
;
// elem
a
=
nod
(
OADDR
,
a
,
N
);
args
=
list
(
args
,
a
);
a
=
mkcall1
(
chanfn
(
"selectrecv"
,
2
,
t
),
types
[
TBOOL
],
init
,
var
,
c
->
right
,
nod
(
OADDR
,
c
->
left
,
N
));
goto
out
;
dflt:
// selectdefault(sel *byte);
on
=
syslook
(
"selectdefault"
,
0
);
a
=
var
;
args
=
list1
(
a
);
a
=
mkcall
(
"selectdefault"
,
types
[
TBOOL
],
init
,
var
);
goto
out
;
out:
a
=
nod
(
OCALL
,
on
,
N
);
a
->
list
=
args
;
r
=
nod
(
OIF
,
N
,
N
);
r
->
ntest
=
a
;
...
...
@@ -1465,7 +1182,7 @@ selectas(Node *name, Node *expr, NodeList **init)
if
(
expr
==
N
||
expr
->
op
!=
ORECV
)
goto
bad
;
walkexpr
(
&
expr
->
left
,
Erv
,
init
);
walkexpr
(
&
expr
->
left
,
init
);
t
=
expr
->
left
->
type
;
if
(
t
==
T
)
goto
bad
;
...
...
@@ -1483,7 +1200,7 @@ walkselect(Node *sel)
{
Node
*
n
,
*
l
,
*
oc
,
*
on
,
*
r
;
Node
*
var
,
*
def
;
NodeList
*
args
,
*
res
,
*
bod
,
*
nbod
,
*
init
,
*
ln
;
NodeList
*
res
,
*
bod
,
*
nbod
,
*
init
,
*
ln
;
int
count
,
op
;
int32
lno
;
...
...
@@ -1579,20 +1296,10 @@ walkselect(Node *sel)
setlineno
(
sel
);
// selectgo(sel *byte);
on
=
syslook
(
"selectgo"
,
0
);
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
list1
(
var
);
// sel-var
res
=
list
(
res
,
r
);
res
=
list
(
res
,
mkcall
(
"selectgo"
,
T
,
nil
,
var
));
// newselect(size uint32) (sel *byte);
on
=
syslook
(
"newselect"
,
0
);
r
=
nod
(
OXXX
,
N
,
N
);
nodconst
(
r
,
types
[
TINT
],
count
);
// count
args
=
list1
(
r
);
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
args
;
r
=
nod
(
OAS
,
var
,
r
);
r
=
nod
(
OAS
,
var
,
mkcall
(
"newselect"
,
var
->
type
,
nil
,
nodintconst
(
count
)));
typecheck
(
&
r
,
Etop
);
typechecklist
(
res
,
Etop
);
...
...
@@ -1813,7 +1520,7 @@ mkdotargs(NodeList *lr0, NodeList *nn, Type *l, int fp, NodeList **init)
r
->
left
->
type
=
r
->
right
->
type
;
r
->
left
->
xoffset
+=
t
->
width
;
typecheck
(
&
r
,
Etop
);
walkexpr
(
&
r
,
Etop
,
init
);
walkexpr
(
&
r
,
init
);
lr
->
n
=
r
;
t
=
t
->
down
;
}
...
...
@@ -2067,28 +1774,26 @@ ascompat(Type *dst, Type *src)
}
// generate code for print
// fmt = 0: print
// fmt = 1: println
Node
*
prcompat
(
NodeList
*
all
,
int
fmt
,
int
dopanic
)
static
Node
*
prcompat
(
Node
*
nn
)
{
Node
*
r
;
Node
*
n
;
NodeList
*
l
;
NodeList
*
l
,
*
all
;
Node
*
on
;
Type
*
t
;
int
notfirst
,
et
;
int
notfirst
,
et
,
op
;
NodeList
*
calls
;
op
=
nn
->
op
;
all
=
nn
->
list
;
calls
=
nil
;
notfirst
=
0
;
for
(
l
=
all
;
l
;
l
=
l
->
next
)
{
if
(
notfirst
)
{
on
=
syslook
(
"printsp"
,
0
);
calls
=
list
(
calls
,
nod
(
OCALL
,
on
,
N
));
}
notfirst
=
fmt
;
if
(
notfirst
)
calls
=
list
(
calls
,
mkcall
(
"printsp"
,
T
,
nil
));
notfirst
=
op
==
OPRINTN
||
op
==
OPANICN
;
typecheck
(
&
l
->
n
,
Erv
);
n
=
l
->
n
;
...
...
@@ -2153,39 +1858,21 @@ prcompat(NodeList *all, int fmt, int dopanic)
calls
=
list
(
calls
,
r
);
}
if
(
fmt
==
1
&&
!
dopanic
)
{
on
=
syslook
(
"printnl"
,
0
);
calls
=
list
(
calls
,
nod
(
OCALL
,
on
,
N
));
}
if
(
op
==
OPRINTN
)
calls
=
list
(
calls
,
mkcall
(
"printnl"
,
T
,
nil
));
typechecklist
(
calls
,
Etop
);
walkexprlist
(
calls
,
Etop
,
nil
);
walkexprlist
(
calls
,
nil
);
if
(
dopanic
)
r
=
nodpanic
(
0
);
if
(
op
==
OPANIC
||
op
==
OPANICN
)
r
=
mkcall
(
"panicl"
,
T
,
nil
);
else
r
=
nod
(
OEMPTY
,
N
,
N
);
typecheck
(
&
r
,
Etop
);
walkexpr
(
&
r
,
Etop
,
nil
);
walkexpr
(
&
r
,
nil
);
r
->
ninit
=
calls
;
return
r
;
}
Node
*
nodpanic
(
int32
lineno
)
{
Node
*
n
,
*
on
;
NodeList
*
args
;
on
=
syslook
(
"panicl"
,
0
);
n
=
nodintconst
(
lineno
);
args
=
list1
(
n
);
n
=
nod
(
OCALL
,
on
,
N
);
n
->
list
=
args
;
typecheck
(
&
n
,
Etop
);
walkexpr
(
&
n
,
Etop
,
nil
);
return
n
;
}
Node
*
makecompat
(
Node
*
n
)
{
...
...
@@ -2203,7 +1890,7 @@ makecompat(Node *n)
l
=
args
->
n
;
args
=
args
->
next
;
init
=
nil
;
walkexpr
(
&
l
,
Etype
,
&
init
);
walkexpr
(
&
l
,
&
init
);
if
(
l
->
op
!=
OTYPE
)
{
yyerror
(
"cannot make(expr)"
);
return
n
;
...
...
@@ -2217,11 +1904,11 @@ makecompat(Node *n)
case
TARRAY
:
if
(
!
isslice
(
t
))
goto
bad
;
return
arrayop
(
n
,
Erv
);
return
arrayop
(
n
);
case
TMAP
:
return
mapop
(
n
,
Erv
,
nil
);
return
mapop
(
n
,
nil
);
case
TCHAN
:
return
chanop
(
n
,
Erv
,
nil
);
return
chanop
(
n
,
nil
);
}
bad:
...
...
@@ -2235,26 +1922,18 @@ bad:
Node
*
callnew
(
Type
*
t
)
{
Node
*
r
,
*
on
;
NodeList
*
args
;
Node
*
fn
;
dowidth
(
t
);
on
=
syslook
(
"mal"
,
1
);
argtype
(
on
,
t
);
r
=
nodintconst
(
t
->
width
);
args
=
list1
(
r
);
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
args
;
typecheck
(
&
r
,
Erv
);
walkexpr
(
&
r
,
Erv
,
nil
);
return
r
;
fn
=
syslook
(
"mal"
,
1
);
argtype
(
fn
,
t
);
return
mkcall1
(
fn
,
ptrto
(
t
),
nil
,
nodintconst
(
t
->
width
));
}
Node
*
stringop
(
Node
*
n
,
int
top
,
NodeList
**
init
)
stringop
(
Node
*
n
,
NodeList
**
init
)
{
Node
*
r
,
*
c
,
*
on
;
NodeList
*
args
;
Node
*
r
,
*
fn
;
switch
(
n
->
op
)
{
default:
...
...
@@ -2267,30 +1946,18 @@ stringop(Node *n, int top, NodeList **init)
case
OLE
:
case
OLT
:
// sys_cmpstring(s1, s2) :: 0
on
=
syslook
(
"cmpstring"
,
0
);
r
=
nod
(
OCONV
,
n
->
left
,
N
);
r
->
type
=
types
[
TSTRING
];
args
=
list1
(
r
);
c
=
nod
(
OCONV
,
n
->
right
,
N
);
c
->
type
=
types
[
TSTRING
];
args
=
list
(
args
,
c
);
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
args
;
c
=
nodintconst
(
0
);
r
=
nod
(
n
->
op
,
r
,
c
);
r
=
mkcall
(
"cmpstring"
,
types
[
TINT
],
init
,
conv
(
n
->
left
,
types
[
TSTRING
]),
conv
(
n
->
right
,
types
[
TSTRING
]));
r
=
nod
(
n
->
op
,
r
,
nodintconst
(
0
));
typecheck
(
&
r
,
Erv
);
break
;
case
OADD
:
// sys_catstring(s1, s2)
on
=
syslook
(
"catstring"
,
0
);
r
=
nod
(
OCONV
,
n
->
left
,
N
);
r
->
type
=
types
[
TSTRING
];
args
=
list1
(
r
);
c
=
nod
(
OCONV
,
n
->
right
,
N
);
c
->
type
=
types
[
TSTRING
];
args
=
list
(
args
,
c
);
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
args
;
r
=
mkcall
(
"catstring"
,
n
->
type
,
init
,
conv
(
n
->
left
,
types
[
TSTRING
]),
conv
(
n
->
right
,
types
[
TSTRING
]));
break
;
case
OASOP
:
...
...
@@ -2303,82 +1970,50 @@ stringop(Node *n, int top, NodeList **init)
// s1 = sys_catstring(s1, s2)
if
(
n
->
etype
!=
OADD
)
fatal
(
"stringop: not cat"
);
on
=
syslook
(
"catstring"
,
0
);
r
=
nod
(
OCONV
,
n
->
left
,
N
);
r
->
type
=
types
[
TSTRING
];
args
=
list1
(
r
);
c
=
nod
(
OCONV
,
n
->
right
,
N
);
c
->
type
=
types
[
TSTRING
];
args
=
list
(
args
,
c
);
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
args
;
r
=
mkcall
(
"catstring"
,
n
->
left
->
type
,
init
,
conv
(
n
->
left
,
types
[
TSTRING
]),
conv
(
n
->
right
,
types
[
TSTRING
]));
r
=
nod
(
OAS
,
n
->
left
,
r
);
break
;
}
break
;
case
OSLICE
:
r
=
nod
(
OCONV
,
n
->
left
,
N
);
r
->
type
=
types
[
TSTRING
];
args
=
list1
(
r
);
case
OSLICE
:
// sys_slicestring(s, lb, hb)
r
=
nod
(
OCONV
,
n
->
right
->
left
,
N
);
r
->
type
=
types
[
TINT
];
args
=
list
(
args
,
r
);
c
=
nod
(
OCONV
,
n
->
right
->
right
,
N
);
c
->
type
=
types
[
TINT
];
args
=
list
(
args
,
c
);
on
=
syslook
(
"slicestring"
,
0
);
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
args
;
r
=
mkcall
(
"slicestring"
,
n
->
type
,
init
,
conv
(
n
->
left
,
types
[
TSTRING
]),
conv
(
n
->
right
->
left
,
types
[
TINT
]),
conv
(
n
->
right
->
right
,
types
[
TINT
]));
break
;
case
OINDEX
:
// TODO(rsc): should be done in back end
// sys_indexstring(s, i)
r
=
nod
(
OCONV
,
n
->
left
,
N
);
r
->
type
=
types
[
TSTRING
];
args
=
list1
(
r
);
r
=
nod
(
OCONV
,
n
->
right
,
N
);
r
->
type
=
types
[
TINT
];
args
=
list
(
args
,
r
);
on
=
syslook
(
"indexstring"
,
0
);
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
args
;
r
=
mkcall
(
"indexstring"
,
n
->
type
,
init
,
conv
(
n
->
left
,
types
[
TSTRING
]),
conv
(
n
->
right
,
types
[
TINT
]));
break
;
case
OCONV
:
// sys_intstring(v)
r
=
nod
(
OCONV
,
n
->
left
,
N
);
r
->
type
=
types
[
TINT64
];
args
=
list1
(
r
);
on
=
syslook
(
"intstring"
,
0
);
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
args
;
r
=
mkcall
(
"intstring"
,
n
->
type
,
init
,
conv
(
n
->
left
,
types
[
TINT64
]));
// TODO(rsc): int64?!
break
;
case
OARRAY
:
// arraystring([]byte) string;
on
=
syslook
(
"arraystring"
,
0
);
r
=
n
->
left
;
fn
=
syslook
(
"arraystring"
,
0
);
if
(
r
->
type
!=
T
&&
r
->
type
->
type
!=
T
)
{
if
(
istype
(
r
->
type
->
type
,
TINT
)
||
istype
(
r
->
type
->
type
->
type
,
TINT
))
{
// arraystring([]byte) string;
o
n
=
syslook
(
"arraystringi"
,
0
);
f
n
=
syslook
(
"arraystringi"
,
0
);
}
}
args
=
list1
(
r
);
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
args
;
r
=
mkcall1
(
fn
,
n
->
type
,
init
,
r
);
break
;
}
typecheck
(
&
r
,
top
);
walkexpr
(
&
r
,
top
,
init
);
return
r
;
}
...
...
@@ -2422,11 +2057,11 @@ bad:
}
Node
*
mapop
(
Node
*
n
,
int
top
,
NodeList
**
init
)
mapop
(
Node
*
n
,
NodeList
**
init
)
{
Node
*
r
,
*
a
,
*
l
;
Type
*
t
;
Node
*
on
;
Node
*
fn
,
*
hint
;
int
cl
,
cr
;
NodeList
*
args
;
...
...
@@ -2440,9 +2075,6 @@ mapop(Node *n, int top, NodeList **init)
if
(
cl
>
1
)
yyerror
(
"too many arguments to make map"
);
if
(
!
(
top
&
Erv
))
goto
nottop
;
// newmap(keysize int, valsize int,
// keyalg int, valalg int,
// hint int) (hmap map[any-1]any-2);
...
...
@@ -2451,66 +2083,31 @@ mapop(Node *n, int top, NodeList **init)
if
(
t
==
T
)
break
;
a
=
nodintconst
(
t
->
down
->
width
);
// key width
args
=
list1
(
a
);
a
=
nodintconst
(
t
->
type
->
width
);
// val width
args
=
list
(
args
,
a
);
a
=
nodintconst
(
algtype
(
t
->
down
));
// key algorithm
args
=
list
(
args
,
a
);
a
=
nodintconst
(
algtype
(
t
->
type
));
// val algorithm
args
=
list
(
args
,
a
);
fn
=
syslook
(
"newmap"
,
1
);
argtype
(
fn
,
t
->
down
);
// any-1
argtype
(
fn
,
t
->
type
);
// any-2
if
(
cl
==
1
)
a
=
n
->
list
->
n
;
// hint
hint
=
n
->
list
->
n
;
else
a
=
nodintconst
(
0
);
args
=
list
(
args
,
a
);
on
=
syslook
(
"newmap"
,
1
);
argtype
(
on
,
t
->
down
);
// any-1
argtype
(
on
,
t
->
type
);
// any-2
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
args
;
typecheck
(
&
r
,
Erv
);
walkexpr
(
&
r
,
top
,
nil
);
r
->
type
=
n
->
type
;
hint
=
nodintconst
(
0
);
r
=
mkcall1
(
fn
,
n
->
type
,
init
,
nodintconst
(
t
->
down
->
width
),
// key width
nodintconst
(
t
->
type
->
width
),
// val width
nodintconst
(
algtype
(
t
->
down
)),
// key algorithm
nodintconst
(
algtype
(
t
->
type
)),
// val algorithm
hint
);
break
;
case
OINDEX
:
if
(
!
(
top
&
Erv
))
goto
nottop
;
// mapaccess1(hmap map[any]any, key any) (val any);
t
=
fixmap
(
n
->
left
->
type
);
if
(
t
==
T
)
break
;
convlit
(
&
n
->
right
,
t
->
down
);
if
(
!
eqtype
(
n
->
right
->
type
,
t
->
down
))
{
badtype
(
n
->
op
,
n
->
right
->
type
,
t
->
down
);
break
;
}
a
=
n
->
left
;
// map
args
=
list1
(
a
);
a
=
n
->
right
;
// key
args
=
list
(
args
,
a
);
on
=
syslook
(
"mapaccess1"
,
1
);
argtype
(
on
,
t
->
down
);
// any-1
argtype
(
on
,
t
->
type
);
// any-2
argtype
(
on
,
t
->
down
);
// any-3
argtype
(
on
,
t
->
type
);
// any-4
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
args
;
typecheck
(
&
r
,
Erv
);
walkexpr
(
&
r
,
Erv
,
nil
);
r
->
type
=
t
->
type
;
r
=
mkcall1
(
mapfn
(
"mapaccess1"
,
t
),
t
->
type
,
init
,
n
->
left
,
n
->
right
);
break
;
case
OAS
:
...
...
@@ -2522,24 +2119,7 @@ mapop(Node *n, int top, NodeList **init)
if
(
t
==
T
)
break
;
a
=
n
->
left
->
left
;
// map
args
=
list1
(
a
);
a
=
n
->
left
->
right
;
// key
args
=
list
(
args
,
a
);
a
=
n
->
right
;
// val
args
=
list
(
args
,
a
);
on
=
syslook
(
"mapassign1"
,
1
);
argtype
(
on
,
t
->
down
);
// any-1
argtype
(
on
,
t
->
type
);
// any-2
argtype
(
on
,
t
->
down
);
// any-3
argtype
(
on
,
t
->
type
);
// any-4
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
args
;
typecheck
(
&
r
,
Etop
);
walkexpr
(
&
r
,
Etop
,
init
);
r
=
mkcall1
(
mapfn
(
"mapassign1"
,
t
),
T
,
init
,
n
->
left
->
left
,
n
->
left
->
right
,
n
->
right
);
break
;
case
OAS2
:
...
...
@@ -2562,22 +2142,7 @@ mapop(Node *n, int top, NodeList **init)
if
(
t
==
T
)
break
;
args
=
list1
(
l
->
left
);
// map
args
=
list
(
args
,
l
->
right
);
// key
args
=
list
(
args
,
n
->
rlist
->
n
);
// val
args
=
list
(
args
,
n
->
rlist
->
next
->
n
);
// pres
on
=
syslook
(
"mapassign2"
,
1
);
argtype
(
on
,
t
->
down
);
// any-1
argtype
(
on
,
t
->
type
);
// any-2
argtype
(
on
,
t
->
down
);
// any-3
argtype
(
on
,
t
->
type
);
// any-4
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
args
;
typecheck
(
&
r
,
Etop
);
walkexpr
(
&
r
,
Etop
,
init
);
r
=
mkcall1
(
mapfn
(
"mapassign2"
,
t
),
T
,
init
,
l
->
left
,
l
->
right
,
n
->
rlist
->
n
,
n
->
rlist
->
next
->
n
);
break
;
access2:
...
...
@@ -2595,19 +2160,11 @@ mapop(Node *n, int top, NodeList **init)
args
=
list1
(
r
->
left
);
// map
args
=
list
(
args
,
r
->
right
);
// key
on
=
syslook
(
"mapaccess2"
,
1
);
argtype
(
on
,
t
->
down
);
// any-1
argtype
(
on
,
t
->
type
);
// any-2
argtype
(
on
,
t
->
down
);
// any-3
argtype
(
on
,
t
->
type
);
// any-4
a
=
nod
(
OCALL
,
on
,
N
);
a
->
list
=
args
;
typecheck
(
&
a
,
Erv
);
fn
=
mapfn
(
"mapaccess2"
,
t
);
a
=
mkcall1
(
fn
,
getoutargx
(
fn
->
type
),
init
,
r
->
left
,
r
->
right
);
n
->
rlist
=
list1
(
a
);
typecheck
(
&
n
,
Etop
);
walkexpr
(
&
n
,
Etop
,
init
);
walkexpr
(
&
n
,
init
);
r
=
n
;
break
;
...
...
@@ -2622,34 +2179,31 @@ mapop(Node *n, int top, NodeList **init)
r
=
nod
(
OAS
,
a
,
n
->
left
->
right
);
// tmpi := index
n
->
left
->
right
=
a
;
// m[tmpi]
typecheck
(
&
r
,
Etop
);
walkexpr
(
&
r
,
Etop
,
init
);
walkexpr
(
&
r
,
init
);
*
init
=
list
(
*
init
,
r
);
a
=
nod
(
OXXX
,
N
,
N
);
*
a
=
*
n
->
left
;
// copy of map[tmpi]
a
->
typecheck
=
0
;
a
->
type
=
T
;
a
=
nod
(
n
->
etype
,
a
,
n
->
right
);
// m[tmpi] op right
r
=
nod
(
OAS
,
n
->
left
,
a
);
// map[tmpi] = map[tmpi] op right
typecheck
(
&
r
,
Etop
);
walkexpr
(
&
r
,
Etop
,
init
);
walkexpr
(
&
r
,
init
);
break
;
}
return
r
;
shape:
dump
(
"shape"
,
n
);
fatal
(
"mapop: cl=%d cr=%d, %O"
,
top
,
n
->
op
);
return
N
;
nottop:
yyerror
(
"didn't expect %O here"
,
n
->
op
);
fatal
(
"mapop: %O"
,
n
->
op
);
return
N
;
}
Node
*
chanop
(
Node
*
n
,
int
top
,
NodeList
**
init
)
chanop
(
Node
*
n
,
NodeList
**
init
)
{
Node
*
r
,
*
a
,
*
on
;
NodeList
*
args
;
Node
*
r
,
*
a
,
*
fn
;
Type
*
t
;
int
cl
,
cr
;
...
...
@@ -2663,18 +2217,9 @@ chanop(Node *n, int top, NodeList **init)
t
=
fixchan
(
n
->
left
->
type
);
if
(
t
==
T
)
break
;
a
=
n
->
left
;
// chan
args
=
list1
(
a
);
on
=
syslook
(
"closechan"
,
1
);
argtype
(
on
,
t
);
// any-1
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
args
;
typecheck
(
&
r
,
Etop
);
walkexpr
(
&
r
,
top
,
nil
);
r
->
type
=
n
->
type
;
fn
=
syslook
(
"closechan"
,
1
);
argtype
(
fn
,
t
);
r
=
mkcall1
(
fn
,
T
,
init
,
n
->
left
);
break
;
case
OCLOSED
:
...
...
@@ -2682,18 +2227,9 @@ chanop(Node *n, int top, NodeList **init)
t
=
fixchan
(
n
->
left
->
type
);
if
(
t
==
T
)
break
;
a
=
n
->
left
;
// chan
args
=
list1
(
a
);
on
=
syslook
(
"closedchan"
,
1
);
argtype
(
on
,
t
);
// any-1
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
args
;
typecheck
(
&
r
,
Erv
);
walkexpr
(
&
r
,
top
,
nil
);
n
->
type
=
r
->
type
;
fn
=
syslook
(
"closedchan"
,
1
);
argtype
(
fn
,
t
);
r
=
mkcall1
(
fn
,
n
->
type
,
init
,
n
->
left
);
break
;
case
OMAKE
:
...
...
@@ -2708,26 +2244,14 @@ chanop(Node *n, int top, NodeList **init)
if
(
t
==
T
)
break
;
a
=
nodintconst
(
t
->
type
->
width
);
// elem width
args
=
list1
(
a
);
a
=
nodintconst
(
algtype
(
t
->
type
));
// elem algorithm
args
=
list
(
args
,
a
);
a
=
nodintconst
(
0
);
if
(
cl
==
1
)
{
// async buf size
a
=
nod
(
OCONV
,
n
->
list
->
n
,
N
);
a
->
type
=
types
[
TINT
];
}
args
=
list
(
args
,
a
);
on
=
syslook
(
"newchan"
,
1
);
argtype
(
on
,
t
->
type
);
// any-1
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
args
;
typecheck
(
&
r
,
Erv
);
walkexpr
(
&
r
,
top
,
nil
);
r
->
type
=
n
->
type
;
if
(
cl
==
1
)
a
=
conv
(
n
->
list
->
n
,
types
[
TINT
]);
else
a
=
nodintconst
(
0
);
r
=
mkcall1
(
chanfn
(
"newchan"
,
1
,
t
),
n
->
type
,
init
,
nodintconst
(
t
->
type
->
width
),
nodintconst
(
algtype
(
t
->
type
)),
a
);
break
;
case
OAS2
:
...
...
@@ -2743,25 +2267,16 @@ chanop(Node *n, int top, NodeList **init)
t
=
fixchan
(
r
->
left
->
type
);
if
(
t
==
T
)
break
;
if
(
!
(
t
->
chan
&
Crecv
))
{
yyerror
(
"cannot receive from %T"
,
t
);
break
;
}
a
=
r
->
left
;
// chan
args
=
list1
(
a
);
on
=
syslook
(
"chanrecv2"
,
1
);
argtype
(
on
,
t
->
type
);
// any-1
argtype
(
on
,
t
->
type
);
// any-2
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
args
;
typecheck
(
&
r
,
Etop
);
fn
=
chanfn
(
"chanrecv2"
,
2
,
t
);
r
=
mkcall1
(
fn
,
getoutargx
(
fn
->
type
),
init
,
r
->
left
);
n
->
rlist
->
n
=
r
;
r
=
n
;
walkexpr
(
&
r
,
Etop
,
init
);
walkexpr
(
&
r
,
init
);
break
;
case
ORECV
:
...
...
@@ -2772,27 +2287,15 @@ chanop(Node *n, int top, NodeList **init)
}
// chanrecv1(hchan *chan any) (elem any);
defaultlit
(
&
n
->
left
,
T
);
t
=
fixchan
(
n
->
left
->
type
);
if
(
t
==
T
)
break
;
if
(
!
(
t
->
chan
&
Crecv
))
{
yyerror
(
"cannot receive from %T"
,
t
);
break
;
}
a
=
n
->
left
;
// chan
args
=
list1
(
a
);
on
=
syslook
(
"chanrecv1"
,
1
);
argtype
(
on
,
t
->
type
);
// any-1
argtype
(
on
,
t
->
type
);
// any-2
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
args
;
typecheck
(
&
r
,
Erv
);
walkexpr
(
&
r
,
Erv
,
nil
);
r
=
mkcall1
(
chanfn
(
"chanrecv1"
,
2
,
t
),
n
->
type
,
init
,
n
->
left
);
break
;
case
OSEND
:
...
...
@@ -2803,39 +2306,16 @@ chanop(Node *n, int top, NodeList **init)
yyerror
(
"cannot send to %T"
,
t
);
break
;
}
if
(
top
!=
Etop
)
if
(
n
->
etype
==
1
)
// clumsy hack
goto
send2
;
// chansend1(hchan *chan any, elem any);
a
=
n
->
left
;
// chan
args
=
list1
(
a
);
a
=
n
->
right
;
// e
args
=
list
(
args
,
a
);
on
=
syslook
(
"chansend1"
,
1
);
argtype
(
on
,
t
->
type
);
// any-1
argtype
(
on
,
t
->
type
);
// any-2
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
args
;
typecheck
(
&
r
,
Etop
);
walkexpr
(
&
r
,
Etop
,
nil
);
r
=
mkcall1
(
chanfn
(
"chansend1"
,
2
,
t
),
T
,
init
,
n
->
left
,
n
->
right
);
break
;
send2:
// chansend2(hchan *chan any, val any) (pres bool);
a
=
n
->
left
;
// chan
args
=
list1
(
a
);
a
=
n
->
right
;
// e
args
=
list
(
args
,
a
);
on
=
syslook
(
"chansend2"
,
1
);
argtype
(
on
,
t
->
type
);
// any-1
argtype
(
on
,
t
->
type
);
// any-2
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
args
;
typecheck
(
&
r
,
Etop
);
walkexpr
(
&
r
,
Etop
,
nil
);
r
=
mkcall1
(
chanfn
(
"chansend2"
,
2
,
t
),
n
->
type
,
init
,
n
->
left
,
n
->
right
);
break
;
}
return
r
;
...
...
@@ -2865,12 +2345,12 @@ bad:
}
Node
*
arrayop
(
Node
*
n
,
int
top
)
arrayop
(
Node
*
n
)
{
Node
*
r
,
*
a
;
Node
*
r
,
*
nel
,
*
max
;
NodeList
*
args
;
Type
*
t
,
*
tl
;
Node
*
o
n
;
Node
*
f
n
;
int
cl
;
r
=
n
;
...
...
@@ -2878,6 +2358,9 @@ arrayop(Node *n, int top)
default:
fatal
(
"darrayop: unknown op %O"
,
n
->
op
);
case
OCONVNOP
:
return
n
;
case
OCONV
:
// arrays2d(old *any, nel int) (ary []any)
if
(
n
->
left
->
type
==
T
||
!
isptr
[
n
->
left
->
type
->
etype
])
...
...
@@ -2887,27 +2370,17 @@ arrayop(Node *n, int top)
if
(
t
==
T
||
tl
==
T
)
break
;
args
=
list1
(
n
->
left
);
// old
a
=
nodintconst
(
t
->
bound
);
// nel
a
=
nod
(
OCONV
,
a
,
N
);
a
->
type
=
types
[
TINT
];
args
=
list
(
args
,
a
);
fn
=
syslook
(
"arrays2d"
,
1
);
argtype
(
fn
,
t
);
// any-1
argtype
(
fn
,
tl
->
type
);
// any-2
on
=
syslook
(
"arrays2d"
,
1
);
argtype
(
on
,
t
);
// any-1
argtype
(
on
,
tl
->
type
);
// any-2
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
args
;
n
->
left
=
r
;
n
->
left
=
mkcall1
(
fn
,
n
->
type
,
nil
,
n
->
left
,
nodintconst
(
t
->
bound
));
typecheck
(
&
n
,
Erv
);
walkexpr
(
&
n
,
top
,
nil
);
walkexpr
(
&
n
,
nil
);
return
n
;
case
OAS
:
r
=
nod
(
OCONV
,
n
->
right
,
N
);
r
->
type
=
n
->
left
->
type
;
n
->
right
=
arrayop
(
r
,
Erv
);
n
->
right
=
arrayop
(
conv
(
n
->
right
,
n
->
left
->
type
));
return
n
;
case
OMAKE
:
...
...
@@ -2919,39 +2392,16 @@ arrayop(Node *n, int top)
t
=
fixarray
(
n
->
type
);
if
(
t
==
T
)
break
;
fn
=
syslook
(
"newarray"
,
1
);
argtype
(
fn
,
t
->
type
);
// any-1
// nel
a
=
n
->
list
->
n
;
if
(
a
==
N
)
{
yyerror
(
"new slice must have size"
);
a
=
nodintconst
(
1
);
}
a
=
nod
(
OCONV
,
a
,
N
);
a
->
type
=
types
[
TINT
];
args
=
list1
(
a
);
// max
nel
=
conv
(
n
->
list
->
n
,
types
[
TINT
]);
if
(
cl
<
2
)
a
=
nodintconst
(
0
);
max
=
nodintconst
(
0
);
else
a
=
n
->
list
->
next
->
n
;
a
=
nod
(
OCONV
,
a
,
N
);
a
->
type
=
types
[
TINT
];
args
=
list
(
args
,
a
);
// width
a
=
nodintconst
(
t
->
type
->
width
);
// width
a
=
nod
(
OCONV
,
a
,
N
);
a
->
type
=
types
[
TINT
];
args
=
list
(
args
,
a
);
on
=
syslook
(
"newarray"
,
1
);
argtype
(
on
,
t
->
type
);
// any-1
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
args
;
typecheck
(
&
r
,
Erv
);
walkexpr
(
&
r
,
top
,
nil
);
r
->
type
=
t
;
// if t had a name, going through newarray lost it
max
=
conv
(
n
->
list
->
next
->
n
,
types
[
TINT
]);
r
=
mkcall1
(
fn
,
n
->
type
,
nil
,
nel
,
max
,
nodintconst
(
t
->
type
->
width
));
break
;
case
OSLICE
:
...
...
@@ -2964,43 +2414,29 @@ arrayop(Node *n, int top)
if
(
t
->
bound
>=
0
)
{
// static slice
a
=
nod
(
OADDR
,
n
->
left
,
N
);
// old
args
=
list1
(
a
);
a
=
nodintconst
(
t
->
bound
);
// nel
a
=
nod
(
OCONV
,
a
,
N
);
a
->
type
=
types
[
TINT
];
args
=
list
(
args
,
a
);
args
=
list1
(
nod
(
OADDR
,
n
->
left
,
N
));
// old
args
=
list
(
args
,
nodintconst
(
t
->
bound
));
// nel
o
n
=
syslook
(
"arrayslices"
,
1
);
argtype
(
o
n
,
t
);
// any-1
argtype
(
o
n
,
t
->
type
);
// any-2
f
n
=
syslook
(
"arrayslices"
,
1
);
argtype
(
f
n
,
t
);
// any-1
argtype
(
f
n
,
t
->
type
);
// any-2
}
else
{
// dynamic slice
a
=
n
->
left
;
// old
args
=
list1
(
a
);
args
=
list1
(
n
->
left
);
// old
o
n
=
syslook
(
"arraysliced"
,
1
);
argtype
(
o
n
,
t
->
type
);
// any-1
argtype
(
o
n
,
t
->
type
);
// any-2
f
n
=
syslook
(
"arraysliced"
,
1
);
argtype
(
f
n
,
t
->
type
);
// any-1
argtype
(
f
n
,
t
->
type
);
// any-2
}
a
=
nod
(
OCONV
,
n
->
right
->
left
,
N
);
// lb
a
->
type
=
types
[
TINT
];
args
=
list
(
args
,
a
);
a
rgs
=
list
(
args
,
conv
(
n
->
right
->
left
,
types
[
TINT
])
);
// lb
a
rgs
=
list
(
args
,
conv
(
n
->
right
->
right
,
types
[
TINT
]));
// hb
args
=
list
(
args
,
nodintconst
(
t
->
type
->
width
));
// width
a
=
nod
(
OCONV
,
n
->
right
->
right
,
N
);
// hb
a
->
type
=
types
[
TINT
];
args
=
list
(
args
,
a
);
a
=
nodintconst
(
t
->
type
->
width
);
// width
a
=
nod
(
OCONV
,
a
,
N
);
a
->
type
=
types
[
TINT
];
args
=
list
(
args
,
a
);
r
=
nod
(
OCALL
,
on
,
N
);
r
=
nod
(
OCALL
,
fn
,
N
);
r
->
list
=
args
;
typecheck
(
&
r
,
Erv
);
walkexpr
(
&
r
,
nil
);
break
;
}
return
r
;
...
...
@@ -3150,7 +2586,7 @@ ifacecvt(Type *tl, Node *n, int et)
r
=
nod
(
OCALL
,
on
,
N
);
r
->
list
=
args
;
typecheck
(
&
r
,
Erv
);
walkexpr
(
&
r
,
Erv
,
nil
);
walkexpr
(
&
r
,
nil
);
return
r
;
}
...
...
@@ -3184,7 +2620,7 @@ ifaceop(Node *n)
if
(
n
->
op
==
ONE
)
r
=
nod
(
ONOT
,
r
,
N
);
typecheck
(
&
r
,
Erv
);
walkexpr
(
&
r
,
Erv
,
nil
);
walkexpr
(
&
r
,
nil
);
return
r
;
}
}
...
...
@@ -3214,13 +2650,13 @@ convas(Node *n, NodeList **init)
if
(
n
->
left
->
op
==
OINDEX
)
if
(
istype
(
n
->
left
->
left
->
type
,
TMAP
))
{
n
=
mapop
(
n
,
Elv
,
init
);
n
=
mapop
(
n
,
init
);
goto
out
;
}
if
(
n
->
left
->
op
==
OSEND
)
if
(
n
->
left
->
type
!=
T
)
{
n
=
chanop
(
n
,
Elv
,
init
);
n
=
chanop
(
n
,
init
);
goto
out
;
}
...
...
@@ -3236,7 +2672,7 @@ convas(Node *n, NodeList **init)
if
(
isslice
(
lt
)
&&
isptr
[
rt
->
etype
]
&&
isfixedarray
(
rt
->
type
))
{
if
(
!
eqtype
(
lt
->
type
->
type
,
rt
->
type
->
type
->
type
))
goto
bad
;
n
=
arrayop
(
n
,
Etop
);
n
=
arrayop
(
n
);
goto
out
;
}
...
...
@@ -3389,14 +2825,14 @@ colas(NodeList *ll, NodeList *lr)
if
(
nr
->
left
->
op
==
ONAME
&&
nr
->
left
->
etype
!=
0
)
break
;
typecheck
(
&
nr
->
left
,
Erv
|
Etype
|
Ecall
);
walkexpr
(
&
nr
->
left
,
Erv
|
Etype
|
Ecall
,
&
init
);
walkexpr
(
&
nr
->
left
,
&
init
);
if
(
nr
->
left
->
op
==
OTYPE
)
break
;
goto
call
;
case
OCALLMETH
:
case
OCALLINTER
:
typecheck
(
&
nr
->
left
,
Erv
);
walkexpr
(
&
nr
->
left
,
Erv
,
&
init
);
walkexpr
(
&
nr
->
left
,
&
init
);
call:
convlit
(
&
nr
->
left
,
types
[
TFUNC
]);
t
=
nr
->
left
->
type
;
...
...
@@ -3466,7 +2902,7 @@ multi:
// if so, types are valuetype,bool
if
(
cl
!=
2
)
goto
badt
;
walkexpr
(
&
nr
->
left
,
Erv
,
&
init
);
walkexpr
(
&
nr
->
left
,
&
init
);
t
=
nr
->
left
->
type
;
if
(
!
istype
(
t
,
TMAP
))
goto
badt
;
...
...
@@ -3493,7 +2929,7 @@ multi:
case
ORECV
:
if
(
cl
!=
2
)
goto
badt
;
walkexpr
(
&
nr
->
left
,
Erv
,
&
init
);
walkexpr
(
&
nr
->
left
,
&
init
);
t
=
nr
->
left
->
type
;
if
(
!
istype
(
t
,
TCHAN
))
goto
badt
;
...
...
@@ -4011,7 +3447,7 @@ structlit(Node *n, Node *var, NodeList **init)
a
=
nod
(
ODOT
,
var
,
newname
(
l
->
sym
));
a
=
nod
(
OAS
,
a
,
r
);
typecheck
(
&
a
,
Etop
);
walkexpr
(
&
a
,
Etop
,
init
);
walkexpr
(
&
a
,
init
);
if
(
nerr
!=
nerrors
)
return
var
;
*
init
=
list
(
*
init
,
a
);
...
...
@@ -4028,7 +3464,7 @@ keyval:
memset
(
hash
,
0
,
sizeof
(
hash
));
a
=
nod
(
OAS
,
var
,
N
);
typecheck
(
&
a
,
Etop
);
walkexpr
(
&
a
,
Etop
,
init
);
walkexpr
(
&
a
,
init
);
*
init
=
list
(
*
init
,
a
);
for
(;
nl
;
nl
=
nl
->
next
)
{
...
...
@@ -4048,7 +3484,7 @@ keyval:
a
=
nod
(
OAS
,
a
,
r
->
right
);
typecheck
(
&
a
,
Etop
);
walkexpr
(
&
a
,
Etop
,
init
);
walkexpr
(
&
a
,
init
);
if
(
nerr
!=
nerrors
)
break
;
...
...
@@ -4130,7 +3566,7 @@ arraylit(Node *n, Node *var, NodeList **init)
a
->
list
=
list
(
list1
(
typenod
(
t
)),
nodintconst
(
ninit
));
a
=
nod
(
OAS
,
var
,
a
);
typecheck
(
&
a
,
Etop
);
walkexpr
(
&
a
,
Etop
,
init
);
walkexpr
(
&
a
,
init
);
*
init
=
list
(
*
init
,
a
);
}
else
{
// if entire array isnt initialized,
...
...
@@ -4138,7 +3574,7 @@ arraylit(Node *n, Node *var, NodeList **init)
if
(
ninit
<
b
)
{
a
=
nod
(
OAS
,
var
,
N
);
typecheck
(
&
a
,
Etop
);
walkexpr
(
&
a
,
Etop
,
init
);
walkexpr
(
&
a
,
init
);
*
init
=
list
(
*
init
,
a
);
}
}
...
...
@@ -4170,7 +3606,7 @@ arraylit(Node *n, Node *var, NodeList **init)
a
=
nod
(
OINDEX
,
var
,
a
);
a
=
nod
(
OAS
,
a
,
r
);
typecheck
(
&
a
,
Etop
);
walkexpr
(
&
a
,
Etop
,
init
);
// add any assignments in r to top
walkexpr
(
&
a
,
init
);
// add any assignments in r to top
if
(
nerr
!=
nerrors
)
break
;
...
...
@@ -4258,7 +3694,7 @@ maplit(Node *n, Node *var, NodeList **init)
a
->
list
=
list1
(
typenod
(
t
));
a
=
nod
(
OAS
,
var
,
a
);
typecheck
(
&
a
,
Etop
);
walkexpr
(
&
a
,
Etop
,
init
);
walkexpr
(
&
a
,
init
);
*
init
=
list
(
*
init
,
a
);
memset
(
hash
,
0
,
sizeof
(
hash
));
...
...
@@ -4277,7 +3713,7 @@ maplit(Node *n, Node *var, NodeList **init)
a
=
nod
(
OINDEX
,
var
,
r
->
left
);
a
=
nod
(
OAS
,
a
,
r
->
right
);
typecheck
(
&
a
,
Etop
);
walkexpr
(
&
a
,
Etop
,
init
);
walkexpr
(
&
a
,
init
);
if
(
nerr
!=
nerrors
)
break
;
...
...
@@ -4392,3 +3828,94 @@ heapmoves(void)
nn
=
concat
(
nn
,
paramstoheap
(
getinarg
(
curfn
->
type
)));
curfn
->
enter
=
concat
(
curfn
->
enter
,
nn
);
}
static
Node
*
vmkcall
(
Node
*
fn
,
Type
*
t
,
NodeList
**
init
,
va_list
va
)
{
int
i
,
n
;
Node
*
r
;
NodeList
*
args
;
if
(
fn
->
type
==
T
||
fn
->
type
->
etype
!=
TFUNC
)
fatal
(
"mkcall %#N %T"
,
fn
,
fn
->
type
);
args
=
nil
;
n
=
fn
->
type
->
intuple
;
for
(
i
=
0
;
i
<
n
;
i
++
)
args
=
list
(
args
,
va_arg
(
va
,
Node
*
));
r
=
nod
(
OCALL
,
fn
,
N
);
r
->
list
=
args
;
if
(
fn
->
type
->
outtuple
>
0
)
typecheck
(
&
r
,
Erv
);
else
typecheck
(
&
r
,
Etop
);
walkexpr
(
&
r
,
init
);
r
->
type
=
t
;
return
r
;
}
static
Node
*
mkcall
(
char
*
name
,
Type
*
t
,
NodeList
**
init
,
...)
{
Node
*
r
;
va_list
va
;
va_start
(
va
,
init
);
r
=
vmkcall
(
syslook
(
name
,
0
),
t
,
init
,
va
);
va_end
(
va
);
return
r
;
}
static
Node
*
mkcall1
(
Node
*
fn
,
Type
*
t
,
NodeList
**
init
,
...)
{
Node
*
r
;
va_list
va
;
va_start
(
va
,
init
);
r
=
vmkcall
(
fn
,
t
,
init
,
va
);
va_end
(
va
);
return
r
;
}
static
Node
*
conv
(
Node
*
n
,
Type
*
t
)
{
if
(
eqtype
(
n
->
type
,
t
))
return
n
;
n
=
nod
(
OCONV
,
n
,
N
);
n
->
type
=
t
;
typecheck
(
&
n
,
Erv
);
walkexpr
(
&
n
,
nil
);
return
n
;
}
static
Node
*
chanfn
(
char
*
name
,
int
n
,
Type
*
t
)
{
Node
*
fn
;
int
i
;
if
(
t
->
etype
!=
TCHAN
)
fatal
(
"chanfn %T"
,
t
);
fn
=
syslook
(
name
,
1
);
for
(
i
=
0
;
i
<
n
;
i
++
)
argtype
(
fn
,
t
->
type
);
return
fn
;
}
static
Node
*
mapfn
(
char
*
name
,
Type
*
t
)
{
Node
*
fn
;
if
(
t
->
etype
!=
TMAP
)
fatal
(
"mapfn %T"
,
t
);
fn
=
syslook
(
name
,
1
);
argtype
(
fn
,
t
->
down
);
argtype
(
fn
,
t
->
type
);
argtype
(
fn
,
t
->
down
);
argtype
(
fn
,
t
->
type
);
return
fn
;
}
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