Toggle navigation
Toggle navigation
This project
Loading...
Sign in
Franck Pommereau
/
zinc
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
Franck Pommereau
2017-11-28 11:50:33 +0100
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
2afb0566c8fef76723a3f271c998a928c3d82568
2afb0566
1 parent
ad0f4490
reimplemented Go lib with proper dicts
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
284 additions
and
363 deletions
libs/go/src/dicts/dicts.go
libs/go/src/snk/main.go
libs/go/src/snk/markings.go
libs/go/src/snk/multisets.go
libs/go/src/snk/sets.go
snakes/compil/go/codegen.py
snakes/compil/python/codegen.py
test/gotest.py
test/testall-go.snk
libs/go/src/dicts/dicts.go
View file @
2afb056
//
Go implementation Python3 dicts, translat
ed from a Python version at
//
Python3 dicts ported to Go, inspir
ed from a Python version at
// https://code.activestate.com/recipes/578375/
package
dicts
...
...
@@ -6,6 +6,7 @@ package dicts
import
(
"bytes"
"fmt"
"hash/fnv"
)
type
Hashable
interface
{
...
...
@@ -35,19 +36,16 @@ func hash (key Hashable) uint64 {
}
}
// # Placeholder constants
// FREE = -1
// DUMMY = -2
func
StringHash
(
s
string
)
uint64
{
hash
:=
fnv
.
New64
()
hash
.
Write
([]
byte
(
s
))
return
hash
.
Sum64
()
}
const
_FREE
int64
=
-
1
const
_DUMMY
int64
=
-
2
// def __init__(self, *args, **kwds):
// if not hasattr(self, 'keylist'):
// self.clear()
// self.update(*args, **kwds)
func
NewDict
(
items
...
Item
)
Dict
{
func
MakeDict
(
items
...
Item
)
Dict
{
d
:=
Dict
{}
d
.
Clear
()
for
_
,
i
:=
range
items
{
...
...
@@ -56,21 +54,6 @@ func NewDict (items ...Item) Dict {
return
d
}
// def _make_index(n):
// 'New sequence of indices using the smallest possible datatype'
// # if n <= 2**7: return array.array('b', [FREE]) * n # signed char
// # if n <= 2**15: return array.array('h', [FREE]) * n # signed short
// # if n <= 2**31: return array.array('l', [FREE]) * n # signed long
// return [FREE] * n # python integers
//
// def clear(self):
// self.indices = self._make_index(8)
// self.hashlist = []
// self.keylist = []
// self.valuelist = []
// self.used = 0
// self.filled = 0 # used + dummies
func
(
self
*
Dict
)
Clear
()
{
self
.
indices
=
make
(
map
[
uint64
]
int64
)
self
.
itemlist
=
make
([]
Item
,
0
)
...
...
@@ -78,26 +61,10 @@ func (self *Dict) Clear () {
self
.
filled
=
0
}
// def __len__(self):
// return self.used
func
(
self
Dict
)
Len
()
uint64
{
return
self
.
used
}
// def _gen_probes(hashvalue, mask):
// 'Same sequence of probes used in the current dictionary design'
// PERTURB_SHIFT = 5
// if hashvalue < 0:
// hashvalue = -hashvalue
// i = hashvalue & mask
// yield i
// perturb = hashvalue
// while True:
// i = (5 * i + perturb + 1) & 0xFFFFFFFFFFFFFFFF
// yield i & mask
// perturb >>= PERTURB_SHIFT
const
_PERTURB_SHIFT
uint64
=
5
type
probe
struct
{
...
...
@@ -116,22 +83,6 @@ func (self *probe) next () uint64 {
return
self
.
i
}
// def _lookup(self, key, hashvalue):
// 'Same lookup logic as currently used in real dicts'
// assert self.filled < len(self.indices) # At least one open slot
// freeslot = None
// for i in self._gen_probes(hashvalue, len(self.indices)-1):
// index = self.indices[i]
// if index == FREE:
// return (FREE, i) if freeslot is None else (DUMMY, freeslot)
// elif index == DUMMY:
// if freeslot is None:
// freeslot = i
// elif (self.keylist[index] is key or
// self.hashlist[index] == hashvalue
// and self.keylist[index] == key):
// return (index, i)
func
(
self
Dict
)
lookup
(
key
Hashable
,
hashvalue
uint64
)
(
int64
,
uint64
)
{
var
freeslot
*
uint64
=
nil
for
i
,
p
:=
first_probe
(
hashvalue
);
true
;
i
=
p
.
next
()
{
...
...
@@ -147,58 +98,34 @@ func (self Dict) lookup (key Hashable, hashvalue uint64) (int64, uint64) {
freeslot
=
new
(
uint64
)
*
freeslot
=
i
}
}
else
if
self
.
itemlist
[
index
]
.
Key
==
&
key
||
(
self
.
itemlist
[
index
]
.
hash
==
hashvalue
&&
(
*
(
self
.
itemlist
[
index
]
.
Key
))
.
Eq
(
key
))
{
return
index
,
i
}
else
{
item
:=
self
.
itemlist
[
index
]
if
item
.
Key
==
&
key
||
item
.
hash
==
hashvalue
&&
(
*
item
.
Key
)
.
Eq
(
key
)
{
return
index
,
i
}
}
}
// never reached
return
0
,
0
}
// def __getitem__(self, key):
// hashvalue = hash(key)
// index, i = self._lookup(key, hashvalue)
// if index < 0:
// raise KeyError(key)
// return self.valuelist[index]
func
(
self
Dict
)
Get
(
key
Hashable
)
interface
{}
{
func
(
self
Dict
)
Get
(
key
Hashable
)
*
interface
{}
{
index
,
_
:=
self
.
lookup
(
key
,
hash
(
key
))
if
index
<
0
{
panic
(
"Dict has no such key"
)
return
nil
}
return
*
(
self
.
itemlist
[
index
]
.
Value
)
return
self
.
itemlist
[
index
]
.
Value
}
// def get(self, key, default=None):
// index, i = self._lookup(key, hash(key))
// return self.valuelist[index] if index >= 0 else default
func
(
self
Dict
)
Fetch
(
key
Hashable
,
fallback
interface
{})
interface
{}
{
func
(
self
Dict
)
Fetch
(
key
Hashable
,
fallback
interface
{})
*
interface
{}
{
index
,
_
:=
self
.
lookup
(
key
,
hash
(
key
))
if
index
<
0
{
return
fallback
return
&
fallback
}
else
{
return
*
(
self
.
itemlist
[
index
]
.
Value
)
return
self
.
itemlist
[
index
]
.
Value
}
}
// def __setitem__(self, key, value):
// hashvalue = hash(key)
// index, i = self._lookup(key, hashvalue)
// if index < 0:
// self.indices[i] = self.used
// self.hashlist.append(hashvalue)
// self.keylist.append(key)
// self.valuelist.append(value)
// self.used += 1
// if index == FREE:
// self.filled += 1
// if self.filled * 3 > len(self.indices) * 2:
// self._resize(4 * len(self))
// else:
// self.valuelist[index] = value
func
(
self
*
Dict
)
Set
(
key
Hashable
,
value
interface
{})
{
hashvalue
:=
hash
(
key
)
index
,
i
:=
self
.
lookup
(
key
,
hashvalue
)
...
...
@@ -214,32 +141,8 @@ func (self *Dict) Set (key Hashable, value interface{}) {
}
}
// def __delitem__(self, key):
// hashvalue = hash(key)
// index, i = self._lookup(key, hashvalue)
// if index < 0:
// raise KeyError(key)
// self.indices[i] = DUMMY
// self.used -= 1
// # If needed, swap with the lastmost entry to avoid leaving a "hole"
// if index != self.used:
// lasthash = self.hashlist[-1]
// lastkey = self.keylist[-1]
// lastvalue = self.valuelist[-1]
// lastindex, j = self._lookup(lastkey, lasthash)
// assert lastindex >= 0 and i != j
// self.indices[j] = index
// self.hashlist[index] = lasthash
// self.keylist[index] = lastkey
// self.valuelist[index] = lastvalue
// # Remove the lastmost entry
// self.hashlist.pop()
// self.keylist.pop()
// self.valuelist.pop()
func
(
self
*
Dict
)
Del
(
key
Hashable
)
{
hashvalue
:=
hash
(
key
)
index
,
i
:=
self
.
lookup
(
key
,
hashvalue
)
index
,
i
:=
self
.
lookup
(
key
,
hash
(
key
))
if
index
<
0
{
return
}
...
...
@@ -257,19 +160,12 @@ func (self *Dict) Del (key Hashable) {
self
.
itemlist
=
self
.
itemlist
[
:
self
.
used
]
}
// def keys(self):
// return list(self.keylist)
// def values(self):
// return list(self.valuelist)
// def items(self):
// return zip(self.keylist, self.valuelist)
type
dictiter
struct
{
type
DictIterator
struct
{
i
uint64
d
*
Dict
}
func
(
self
*
dictite
r
)
Next
()
*
Item
{
func
(
self
*
DictIterato
r
)
Next
()
*
Item
{
self
.
i
++
if
self
.
i
>=
self
.
d
.
used
{
return
nil
...
...
@@ -278,8 +174,8 @@ func (self *dictiter) Next () *Item {
}
}
func
(
self
Dict
)
Iter
()
(
dictite
r
,
*
Item
)
{
it
:=
dictite
r
{
0
,
&
self
}
func
(
self
Dict
)
Iter
()
(
DictIterato
r
,
*
Item
)
{
it
:=
DictIterato
r
{
0
,
&
self
}
if
self
.
used
==
0
{
return
it
,
nil
}
else
{
...
...
@@ -287,23 +183,11 @@ func (self Dict) Iter () (dictiter, *Item) {
}
}
// def __contains__(self, key):
// index, i = self._lookup(key, hash(key))
// return index >= 0
func
(
self
Dict
)
Has
(
key
Hashable
)
bool
{
index
,
_
:=
self
.
lookup
(
key
,
hash
(
key
))
return
index
>=
0
}
// def popitem(self):
// if not self.keylist:
// raise KeyError('popitem(): dictionary is empty')
// key = self.keylist[-1]
// value = self.valuelist[-1]
// del self[key]
// return key, value
func
(
self
*
Dict
)
Pop
()
Item
{
if
self
.
used
==
0
{
panic
(
"cannot Pop from empty Dict"
)
...
...
@@ -313,9 +197,6 @@ func (self *Dict) Pop () Item {
return
item
}
// def __repr__(self):
// return 'Dict(%r)' % self.items()
func
(
self
Dict
)
String
()
string
{
buf
:=
bytes
.
NewBufferString
(
"{"
)
for
i
:=
uint64
(
0
);
i
<
self
.
used
;
i
++
{
...
...
@@ -330,15 +211,6 @@ func (self Dict) String () string {
return
buf
.
String
()
}
// def show_structure(self):
// 'Diagnostic method. Not part of the API.'
// print '=' * 50
// print self
// print 'Indices:', self.indices
// for i, row in enumerate(zip(self.hashlist, self.keylist, self.valuelist)):
// print i, row
// print '-' * 50
func
(
self
Item
)
String
()
string
{
return
fmt
.
Sprintf
(
"Item{%s}"
,
fmt
.
Sprintf
(
"%s, %s, %d"
,
...
...
@@ -353,9 +225,10 @@ func (self Dict) ShowStructure () {
}
fmt
.
Println
()
fmt
.
Println
(
self
)
fmt
.
Println
(
"Indices: "
,
self
.
indices
)
fmt
.
Println
(
"Indices:"
,
self
.
indices
)
fmt
.
Println
(
"Items:"
)
for
i
:=
uint64
(
0
);
i
<
self
.
used
;
i
++
{
fmt
.
Print
ln
(
self
.
itemlist
[
i
])
fmt
.
Print
f
(
" [%d] %s
\n
"
,
i
,
self
.
itemlist
[
i
])
}
for
i
:=
0
;
i
<
50
;
i
++
{
fmt
.
Print
(
"-"
)
...
...
libs/go/src/snk/main.go
View file @
2afb056
...
...
@@ -6,7 +6,7 @@ import "fmt"
func
StateSpace
(
init
func
()
Marking
,
addsucc
func
(
Marking
,
Set
),
print_states
bool
,
print_succs
bool
)
int
{
var
succ
Set
count
:=
0
count
:=
1
i
:=
init
()
todo
:=
MakeQueue
(
&
i
)
seen
:=
MakeSet
(
&
i
)
...
...
libs/go/src/snk/markings.go
View file @
2afb056
...
...
@@ -3,22 +3,23 @@ package snk
import
"fmt"
import
"bytes"
import
"hash/fnv"
import
"dicts"
type
Marking
struct
{
id
in
t
data
*
map
[
string
]
*
Mse
t
d
*
dicts
.
Dic
t
i
in
t
}
func
(
self
*
Marking
)
SetId
(
id
int
)
{
self
.
i
d
=
id
self
.
i
=
id
}
func
MakeMarking
(
id
...
int
)
Marking
{
m
:=
make
(
map
[
string
]
*
Mset
)
d
:=
dicts
.
MakeDict
(
)
if
len
(
id
)
==
0
{
return
Marking
{
-
1
,
&
m
}
return
Marking
{
&
d
,
-
1
}
}
else
if
len
(
id
)
==
1
{
return
Marking
{
id
[
0
],
&
m
}
return
Marking
{
&
d
,
id
[
0
]
}
}
else
{
panic
(
"at most one id expected"
)
}
...
...
@@ -27,14 +28,36 @@ func MakeMarking (id ...int) Marking {
func
(
self
Marking
)
Hash
()
uint64
{
var
h
uint64
=
2471033218594493899
hash
:=
fnv
.
New64
()
for
place
,
tokens
:=
range
*
self
.
data
{
for
iter
,
item
:=
self
.
d
.
Iter
();
item
!=
nil
;
item
=
iter
.
Next
()
{
hash
.
Reset
()
hash
.
Write
([]
byte
(
fmt
.
Sprintf
(
"[%s]{%x}"
,
place
,
tokens
.
Hash
())))
hash
.
Write
([]
byte
(
fmt
.
Sprintf
(
"[%s]{%x}"
,
fmt
.
Sprint
(
*
(
item
.
Key
)),
(
*
item
.
Value
)
.
(
Mset
)
.
Hash
())))
h
^=
hash
.
Sum64
()
}
return
h
}
type
place
struct
{
s
string
}
func
(
self
place
)
Hash
()
uint64
{
return
dicts
.
StringHash
(
self
.
s
)
}
func
(
self
place
)
Eq
(
other
interface
{})
bool
{
if
val
,
isplace
:=
other
.
(
place
);
isplace
{
return
val
.
s
==
self
.
s
}
else
{
return
false
}
}
func
(
self
Marking
)
Has
(
p
string
)
bool
{
return
self
.
d
.
Has
(
place
{
p
})
}
//### a := snk.MakeMarking()
//... a.Set("p1", 1, 2, 3, 4)
//... b := a.Copy()
...
...
@@ -69,15 +92,13 @@ func (self Marking) Hash () uint64 {
//=== true
func
(
self
Marking
)
Eq
(
other
Marking
)
bool
{
if
len
(
*
self
.
data
)
!=
len
(
*
other
.
data
)
{
if
self
.
d
.
Len
()
!=
other
.
d
.
Len
(
)
{
return
false
}
for
place
,
left
:=
range
*
self
.
data
{
if
right
,
found
:=
(
*
other
.
data
)[
place
]
;
found
{
if
!
left
.
Eq
(
*
right
)
{
return
false
}
}
else
{
for
iter
,
p
,
m
:=
self
.
Iter
();
p
!=
nil
;
p
,
m
=
iter
.
Next
()
{
if
!
other
.
d
.
Has
(
place
{
*
p
})
{
return
false
}
else
if
!
m
.
Eq
(
other
.
Get
(
*
p
))
{
return
false
}
}
...
...
@@ -86,12 +107,12 @@ func (self Marking) Eq (other Marking) bool {
//+++ snk.MakeMarking().Eq(snk.MakeMarking())
func
(
self
Marking
)
Set
(
p
lace
string
,
tokens
...
interface
{})
{
func
(
self
Marking
)
Set
(
p
string
,
tokens
...
interface
{})
{
if
len
(
tokens
)
==
0
{
delete
(
*
self
.
data
,
place
)
self
.
d
.
Del
(
place
{
p
}
)
}
else
{
m
:=
MakeMset
(
tokens
...
)
(
*
self
.
data
)[
place
]
=
&
m
self
.
d
.
Set
(
place
{
p
},
m
)
}
}
...
...
@@ -110,12 +131,12 @@ func (self Marking) Set (place string, tokens ...interface{}) {
//... a.Get("p1").Empty()
//=== true
func
(
self
Marking
)
Update
(
place
string
,
tokens
Mset
)
{
if
_
,
found
:=
(
*
self
.
data
)[
place
]
;
found
{
(
*
self
.
data
)[
place
]
.
Add
(
tokens
)
func
(
self
Marking
)
Update
(
p
string
,
tokens
Mset
)
{
if
self
.
Has
(
p
)
{
m
:=
self
.
Get
(
p
)
m
.
Add
(
tokens
)
}
else
{
m
:=
tokens
.
Copy
()
(
*
self
.
data
)[
place
]
=
&
m
self
.
d
.
Set
(
place
{
p
},
tokens
.
Copy
())
}
}
...
...
@@ -131,9 +152,8 @@ func (self Marking) Update (place string, tokens Mset) {
func
(
self
Marking
)
Copy
()
Marking
{
copy
:=
MakeMarking
()
for
key
,
value
:=
range
*
self
.
data
{
m
:=
value
.
Copy
()
(
*
copy
.
data
)[
key
]
=
&
m
for
iter
,
p
,
m
:=
self
.
Iter
();
p
!=
nil
;
p
,
m
=
iter
.
Next
()
{
copy
.
Update
(
*
p
,
*
m
)
}
return
copy
}
...
...
@@ -183,12 +203,8 @@ func (self Marking) Copy () Marking {
//... a.Eq(b)
//=== false
func
(
self
Marking
)
Get
(
place
string
)
Mset
{
if
value
,
found
:=
(
*
self
.
data
)[
place
]
;
found
{
return
*
value
}
else
{
return
MakeMset
()
}
func
(
self
Marking
)
Get
(
p
string
)
Mset
{
return
(
*
(
self
.
d
.
Fetch
(
place
{
p
},
MakeMset
())))
.
(
Mset
)
}
//### a := snk.MakeMarking()
...
...
@@ -211,11 +227,7 @@ func (self Marking) Get (place string) Mset {
func
(
self
Marking
)
NotEmpty
(
places
...
string
)
bool
{
for
_
,
key
:=
range
places
{
if
value
,
found
:=
(
*
self
.
data
)[
key
]
;
found
{
if
value
.
Empty
()
{
return
false
}
}
else
{
if
self
.
Get
(
key
)
.
Empty
()
{
return
false
}
}
...
...
@@ -247,8 +259,8 @@ func (self Marking) NotEmpty (places ...string) bool {
//=== false
func
(
self
Marking
)
Add
(
other
Marking
)
Marking
{
for
place
,
right
:=
range
*
other
.
data
{
self
.
Update
(
place
,
*
right
)
for
iter
,
p
,
m
:=
other
.
Iter
();
p
!=
nil
;
p
,
m
=
iter
.
Next
()
{
self
.
Update
(
*
p
,
*
m
)
}
return
self
}
...
...
@@ -259,21 +271,21 @@ func (self Marking) Add (other Marking) Marking {
//... b := snk.MakeMarking()
//... b.Set("p2", 2, 4)
//... b.Set("p3", 1)
//... a.Add(b)
//... c := snk.MakeMarking()
//... c.Set("p1", 1, 2, 2, 3)
//... c.Set("p2", 1, 1, 2, 4, 4)
//... c.Set("p3", 1)
//... a.Add(b)
//... a.Eq(c)
//=== true
func
(
self
Marking
)
Sub
(
other
Marking
)
Marking
{
for
place
,
right
:=
range
*
other
.
data
{
if
left
,
found
:=
(
*
self
.
data
)[
place
]
;
found
{
left
.
Sub
(
*
right
)
if
left
.
Empty
()
{
delete
(
*
self
.
data
,
place
)
}
for
iter
,
p
,
m
:=
other
.
Iter
();
p
!=
nil
;
p
,
m
=
iter
.
Next
()
{
mine
:=
self
.
Get
(
*
p
)
if
m
.
Geq
(
mine
)
{
self
.
d
.
Del
(
place
{
*
p
})
}
else
{
mine
.
Sub
(
*
m
)
}
}
return
self
...
...
@@ -293,12 +305,8 @@ func (self Marking) Sub (other Marking) Marking {
//=== true
func
(
self
Marking
)
Geq
(
other
Marking
)
bool
{
for
key
,
value
:=
range
*
other
.
data
{
if
mine
,
found
:=
(
*
self
.
data
)[
key
]
;
found
{
if
!
mine
.
Geq
(
*
value
)
{
return
false
}
}
else
{
for
iter
,
p
,
m
:=
other
.
Iter
();
p
!=
nil
;
p
,
m
=
iter
.
Next
()
{
if
!
self
.
Get
(
*
p
)
.
Geq
(
*
m
)
{
return
false
}
}
...
...
@@ -350,21 +358,30 @@ func (self Marking) Geq (other Marking) bool {
//... a.Geq(b)
//=== false
func
(
self
Marking
)
Iter
(
place
string
)
(
MsetIterator
,
interface
{})
{
mset
,
found
:=
(
*
self
.
data
)[
place
]
if
found
{
return
mset
.
Iter
()
type
MarkingIterator
struct
{
iter
*
dicts
.
DictIterator
}
func
(
self
MarkingIterator
)
Next
()
(
*
string
,
*
Mset
)
{
next
:=
self
.
iter
.
Next
()
if
next
==
nil
{
return
nil
,
nil
}
else
{
return
MakeMset
()
.
Iter
()
p
:=
(
*
next
.
Key
)
.
(
place
)
m
:=
(
*
next
.
Value
)
.
(
Mset
)
return
&
(
p
.
s
),
&
m
}
}
func
(
self
Marking
)
IterDup
(
place
string
)
(
MsetIterator
,
interface
{})
{
mset
,
found
:=
(
*
self
.
data
)[
place
]
if
found
{
return
mset
.
IterDup
()
func
(
self
Marking
)
Iter
()
(
MarkingIterator
,
*
string
,
*
Mset
)
{
iter
,
item
:=
self
.
d
.
Iter
()
myiter
:=
MarkingIterator
{
&
iter
}
if
item
==
nil
{
return
myiter
,
nil
,
nil
}
else
{
return
MakeMset
()
.
Iter
()
p
:=
(
*
item
.
Key
)
.
(
place
)
m
:=
(
*
item
.
Value
)
.
(
Mset
)
return
myiter
,
&
(
p
.
s
),
&
m
}
}
...
...
@@ -372,7 +389,7 @@ func (self Marking) IterDup (place string) (MsetIterator, interface{}) {
//... a.Set("p1", 1, 2, 2, 3)
//... a.Set("p2", 1, 1, 4)
//... fmt.Print("{")
//... for i, p := a.
Iter("p1"
); p != nil; p = i.Next() { fmt.Print(*p, ", ") }
//... for i, p := a.
Get("p1").Iter(
); p != nil; p = i.Next() { fmt.Print(*p, ", ") }
//... fmt.Println("}")
//... nil
//>>> eval(out) == {1, 2, 3}
...
...
@@ -381,24 +398,25 @@ func (self Marking) IterDup (place string) (MsetIterator, interface{}) {
//... a.Set("p1", 1, 2, 2, 3)
//... a.Set("p2", 1, 1, 4)
//... fmt.Print("{")
//... for i, p := a.
Iter("p3"
); p != nil; p = i.Next() { fmt.Print(*p, ", ") }
//... for i, p := a.
Get("p3").Iter(
); p != nil; p = i.Next() { fmt.Print(*p, ", ") }
//... fmt.Println("}")
//... nil
//=== {}
func
(
self
Marking
)
String
()
string
{
buf
:=
bytes
.
NewBufferString
(
""
)
if
self
.
i
d
>=
0
{
buf
.
WriteString
(
fmt
.
Sprintf
(
"[%d] "
,
self
.
i
d
))
if
self
.
i
>=
0
{
buf
.
WriteString
(
fmt
.
Sprintf
(
"[%d] "
,
self
.
i
))
}
buf
.
WriteString
(
"{"
)
i
:=
0
for
key
,
value
:=
range
*
self
.
data
{
if
i
>
0
{
comma
:=
false
for
iter
,
p
,
m
:=
self
.
Iter
();
p
!=
nil
;
p
,
m
=
iter
.
Next
()
{
if
comma
{
buf
.
WriteString
(
", "
)
}
else
{
comma
=
true
}
i
+=
1
buf
.
WriteString
(
fmt
.
Sprintf
(
`"%s": %s`
,
key
,
value
))
buf
.
WriteString
(
fmt
.
Sprintf
(
`"%s": %s`
,
*
p
,
*
m
))
}
buf
.
WriteString
(
"}"
)
return
buf
.
String
()
...
...
libs/go/src/snk/multisets.go
View file @
2afb056
...
...
@@ -4,52 +4,73 @@ import "fmt"
import
"bytes"
import
"hash/fnv"
import
"hashstructure"
import
"dicts"
type
Mset
struct
{
d
ata
*
map
[
interface
{}]
in
t
d
*
dicts
.
Dic
t
}
func
(
self
Mset
)
Hash
()
uint64
{
var
h
uint64
=
13124430844775843711
hash
:=
fnv
.
New64
()
for
value
,
count
:=
range
*
self
.
data
{
hv
,
err
:=
hashstructure
.
Hash
(
value
,
nil
)
for
iter
,
item
:=
self
.
d
.
Iter
();
item
!=
nil
;
item
=
iter
.
Next
()
{
hv
,
err
:=
hashstructure
.
Hash
(
*
(
item
.
Key
)
,
nil
)
if
err
!=
nil
{
panic
(
err
)
}
hash
.
Reset
()
hash
.
Write
([]
byte
(
fmt
.
Sprintf
(
"[%x]{%x}"
,
hv
,
count
)))
hash
.
Write
([]
byte
(
fmt
.
Sprintf
(
"[%x]{%x}"
,
hv
,
*
(
item
.
Value
)
)))
h
^=
hash
.
Sum64
()
}
return
h
}
type
AsString
struct
{
val
*
interface
{}
}
func
(
self
AsString
)
Hash
()
uint64
{
return
dicts
.
StringHash
(
fmt
.
Sprint
(
*
(
self
.
val
)))
}
func
(
self
AsString
)
Eq
(
other
interface
{})
bool
{
if
v
,
ok
:=
other
.
(
AsString
);
ok
{
return
fmt
.
Sprint
(
*
(
self
.
val
))
==
fmt
.
Sprint
(
*
(
v
.
val
))
}
else
{
return
fmt
.
Sprint
(
*
(
self
.
val
))
==
fmt
.
Sprint
(
other
)
}
}
func
i2h
(
v
interface
{})
dicts
.
Hashable
{
return
AsString
{
&
v
}
}
func
h2i
(
v
*
dicts
.
Hashable
)
*
interface
{}
{
return
(
*
v
)
.
(
AsString
)
.
val
}
//+++ snk.MakeMset(1, 2, 2, 3, 3, 3).Hash() == snk.MakeMset(3, 3, 3, 2, 2, 1).Hash()
//+++ snk.MakeMset(1, 2, 2, 3, 3, 3).Hash() == snk.MakeMset(3, 2, 1, 3, 2, 3).Hash()
func
MakeMset
(
values
...
interface
{})
Mset
{
m
:=
make
(
map
[
interface
{}]
int
)
mset
:=
Mset
{
&
m
}
dict
:=
dicts
.
MakeDict
(
)
mset
:=
Mset
{
&
dict
}
for
_
,
elt
:=
range
values
{
if
count
,
found
:=
(
*
mset
.
data
)[
elt
];
found
{
(
*
mset
.
data
)[
elt
]
=
count
+
1
}
else
{
(
*
mset
.
data
)[
elt
]
=
1
}
h
:=
i2h
(
elt
)
count
:=
(
*
mset
.
d
.
Fetch
(
h
,
uint64
(
0
)))
.
(
uint64
)
mset
.
d
.
Set
(
h
,
count
+
1
)
}
return
mset
}
func
(
self
Mset
)
Eq
(
other
Mset
)
bool
{
if
len
(
*
self
.
data
)
!=
len
(
*
other
.
data
)
{
if
self
.
d
.
Len
()
!=
other
.
d
.
Len
(
)
{
return
false
}
for
key
,
left
:=
range
*
self
.
data
{
if
right
,
found
:=
(
*
other
.
data
)[
key
];
found
{
if
left
!=
right
{
return
false
}
}
else
{
for
iter
,
item
:=
self
.
d
.
Iter
();
item
!=
nil
;
item
=
iter
.
Next
()
{
if
!
other
.
d
.
Has
(
*
(
item
.
Key
))
{
return
false
}
else
if
(
*
item
.
Value
)
.
(
uint64
)
!=
(
*
other
.
d
.
Get
(
*
(
item
.
Key
)))
.
(
uint64
)
{
return
false
}
}
...
...
@@ -65,18 +86,18 @@ func (self Mset) Eq (other Mset) bool {
func
(
self
Mset
)
Copy
()
Mset
{
copy
:=
MakeMset
()
for
key
,
value
:=
range
*
self
.
data
{
(
*
copy
.
data
)[
key
]
=
value
for
iter
,
item
:=
self
.
d
.
Iter
();
item
!=
nil
;
item
=
iter
.
Next
()
{
copy
.
d
.
Set
(
*
(
item
.
Key
),
*
(
item
.
Value
))
}
return
copy
}
//+++ snk.MakeMset(1, 2, 2, 3, 3, 3).Copy().Eq(snk.MakeMset(1, 2, 2, 3, 3, 3))
func
(
self
Mset
)
Len
()
int
{
count
:=
0
for
_
,
value
:=
range
*
self
.
data
{
count
+=
value
func
(
self
Mset
)
Len
()
uint64
{
count
:=
uint64
(
0
)
for
iter
,
item
:=
self
.
d
.
Iter
();
item
!=
nil
;
item
=
iter
.
Next
()
{
count
+=
(
*
(
item
.
Value
))
.
(
uint64
)
}
return
count
}
...
...
@@ -85,12 +106,9 @@ func (self Mset) Len () int {
//+++ snk.MakeMset().Len() == 0
func
(
self
Mset
)
Add
(
other
Mset
)
Mset
{
for
key
,
value
:=
range
*
other
.
data
{
if
count
,
found
:=
(
*
self
.
data
)[
key
]
;
found
{
(
*
self
.
data
)[
key
]
=
value
+
count
}
else
{
(
*
self
.
data
)[
key
]
=
value
}
for
iter
,
item
:=
other
.
d
.
Iter
();
item
!=
nil
;
item
=
iter
.
Next
()
{
count
:=
(
*
(
self
.
d
.
Fetch
(
*
(
item
.
Key
),
uint64
(
0
))))
.
(
uint64
)
self
.
d
.
Set
(
*
(
item
.
Key
),
count
+
(
*
(
item
.
Value
))
.
(
uint64
))
}
return
self
}
...
...
@@ -102,13 +120,13 @@ func (self Mset) Add (other Mset) Mset {
//=== true
func
(
self
Mset
)
Sub
(
other
Mset
)
Mset
{
for
key
,
value
:=
range
*
other
.
data
{
if
count
,
found
:=
(
*
self
.
data
)[
key
]
;
found
{
if
count
>
value
{
(
*
self
.
data
)[
key
]
=
count
-
value
}
else
{
delete
(
*
self
.
data
,
key
)
}
for
iter
,
item
:=
other
.
d
.
Iter
();
item
!=
nil
;
item
=
iter
.
Next
()
{
left
:=
(
*
(
self
.
d
.
Fetch
(
*
(
item
.
Key
),
uint64
(
0
))))
.
(
uint64
)
right
:=
(
*
(
item
.
Value
))
.
(
uint64
)
if
left
<=
right
{
self
.
d
.
Del
(
*
(
item
.
Key
))
}
else
{
self
.
d
.
Set
(
*
(
item
.
Key
),
left
-
right
)
}
}
return
self
...
...
@@ -127,12 +145,9 @@ func (self Mset) Sub (other Mset) Mset {
//=== true
func
(
self
Mset
)
Geq
(
other
Mset
)
bool
{
for
key
,
value
:=
range
*
other
.
data
{
if
count
,
found
:=
(
*
self
.
data
)[
key
]
;
found
{
if
count
<
value
{
return
false
}
}
else
{
for
iter
,
item
:=
other
.
d
.
Iter
();
item
!=
nil
;
item
=
iter
.
Next
()
{
count
:=
(
*
(
self
.
d
.
Fetch
(
*
(
item
.
Key
),
uint64
(
0
))))
.
(
uint64
)
if
count
<
(
*
item
.
Value
)
.
(
uint64
)
{
return
false
}
}
...
...
@@ -149,19 +164,15 @@ func (self Mset) Geq (other Mset) bool {
//--- snk.MakeMset().Geq(snk.MakeMset(1))
func
(
self
Mset
)
Empty
()
bool
{
return
len
(
*
self
.
data
)
==
0
return
self
.
d
.
Len
(
)
==
0
}
//+++ snk.MakeMset().Empty()
//+++ snk.MakeMset().Empty()
//--- snk.MakeMset(1, 2).Empty()
func
(
self
Mset
)
Count
(
value
interface
{})
int
{
if
count
,
found
:=
(
*
self
.
data
)[
value
]
;
found
{
return
count
}
else
{
return
0
}
func
(
self
Mset
)
Count
(
value
interface
{})
uint64
{
return
(
*
(
self
.
d
.
Fetch
(
i2h
(
value
),
uint64
(
0
))))
.
(
uint64
)
}
//### snk.MakeMset(1, 2, 2, 3, 3, 3).Count(1)
...
...
@@ -174,62 +185,42 @@ func (self Mset) Count (value interface{}) int {
//=== 3
type
MsetIterator
struct
{
done
bool
ask
chan
bool
rep
chan
interface
{}
iter
dicts
.
DictIterator
dup
bool
count
uint64
current
*
dicts
.
Item
}
func
(
self
MsetIterator
)
Next
()
interface
{}
{
var
rep
interface
{}
if
self
.
done
{
func
(
self
*
MsetIterator
)
Next
()
*
interface
{}
{
if
self
.
current
==
nil
{
return
nil
}
self
.
ask
<-
true
rep
=
<-
self
.
rep
if
rep
==
nil
{
self
.
done
=
true
}
return
rep
}
func
(
self
MsetIterator
)
Stop
()
{
if
!
self
.
done
{
self
.
ask
<-
false
self
.
done
=
true
}
}
func
(
self
Mset
)
iterate
(
it
MsetIterator
,
dup
bool
)
{
for
key
,
num
:=
range
*
self
.
data
{
if
!
dup
{
num
=
1
}
for
i
:=
0
;
i
<
num
;
i
++
{
if
it
.
done
{
return
}
if
<-
it
.
ask
{
it
.
rep
<-
key
}
else
{
return
}
}
else
if
self
.
count
==
0
{
self
.
current
=
self
.
iter
.
Next
()
if
self
.
current
==
nil
{
return
nil
}
else
if
self
.
dup
{
self
.
count
=
(
*
(
self
.
current
.
Value
))
.
(
uint64
)
-
1
}
}
else
if
self
.
dup
{
self
.
count
--
}
if
<-
it
.
ask
{
it
.
rep
<-
nil
}
return
h2i
(
self
.
current
.
Key
)
}
func
(
self
Mset
)
Iter
()
(
MsetIterator
,
interface
{})
{
it
:=
MsetIterator
{
false
,
make
(
chan
bool
),
make
(
chan
interface
{})}
go
self
.
iterate
(
it
,
false
)
return
it
,
it
.
Next
()
func
(
self
Mset
)
Iter
()
(
MsetIterator
,
*
interface
{})
{
iter
,
item
:=
self
.
d
.
Iter
()
myiter
:=
MsetIterator
{
iter
,
false
,
0
,
item
}
if
item
==
nil
{
return
myiter
,
nil
}
else
{
return
myiter
,
h2i
(
item
.
Key
)
}
}
func
(
self
Mset
)
IterDup
()
(
MsetIterator
,
interface
{})
{
it
:=
MsetIterator
{
false
,
make
(
chan
bool
),
make
(
chan
interface
{})}
go
self
.
iterate
(
it
,
true
)
return
it
,
it
.
Next
(
)
func
(
self
Mset
)
IterDup
()
(
MsetIterator
,
*
interface
{})
{
it
er
,
item
:=
self
.
d
.
Iter
()
myiter
:=
MsetIterator
{
iter
,
true
,
(
*
(
item
.
Value
))
.
(
uint64
)
-
1
,
item
}
return
myiter
,
h2i
(
item
.
Key
)
}
//### a := snk.MakeMset(1, 2, 2, 3, 3, 3)
...
...
@@ -246,15 +237,14 @@ func (self Mset) IterDup () (MsetIterator, interface{}) {
func
(
self
Mset
)
String
()
string
{
buf
:=
bytes
.
NewBufferString
(
"["
)
count
:=
0
for
key
,
value
:=
range
*
self
.
data
{
for
i
:=
0
;
i
<
value
;
i
+=
1
{
if
count
>
0
{
buf
.
WriteString
(
", "
)
}
buf
.
WriteString
(
fmt
.
Sprint
(
key
))
count
+=
1
comma
:=
false
for
iter
,
val
:=
self
.
IterDup
();
val
!=
nil
;
val
=
iter
.
Next
()
{
if
comma
{
buf
.
WriteString
(
", "
)
}
else
{
comma
=
true
}
buf
.
WriteString
(
fmt
.
Sprint
(
*
val
))
}
buf
.
WriteString
(
"]"
)
return
buf
.
String
()
...
...
@@ -268,18 +258,24 @@ func (self Mset) String () string {
//... a
//>>> list(sorted(eval(out))) == [1, 2, 2, 3, 3, 3]
type
mapfunc
func
(
interface
{},
int
)
(
interface
{},
int
)
type
mapfunc
func
(
interface
{},
uint64
)
(
interface
{},
uint64
)
func
(
self
Mset
)
Map
(
f
mapfunc
)
Mset
{
copy
:=
MakeMset
()
for
k0
,
n0
:=
range
*
self
.
data
{
k1
,
n1
:=
f
(
k0
,
n0
)
(
*
copy
.
data
)[
k1
]
=
n1
for
iter
,
item
:=
self
.
d
.
Iter
();
item
!=
nil
;
item
=
iter
.
Next
()
{
k
:=
*
h2i
(
item
.
Key
)
v
:=
(
*
(
item
.
Value
))
.
(
uint64
)
k
,
v
=
f
(
k
,
v
)
copy
.
d
.
Set
(
i2h
(
k
),
v
)
}
return
copy
}
//### a := snk.MakeMset(1, 2, 2)
//... b := a.Map(func (v interface{}, n
int) (interface{}, int
) {return v.(int)+1, n})
//... b := a.Map(func (v interface{}, n
uint64) (interface{}, uint64
) {return v.(int)+1, n})
//... b.Eq(snk.MakeMset(2, 3, 3))
//=== true
func
(
self
Mset
)
ShowStructure
()
{
self
.
d
.
ShowStructure
()
}
...
...
libs/go/src/snk/sets.go
View file @
2afb056
...
...
@@ -28,17 +28,17 @@ func (self Set) NotEmpty () bool {
}
//+++ snk.MakeSet().Empty()
//--- snk.MakeSet(
snk.MakeMarking()
).Empty()
//--- snk.MakeSet(
&a
).Empty()
//--- snk.MakeSet().NotEmpty()
//+++ snk.MakeSet(
snk.MakeMarking()
).NotEmpty()
//+++ snk.MakeSet(
&a
).NotEmpty()
func
(
self
Set
)
Len
()
int
{
return
len
(
self
.
data
)
}
//+++ snk.MakeSet().Len() == 0
//+++ snk.MakeSet(
snk.MakeMarking()
).Len() == 1
//+++ snk.MakeSet(
snk.MakeMarking(), snk.MakeMarking()
).Len() == 1
//+++ snk.MakeSet(
&a
).Len() == 1
//+++ snk.MakeSet(
&a, &a
).Len() == 1
func
(
self
Set
)
lookup
(
m
*
Marking
)
(
uint64
,
bool
)
{
slot
:=
m
.
Hash
()
...
...
@@ -66,12 +66,13 @@ func (self *Set) AddPtr (m *Marking) {
}
}
//### s := snk.MakeSet(
a,
b)
//### s := snk.MakeSet(
&a, &
b)
//... s.Len()
//=== 2
//### s := snk.MakeSet(a, b)
//... s.Add(c).Add(c)
//### s := snk.MakeSet(&a, &b)
//... s.Add(c)
//... s.Add(c)
//... s.Len()
//=== 3
...
...
@@ -88,6 +89,6 @@ func (self Set) Has (m *Marking) bool {
return
found
}
//+++ snk.MakeSet(
a, b).Has(
a)
//+++ snk.MakeSet(
a, b).Has(
b)
//--- snk.MakeSet(
a, b).Has(
c)
//+++ snk.MakeSet(
&a, &b).Has(&
a)
//+++ snk.MakeSet(
&a, &b).Has(&
b)
//--- snk.MakeSet(
&a, &b).Has(&
c)
...
...
snakes/compil/go/codegen.py
View file @
2afb056
...
...
@@ -144,10 +144,10 @@ class CodeGenerator (ast.CodeGenerator) :
pvar
=
node
.
CTX
.
names
.
fresh
(
base
=
"p"
+
node
.
variable
)
ivar
=
node
.
CTX
.
names
.
fresh
(
base
=
"i"
+
node
.
variable
)
self
.
fill
(
"
%
s := true"
%
bvar
)
self
.
fill
(
"for
%
s,
%
s :=
%
s.
Iter(
%
s
);
%
s != nil;
%
s =
%
s.Next() {"
self
.
fill
(
"for
%
s,
%
s :=
%
s.
Get(
%
s).Iter(
);
%
s != nil;
%
s =
%
s.Next() {"
%
(
ivar
,
pvar
,
node
.
marking
,
S
(
node
.
place
.
name
),
pvar
,
pvar
,
ivar
))
with
self
.
indent
()
:
self
.
fill
(
"
%
s =
%
s
.(
%
s)"
self
.
fill
(
"
%
s =
(*
%
s)
.(
%
s)"
%
(
node
.
variable
,
pvar
,
self
.
typedef
[
node
.
place
.
type
]))
self
.
fill
(
"if "
)
self
.
visit
(
node
.
guard
)
...
...
@@ -165,10 +165,10 @@ class CodeGenerator (ast.CodeGenerator) :
def
visit_ForeachToken
(
self
,
node
)
:
ivar
=
node
.
NAMES
.
fresh
(
base
=
"i"
+
node
.
variable
)
pvar
=
node
.
NAMES
.
fresh
(
base
=
"p"
+
node
.
variable
)
self
.
fill
(
"for
%
s,
%
s :=
%
s.
Iter(
%
s
);
%
s != nil;
%
s =
%
s.Next() {"
self
.
fill
(
"for
%
s,
%
s :=
%
s.
Get(
%
s).Iter(
);
%
s != nil;
%
s =
%
s.Next() {"
%
(
ivar
,
pvar
,
node
.
marking
,
S
(
node
.
place
.
name
),
pvar
,
pvar
,
ivar
))
with
self
.
indent
()
:
self
.
fill
(
"
%
s =
%
s
.(
%
s)"
self
.
fill
(
"
%
s =
(*
%
s)
.(
%
s)"
%
(
node
.
variable
,
pvar
,
self
.
typedef
[
node
.
place
.
type
]))
self
.
children_visit
(
node
.
body
,
True
)
self
.
fill
(
"}"
)
...
...
@@ -190,7 +190,7 @@ class CodeGenerator (ast.CodeGenerator) :
self
.
fill
(
"for
%
s,
%
s :=
%
s.Iter();
%
s != nil;
%
s =
%
s.Next() {"
%
(
ivar
,
pvar
,
node
.
variable
,
pvar
,
pvar
,
ivar
))
with
self
.
indent
()
:
self
.
fill
(
"_,
%
s =
%
s
.(
%
s)"
self
.
fill
(
"_,
%
s =
(*
%
s)
.(
%
s)"
%
(
bvar
,
pvar
,
self
.
typedef
[
node
.
place
.
type
]))
self
.
fill
(
"if !
%
s { break }"
%
bvar
)
self
.
fill
(
"}"
)
...
...
snakes/compil/python/codegen.py
View file @
2afb056
...
...
@@ -75,7 +75,7 @@ def main () :
args
=
parser
.
parse_args
()
if
args
.
mode
in
"gml"
and
args
.
size
:
n
,
_
=
statespace
(
False
,
False
,
False
)
print
(
"
%
s reachable states"
)
print
(
"
%
s reachable states"
%
n
)
elif
args
.
mode
==
"d"
and
args
.
size
:
_
,
n
=
statespace
(
False
,
False
,
False
)
print
(
"
%
s deadlocks"
)
...
...
test/gotest.py
View file @
2afb056
import
os
,
os.path
import
os
,
os.path
,
subprocess
def
walk
(
root
=
'libs/go/src/snk'
)
:
for
dirpath
,
dirnames
,
filenames
in
os
.
walk
(
root
)
:
...
...
@@ -16,7 +16,6 @@ class Test (object) :
self
.
expected
=
list
(
expected
)
self
.
pychecks
=
[]
def
codegen
(
self
,
outfile
,
indent
=
" "
)
:
outfile
.
write
(
' //
%
s:
%
s
\n
'
%
(
self
.
path
,
self
.
lineno
))
if
self
.
path
in
self
.
idx
:
outfile
.
write
(
' '
+
'
\n
'
.
join
(
self
.
idx
[
self
.
path
])
+
'
\n
'
)
outfile
.
write
(
' fmt.Println("###
%
s:
%
s")
\n
'
%
(
self
.
path
,
self
.
lineno
))
...
...
@@ -27,7 +26,7 @@ class Test (object) :
if
self
.
source
[
-
1
]
==
"nil"
and
output
[
-
1
]
==
"<nil>"
:
output
.
pop
(
-
1
)
if
self
.
expected
and
self
.
expected
!=
output
:
print
(
"####
%
s:
%
s"
%
(
self
.
path
,
self
.
lineno
))
print
(
"
\n
####
%
s:
%
s"
%
(
self
.
path
,
self
.
lineno
))
print
(
"
\n
"
.
join
(
self
.
source
))
print
(
"## expected:"
)
print
(
"
\n
"
.
join
(
self
.
expected
))
...
...
@@ -48,7 +47,7 @@ class Test (object) :
res
=
"raised
%
s:
%
s"
%
(
err
.
__class__
.
__name__
,
err
)
if
res
is
not
True
:
ret
=
1
print
(
"####
%
s:
%
s"
%
(
self
.
path
,
self
.
lineno
))
print
(
"
\n
####
%
s:
%
s"
%
(
self
.
path
,
self
.
lineno
))
print
(
"
\n
"
.
join
(
self
.
source
))
if
res
is
False
:
print
(
"## failed"
)
...
...
@@ -62,6 +61,7 @@ def extract (root, path) :
package
=
None
imports
=
set
()
tests
=
[]
declare
=
[]
for
num
,
line
in
enumerate
(
open
(
os
.
path
.
join
(
root
,
path
)))
:
if
line
.
startswith
(
'package '
)
:
package
=
line
.
split
()[
-
1
]
...
...
@@ -83,10 +83,12 @@ def extract (root, path) :
Test
.
idx
[
path
]
.
append
(
line
[
6
:]
.
rstrip
())
elif
line
.
startswith
(
"//$$$ "
)
:
imports
.
update
(
line
[
6
:]
.
strip
()
.
split
())
elif
line
.
startswith
(
"//
%%%
"
)
:
declare
.
append
(
line
[
6
:]
.
rstrip
())
print
(
"+
%
s (
%
s) =
%
s tests"
%
(
path
,
package
,
len
(
tests
)))
return
package
,
imports
,
tests
return
package
,
declare
,
imports
,
tests
def
codegen
(
packages
,
imports
,
tests
,
out
)
:
def
codegen
(
packages
,
declare
,
imports
,
tests
,
out
)
:
funcs
=
[]
out
.
write
(
'package main
\n\n
import "fmt"
\n
'
)
for
p
in
packages
:
...
...
@@ -94,6 +96,9 @@ def codegen (packages, imports, tests, out) :
for
p
in
imports
-
packages
:
out
.
write
(
'import "
%
s"
\n
'
%
p
)
out
.
write
(
"
\n
"
)
for
d
in
declare
:
out
.
write
(
"
%
s
\n
"
%
d
)
out
.
write
(
"
\n
"
)
for
i
,
t
in
enumerate
(
tests
)
:
name
=
"test
%03
u"
%
i
funcs
.
append
(
name
)
...
...
@@ -105,12 +110,37 @@ def codegen (packages, imports, tests, out) :
out
.
write
(
"
%
s()
\n
"
%
name
)
out
.
write
(
'}'
)
def
getlmap
(
path
)
:
m
=
{}
loc
=
None
for
n
,
l
in
enumerate
(
open
(
path
))
:
if
l
.
strip
()
.
startswith
(
'fmt.Println("### '
)
:
loc
=
l
.
split
(
"### "
)[
-
1
]
.
split
(
'"'
)[
0
]
elif
loc
is
None
:
m
[
n
]
=
"
%
s:
%
s"
%
(
path
,
n
+
1
)
else
:
m
[
n
]
=
loc
return
m
def
run
(
gopath
,
binpath
=
None
,
outpath
=
None
)
:
if
binpath
is
None
:
binpath
=
os
.
path
.
splitext
(
gopath
)[
0
]
if
outpath
is
None
:
outpath
=
binpath
+
".out"
if
os
.
system
(
"go build
%
s"
%
gopath
)
!=
0
:
try
:
subprocess
.
check_output
([
"go"
,
"build"
,
gopath
],
stderr
=
subprocess
.
STDOUT
)
except
subprocess
.
CalledProcessError
as
err
:
tr
=
getlmap
(
gopath
)
out
=
err
.
output
.
decode
()
for
line
in
out
.
splitlines
()
:
try
:
path
,
lineno
,
message
=
line
.
split
(
":"
,
2
)
if
path
.
endswith
(
gopath
)
:
print
(
"
%
s:
%
s"
%
(
tr
[
int
(
lineno
)],
message
))
else
:
print
(
line
)
except
ValueError
:
print
(
line
)
sys
.
exit
()
if
os
.
system
(
"
%
s >
%
s"
%
(
os
.
path
.
join
(
"./"
,
binpath
),
outpath
))
!=
0
:
sys
.
exit
()
...
...
@@ -142,14 +172,17 @@ if __name__ == "__main__" :
sys
.
exit
(
1
)
if
not
gofile
.
endswith
(
".go"
)
:
gofile
+=
".go"
packages
,
imports
,
tests
=
set
()
,
set
(),
[]
packages
,
declare
,
imports
,
tests
=
set
(),
[]
,
set
(),
[]
for
path
in
walk
(
root
)
:
p
,
i
,
t
=
extract
(
root
,
path
)
p
,
d
,
i
,
t
=
extract
(
root
,
path
)
packages
.
add
(
p
)
declare
.
extend
(
d
)
imports
.
update
(
i
)
tests
.
extend
(
t
)
codegen
(
packages
,
imports
,
tests
,
open
(
gofile
,
"w"
))
codegen
(
packages
,
declare
,
imports
,
tests
,
open
(
gofile
,
"w"
))
print
(
"=
%
s tests"
%
len
(
tests
))
output
=
run
(
gofile
)
failed
=
check
(
tests
,
output
)
if
failed
:
print
()
print
(
"=
%
s tests failed (out of
%
s)"
%
(
failed
,
len
(
tests
)))
...
...
test/testall-go.snk
View file @
2afb056
...
...
@@ -23,7 +23,7 @@ func max (init int, values ...int) int {
return m
}
func inc (v interface{}, n
int) (interface{}, int
) {
func inc (v interface{}, n
uint64) (interface{}, uint64
) {
return v.(int)+1, n
}
...
...
Please
register
or
login
to post a comment