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