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
26b357ca
Commit
26b357ca
authored
Dec 05, 2008
by
Ken Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
range statement
R=r OCL=20667 CL=20667
parent
2fe97c33
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
364 additions
and
55 deletions
+364
-55
src/cmd/gc/dcl.c
src/cmd/gc/dcl.c
+1
-1
src/cmd/gc/go.h
src/cmd/gc/go.h
+28
-0
src/cmd/gc/go.y
src/cmd/gc/go.y
+10
-38
src/cmd/gc/sys.go
src/cmd/gc/sys.go
+6
-2
src/cmd/gc/sysimport.c
src/cmd/gc/sysimport.c
+5
-1
src/cmd/gc/walk.c
src/cmd/gc/walk.c
+104
-0
src/runtime/hashmap.c
src/runtime/hashmap.c
+84
-1
src/runtime/hashmap.h
src/runtime/hashmap.h
+13
-12
test/ken/range.go
test/ken/range.go
+113
-0
No files found.
src/cmd/gc/dcl.c
View file @
26b357ca
...
...
@@ -1263,7 +1263,7 @@ void
constiter
(
Node
*
vv
,
Type
*
t
,
Node
*
cc
)
{
Iter
viter
,
citer
;
Node
*
v
,
*
c
,
*
a
;
Node
*
v
,
*
c
;
if
(
cc
==
N
)
cc
=
lastconst
;
...
...
src/cmd/gc/go.h
View file @
26b357ca
...
...
@@ -74,6 +74,33 @@ struct Array
uchar
b
;
// actual array - may not be contig
};
/*
* note this is the runtime representation
* of hashmap iterator. it is probably
* insafe to use it this way, but it puts
* all the changes in one place.
* only flag is referenced from go.
* actual placement does not matter as long
* as the size is >= actual size.
*/
typedef
struct
Hiter
Hiter
;
struct
Hiter
{
uchar
data
[
8
];
// return val from next
int32
elemsize
;
// size of elements in table */
int32
changes
;
// number of changes observed last time */
int32
i
;
// stack pointer in subtable_state */
uchar
last
[
8
];
// last hash value returned */
uchar
h
[
8
];
// the hash table */
struct
{
uchar
sub
[
8
];
// pointer into subtable */
uchar
start
[
8
];
// pointer into start of subtable */
uchar
end
[
8
];
// pointer into end of subtable */
uchar
pad
[
8
];
}
sub
[
4
];
};
enum
{
Mpscale
=
29
,
// safely smaller than bits in a long
...
...
@@ -779,6 +806,7 @@ int isandss(Type*, Node*);
Node
*
convas
(
Node
*
);
void
arrayconv
(
Type
*
,
Node
*
);
Node
*
colas
(
Node
*
,
Node
*
);
Node
*
dorange
(
Node
*
,
Node
*
,
Node
*
,
int
);
Node
*
reorder1
(
Node
*
);
Node
*
reorder2
(
Node
*
);
Node
*
reorder3
(
Node
*
);
...
...
src/cmd/gc/go.y
View file @
26b357ca
...
...
@@ -51,8 +51,7 @@
%
type
<
node
>
stmt_list_r
Astmt_list_r
Bstmt_list_r
%
type
<
node
>
Astmt
Bstmt
%
type
<
node
>
for_stmt
for_body
for_header
%
type
<
node
>
if_stmt
if_body
if_header
%
type
<
node
>
range_header
range_body
range_stmt
select_stmt
%
type
<
node
>
if_stmt
if_body
if_header
select_stmt
%
type
<
node
>
simple_stmt
osimple_stmt
semi_stmt
%
type
<
node
>
expr
uexpr
pexpr
expr_list
oexpr
oexpr_list
expr_list_r
%
type
<
node
>
exprsym3_list_r
exprsym3
...
...
@@ -478,11 +477,6 @@ complex_stmt:
popdcl
();
$$
=
$
2
;
}
|
LRANGE
range_stmt
{
popdcl
();
$$
=
$
2
;
}
|
LCASE
expr_list
':'
{
//
will
be
converted
to
OCASE
...
...
@@ -578,12 +572,20 @@ for_header:
$$->
ntest
=
$
1
;
$$->
nincr
=
N
;
}
|
new_name
':'
new_name
LRANGE
expr
{
$$
=
dorange
($
1
,
$
3
,
$
5
,
1
);
}
|
new_name
LRANGE
expr
{
$$
=
dorange
($
1
,
N
,
$
3
,
1
);
}
for_body
:
for_header
compound_stmt
{
$$
=
$
1
;
$$->
nbody
=
$
2
;
$$->
nbody
=
list
($$->
nbody
,
$
2
)
;
}
for_stmt
:
...
...
@@ -625,36 +627,6 @@ if_stmt:
$$
=
$
2
;
}
range_header
:
new_name
LCOLAS
expr
{
$$
=
N
;
}
|
new_name
','
new_name
LCOLAS
expr
{
$$
=
N
;
}
|
new_name
','
new_name
'='
expr
{
yyerror
(
"range statement only allows := assignment"
);
$$
=
N
;
}
range_body
:
range_header
compound_stmt
{
$$
=
$
1
;
$$->
nbody
=
$
2
;
}
range_stmt
:
{
markdcl
();
}
range_body
{
$$
=
$
2
;
}
select_stmt
:
{
markdcl
();
...
...
src/cmd/gc/sys.go
View file @
26b357ca
...
...
@@ -51,8 +51,8 @@ export func Inf(int) float64; // return signed Inf
export
func
NaN
()
float64
;
// return a NaN
export
func
float32bits
(
float32
)
uint32
;
// raw bits
export
func
float64bits
(
float64
)
uint64
;
// raw bits
export
func
float32frombits
(
uint32
)
float32
;
// raw bits
export
func
float64frombits
(
uint64
)
float64
;
// raw bits
export
func
float32frombits
(
uint32
)
float32
;
// raw bits
export
func
float64frombits
(
uint64
)
float64
;
// raw bits
export
func
newmap
(
keysize
int
,
valsize
int
,
keyalg
int
,
valalg
int
,
...
...
@@ -61,6 +61,10 @@ export func mapaccess1(hmap *map[any]any, key any) (val any);
export
func
mapaccess2
(
hmap
*
map
[
any
]
any
,
key
any
)
(
val
any
,
pres
bool
);
export
func
mapassign1
(
hmap
*
map
[
any
]
any
,
key
any
,
val
any
);
export
func
mapassign2
(
hmap
*
map
[
any
]
any
,
key
any
,
val
any
,
pres
bool
);
export
func
mapiterinit
(
hmap
*
map
[
any
]
any
,
hiter
*
any
);
export
func
mapiternext
(
hiter
*
any
);
export
func
mapiter1
(
hiter
*
any
)
(
key
any
);
export
func
mapiter2
(
hiter
*
any
)
(
key
any
,
val
any
);
export
func
newchan
(
elemsize
int
,
elemalg
int
,
hint
int
)
(
hchan
*
chan
any
);
export
func
chanrecv1
(
hchan
*
chan
any
)
(
elem
any
);
...
...
src/cmd/gc/sysimport.c
View file @
26b357ca
char
*
sysimport
=
char
*
sysimport
=
"package sys
\n
"
"export func sys.mal (? int32) (? *any)
\n
"
"export func sys.breakpoint ()
\n
"
...
...
@@ -48,6 +48,10 @@ char *sysimport =
"export func sys.mapaccess2 (hmap *map[any] any, key any) (val any, pres bool)
\n
"
"export func sys.mapassign1 (hmap *map[any] any, key any, val any)
\n
"
"export func sys.mapassign2 (hmap *map[any] any, key any, val any, pres bool)
\n
"
"export func sys.mapiterinit (hmap *map[any] any, hiter *any)
\n
"
"export func sys.mapiternext (hiter *any)
\n
"
"export func sys.mapiter1 (hiter *any) (key any)
\n
"
"export func sys.mapiter2 (hiter *any) (key any, val any)
\n
"
"export func sys.newchan (elemsize int, elemalg int, hint int) (hchan *chan any)
\n
"
"export func sys.chanrecv1 (hchan *chan any) (elem any)
\n
"
"export func sys.chanrecv2 (hchan *chan any) (elem any, pres bool)
\n
"
...
...
src/cmd/gc/walk.c
View file @
26b357ca
...
...
@@ -3033,6 +3033,110 @@ badt:
return
nl
;
}
Node
*
dorange
(
Node
*
k
,
Node
*
v
,
Node
*
m
,
int
local
)
{
Node
*
n
,
*
hk
,
*
on
,
*
r
,
*
a
;
Type
*
t
,
*
th
;
if
(
!
local
)
fatal
(
"only local varables now"
);
n
=
nod
(
OFOR
,
N
,
N
);
walktype
(
m
,
Erv
);
t
=
m
->
type
;
if
(
t
==
T
)
goto
out
;
if
(
t
->
etype
==
TARRAY
)
goto
ary
;
if
(
isptrto
(
t
,
TARRAY
))
{
t
=
t
->
type
;
goto
ary
;
}
if
(
t
->
etype
==
TMAP
)
goto
map
;
if
(
isptrto
(
t
,
TMAP
))
{
t
=
t
->
type
;
goto
map
;
}
yyerror
(
"range must be over map/array"
);
goto
out
;
ary:
hk
=
nod
(
OXXX
,
N
,
N
);
// hidden key
tempname
(
hk
,
types
[
TINT
]);
// maybe TINT32
n
->
ninit
=
nod
(
OAS
,
hk
,
literal
(
0
));
n
->
ntest
=
nod
(
OLT
,
hk
,
nod
(
OLEN
,
m
,
N
));
n
->
nincr
=
nod
(
OASOP
,
hk
,
literal
(
1
));
n
->
nincr
->
etype
=
OADD
;
k
=
old2new
(
k
,
hk
->
type
);
n
->
nbody
=
nod
(
OAS
,
k
,
hk
);
if
(
v
!=
N
)
{
v
=
old2new
(
v
,
t
->
type
);
n
->
nbody
=
list
(
n
->
nbody
,
nod
(
OAS
,
v
,
nod
(
OINDEX
,
m
,
hk
))
);
}
goto
out
;
map:
th
=
typ
(
TARRAY
);
th
->
type
=
ptrto
(
types
[
TUINT8
]);
th
->
bound
=
(
sizeof
(
struct
Hiter
)
+
types
[
tptr
]
->
width
-
1
)
/
types
[
tptr
]
->
width
;
hk
=
nod
(
OXXX
,
N
,
N
);
// hidden iterator
tempname
(
hk
,
th
);
// hashmap hash_iter
on
=
syslook
(
"mapiterinit"
,
1
);
argtype
(
on
,
t
->
down
);
argtype
(
on
,
t
->
type
);
argtype
(
on
,
th
);
r
=
nod
(
OADDR
,
hk
,
N
);
r
=
list
(
m
,
r
);
r
=
nod
(
OCALL
,
on
,
r
);
n
->
ninit
=
r
;
r
=
nod
(
OINDEX
,
hk
,
literal
(
0
));
a
=
nod
(
OLITERAL
,
N
,
N
);
a
->
val
.
ctype
=
CTNIL
;
r
=
nod
(
ONE
,
r
,
a
);
n
->
ntest
=
r
;
on
=
syslook
(
"mapiternext"
,
1
);
argtype
(
on
,
th
);
r
=
nod
(
OADDR
,
hk
,
N
);
r
=
nod
(
OCALL
,
on
,
r
);
n
->
nincr
=
r
;
k
=
old2new
(
k
,
t
->
down
);
if
(
v
==
N
)
{
on
=
syslook
(
"mapiter1"
,
1
);
argtype
(
on
,
th
);
argtype
(
on
,
t
->
down
);
r
=
nod
(
OADDR
,
hk
,
N
);
r
=
nod
(
OCALL
,
on
,
r
);
n
->
nbody
=
nod
(
OAS
,
k
,
r
);
goto
out
;
}
v
=
old2new
(
v
,
t
->
type
);
on
=
syslook
(
"mapiter2"
,
1
);
argtype
(
on
,
th
);
argtype
(
on
,
t
->
down
);
argtype
(
on
,
t
->
type
);
r
=
nod
(
OADDR
,
hk
,
N
);
r
=
nod
(
OCALL
,
on
,
r
);
n
->
nbody
=
nod
(
OAS
,
nod
(
OLIST
,
k
,
v
),
r
);
goto
out
;
out:
return
n
;
}
/*
* from ascompat[te]
* evaluating actual function arguments.
...
...
src/runtime/hashmap.c
View file @
26b357ca
...
...
@@ -649,7 +649,7 @@ donothing(uint32 s, void *a, void *b)
USED
(
b
);
}
typedef
struct
hash
Hmap
;
typedef
struct
hash
Hmap
;
static
int32
debug
=
0
;
// newmap(keysize uint32, valsize uint32,
...
...
@@ -860,3 +860,86 @@ sys·mapassign2(Hmap *h, ...)
prints
(
"
\n
"
);
}
}
// mapiterinit(hmap *map[any]any, hiter *any);
void
sys
·
mapiterinit
(
Hmap
*
h
,
struct
hash_iter
*
it
)
{
hash_iter_init
(
h
,
it
);
it
->
data
=
hash_next
(
it
);
if
(
debug
)
{
prints
(
"sys·mapiterinit: map="
);
sys
·
printpointer
(
h
);
prints
(
"; iter="
);
sys
·
printpointer
(
it
);
prints
(
"; data="
);
sys
·
printpointer
(
it
->
data
);
prints
(
"
\n
"
);
}
}
// mapiternext(hiter *any);
void
sys
·
mapiternext
(
struct
hash_iter
*
it
)
{
it
->
data
=
hash_next
(
it
);
if
(
debug
)
{
prints
(
"sys·mapiternext: iter="
);
sys
·
printpointer
(
it
);
prints
(
"; data="
);
sys
·
printpointer
(
it
->
data
);
prints
(
"
\n
"
);
}
}
// mapiter1(hiter *any) (key any);
void
sys
·
mapiter1
(
struct
hash_iter
*
it
,
...)
{
Hmap
*
h
;
byte
*
ak
,
*
res
;
h
=
it
->
h
;
ak
=
(
byte
*
)
&
it
+
h
->
ko
;
res
=
it
->
data
;
if
(
res
==
nil
)
throw
(
"sys·mapiter2: key:val nil pointer"
);
h
->
keyalg
->
copy
(
h
->
keysize
,
ak
,
res
);
if
(
debug
)
{
prints
(
"mapiter2: iter="
);
sys
·
printpointer
(
it
);
prints
(
"; map="
);
sys
·
printpointer
(
h
);
prints
(
"
\n
"
);
}
}
// mapiter2(hiter *any) (key any, val any);
void
sys
·
mapiter2
(
struct
hash_iter
*
it
,
...)
{
Hmap
*
h
;
byte
*
ak
,
*
av
,
*
res
;
h
=
it
->
h
;
ak
=
(
byte
*
)
&
it
+
h
->
ko
;
av
=
(
byte
*
)
&
it
+
h
->
vo
;
res
=
it
->
data
;
if
(
res
==
nil
)
throw
(
"sys·mapiter2: key:val nil pointer"
);
h
->
keyalg
->
copy
(
h
->
keysize
,
ak
,
res
);
h
->
valalg
->
copy
(
h
->
valsize
,
av
,
res
+
h
->
keysize
);
if
(
debug
)
{
prints
(
"mapiter2: iter="
);
sys
·
printpointer
(
it
);
prints
(
"; map="
);
sys
·
printpointer
(
h
);
prints
(
"
\n
"
);
}
}
src/runtime/hashmap.h
View file @
26b357ca
...
...
@@ -72,24 +72,25 @@
#define memcpy(a,b,c) mcpy((byte*)(a),(byte*)(b),(uint32)(c))
#define assert(a) if(!(a)) throw("assert")
struct
hash
;
/* opaque */
struct
hash_subtable
;
/* opaque */
struct
hash_entry
;
/* opaque */
struct
hash
;
/* opaque */
struct
hash_subtable
;
/* opaque */
struct
hash_entry
;
/* opaque */
typedef
uint64
uintptr_t
;
typedef
uintptr_t
hash_hash_t
;
struct
hash_iter
{
int32
elemsize
;
/* size of elements in table */
int32
changes
;
/* number of changes observed last time */
int32
i
;
/* stack pointer in subtable_state */
hash_hash_t
last_hash
;
/* last hash value returned */
struct
hash
*
h
;
/* the hash table */
uint8
*
data
;
/* returned from next */
int32
elemsize
;
/* size of elements in table */
int32
changes
;
/* number of changes observed last time */
int32
i
;
/* stack pointer in subtable_state */
hash_hash_t
last_hash
;
/* last hash value returned */
struct
hash
*
h
;
/* the hash table */
struct
hash_iter_sub
{
struct
hash_entry
*
e
;
/* pointer into subtable */
struct
hash_entry
*
start
;
/* start of subtable */
struct
hash_entry
*
end
;
/* end of subtable */
}
subtable_state
[
16
];
/* Should be large enough unless the hashing is
struct
hash_entry
*
e
;
/* pointer into subtable */
struct
hash_entry
*
start
;
/* start of subtable */
struct
hash_entry
*
end
;
/* end of subtable */
}
subtable_state
[
4
];
/* Should be large enough unless the hashing is
so bad that many distinct data values hash
to the same hash value. */
};
...
...
test/ken/range.go
0 → 100644
View file @
26b357ca
// $G $D/$F.go && $L $F.$A && ./$A.out
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
main
const
size
=
16
;
var
a
[
size
]
byte
;
var
p
*
[]
byte
;
var
m
*
map
[
int
]
byte
;
func
f
(
k
int
)
byte
{
return
byte
(
k
*
10007
%
size
);
}
func
init
()
{
p
=
new
([]
byte
,
size
);
m
=
new
(
map
[
int
]
byte
);
for
k
:=
0
;
k
<
size
;
k
++
{
v
:=
f
(
k
);
a
[
k
]
=
v
;
p
[
k
]
=
v
;
m
[
k
]
=
v
;
}
}
func
main
()
{
var
i
int
;
/*
* key only
*/
i
=
0
;
for
k
range
a
{
v
:=
a
[
k
];
if
v
!=
f
(
k
)
{
panicln
(
"key array range"
,
k
,
v
,
a
[
k
]);
}
i
++
;
}
if
i
!=
size
{
panicln
(
"key array size"
,
i
);
}
i
=
0
;
for
k
range
p
{
v
:=
p
[
k
];
if
v
!=
f
(
k
)
{
panicln
(
"key pointer range"
,
k
,
v
,
p
[
k
]);
}
i
++
;
}
if
i
!=
size
{
panicln
(
"key pointer size"
,
i
);
}
i
=
0
;
for
k
range
m
{
v
:=
m
[
k
];
if
v
!=
f
(
k
)
{
panicln
(
"key map range"
,
k
,
v
,
m
[
k
]);
}
i
++
;
}
if
i
!=
size
{
panicln
(
"key map size"
,
i
);
}
/*
* key:value
*/
i
=
0
;
for
k
:
v
range
a
{
if
v
!=
f
(
k
)
{
panicln
(
"key:value array range"
,
k
,
v
,
a
[
k
]);
}
i
++
;
}
if
i
!=
size
{
panicln
(
"key:value array size"
,
i
);
}
i
=
0
;
for
k
:
v
range
p
{
if
v
!=
f
(
k
)
{
panicln
(
"key:value pointer range"
,
k
,
v
,
p
[
k
]);
}
i
++
;
}
if
i
!=
size
{
panicln
(
"key:value pointer size"
,
i
);
}
i
=
0
;
for
k
:
v
range
m
{
if
v
!=
f
(
k
)
{
panicln
(
"key:value map range"
,
k
,
v
,
m
[
k
]);
}
i
++
;
}
if
i
!=
size
{
panicln
(
"key:value map size"
,
i
);
}
}
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