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-22 15:29:11 +0100
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
ee353c75b90c6b70ce49d4962962ae8435105f79
ee353c75
1 parent
13e423bd
started net compilation API
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
134 additions
and
56 deletions
snakes/compil/__init__.py
snakes/compil/__main__.py
snakes/compil/ast.py
snakes/compil/go/__init__.py
snakes/compil/python/__init__.py
snakes/nets.py
test/simple-python.snk
snakes/compil/__init__.py
View file @
ee353c7
import
importlib
,
string
,
collections
import
importlib
,
string
,
collections
,
io
,
tempfile
,
os
,
os.path
from
snakes
import
LanguageError
...
...
@@ -11,6 +11,44 @@ def getlang (name) :
module
.
name
=
name
return
module
def
build
(
lang
,
tree
,
saveto
)
:
if
saveto
is
None
:
out
=
io
.
StringIO
()
elif
isinstance
(
saveto
,
str
)
:
out
=
open
(
str
,
"w+"
)
else
:
try
:
saveto
.
write
(
"hello world!"
)
saveto
.
seek
(
0
)
if
saveto
.
read
(
12
)
!=
"hello world!"
:
raise
IOError
()
saveto
.
seek
(
0
)
saveto
.
truncate
()
saveto
.
flush
()
if
not
os
.
path
.
exists
(
saveto
.
name
)
:
raise
IOError
()
except
:
raise
ValueError
(
"
%
r object does not have expected file-like feature"
%
saveto
.
__class__
.
__name__
)
out
=
saveto
gen
=
lang
.
codegen
.
CodeGenerator
(
out
)
gen
.
visit
(
tree
)
out
.
flush
()
out
.
seek
(
0
)
if
lang
.
INMEM
:
mod
=
lang
.
build
(
tree
,
out
,
tree
.
name
+
lang
.
EXT
)
elif
saveto
is
None
:
try
:
tmp
=
tempfile
.
NamedTemporaryFile
(
mode
=
"w+"
,
suffix
=
lang
.
EXT
,
delete
=
False
)
tmp
.
write
(
out
.
read
())
tmp
.
close
()
mod
=
lang
.
build
(
tree
,
tmp
.
name
,
tree
.
name
+
lang
.
EXT
)
finally
:
os
.
unlink
(
tmp
.
name
)
else
:
mod
=
lang
.
build
(
tree
,
out
.
name
,
os
.
path
.
basename
(
out
.
name
))
mod
.
ast
=
tree
class
BaseDeclare
(
object
)
:
_levels
=
[
None
]
_default
=
None
...
...
@@ -34,9 +72,27 @@ class BaseDeclare (object) :
return
new
class
CompilationError
(
Exception
)
:
def
__init__
(
self
,
msg
,
blame
)
:
Exception
.
__init__
(
self
,
msg
)
self
.
blame
=
blame
def
__init__
(
self
,
ast
,
path
,
msg
,
loc
=
None
,
details
=
None
)
:
if
loc
is
None
:
short
=
"
%
s:
%
s"
%
(
path
,
msg
.
strip
())
self
.
blame
=
None
elif
not
isinstance
(
loc
,
tuple
)
:
short
=
"
%
s[
%
s]:
%
s"
%
(
path
,
loc
,
msg
.
strip
())
self
.
blame
=
ast
.
blame
(
int
(
loc
)
-
1
,
0
)
else
:
short
=
"
%
s[
%
s:
%
s]:
%
s"
%
(
path
,
loc
[
0
]
-
1
,
loc
[
1
],
msg
.
strip
())
self
.
blame
=
ast
.
blame
(
*
loc
)
Exception
.
__init__
(
self
,
short
)
self
.
ast
=
ast
self
.
path
=
path
self
.
loc
=
loc
self
.
details
=
details
def
message
(
self
)
:
msg
=
[
"[ERROR]
%
s"
%
self
]
if
self
.
blame
is
not
None
:
msg
.
append
(
"[BLAME]
%
s"
%
self
.
blame
)
msg
.
append
(
self
.
details
)
return
"
\n
"
.
join
(
msg
)
class
Context
(
object
)
:
def
__init__
(
self
,
**
attrs
)
:
...
...
snakes/compil/__main__.py
0 → 100644
View file @
ee353c7
import
snakes.io.snk
,
sys
from
.
import
build
,
CompilationError
net
=
snakes
.
io
.
snk
.
load
(
open
(
sys
.
argv
[
-
1
]))
ast
=
net
.
__ast__
()
try
:
build
(
net
.
lang
,
ast
,
None
)
except
CompilationError
as
err
:
print
(
err
.
message
())
snakes/compil/ast.py
View file @
ee353c7
...
...
@@ -163,17 +163,14 @@ class AST (_Record) :
found
.
extend
(
sub
.
locate
(
line
,
column
))
return
found
def
locate
(
self
,
line
,
column
)
:
if
not
hasattr
(
self
,
"loc"
)
:
raise
ValueError
(
"AST has no locations"
)
elif
self
.
loc
is
None
:
return
[]
(
l0
,
c0
),
(
l1
,
c1
)
=
self
.
loc
if
((
l0
==
line
==
l1
and
c0
<=
column
<
c1
)
or
(
l0
==
line
<
l1
and
c0
<=
column
)
or
(
l0
<
line
==
l1
and
column
<=
c1
)
or
(
l0
<
line
<
l1
))
:
return
[
self
]
+
self
.
_locate_children
(
line
,
column
)
return
[]
if
hasattr
(
self
,
"loc"
)
and
self
.
loc
is
not
None
:
(
l0
,
c0
),
(
l1
,
c1
)
=
self
.
loc
if
((
l0
==
line
==
l1
and
c0
<=
column
<
c1
)
or
(
l0
==
line
<
l1
and
c0
<=
column
)
or
(
l0
<
line
==
l1
and
column
<=
c1
)
or
(
l0
<
line
<
l1
))
:
return
[
self
]
+
self
.
_locate_children
(
line
,
column
)
return
self
.
_locate_children
(
line
,
column
)
def
blame
(
self
,
line
,
column
)
:
for
node
in
reversed
(
self
.
locate
(
line
,
column
))
:
if
hasattr
(
node
,
"BLAME"
)
:
...
...
@@ -414,8 +411,10 @@ class CodeGenerator (object) :
node
.
body
=
[]
for
lvl
,
line
in
node
.
decl
:
node
.
body
.
append
(
ContextLine
(
line
,
BLAME
=
ContextBlame
(
line
)))
self
.
fill
(
line
)
self
.
children_visit
(
node
.
body
)
self
.
fill
()
def
visit_ContextLine
(
self
,
node
)
:
self
.
fill
(
node
.
code
)
def
visit_SuccProcName
(
self
,
node
)
:
if
not
node
.
trans
:
name
=
"addsucc"
...
...
snakes/compil/go/__init__.py
View file @
ee353c7
from
snakes.compil
import
BaseDeclare
import
subprocess
,
os.path
,
os
,
inspect
import
snakes
from
snakes.compil
import
BaseDeclare
,
CompilationError
from
snakes.compil.go.rename
import
rename
from
.
import
codegen
NONETYPE
=
False
BOOL
=
"bool"
EXT
=
".go"
INMEM
=
False
class
Declare
(
BaseDeclare
)
:
_levels
=
[
"import"
,
"decl"
]
_default
=
"decl"
def
ast2code
(
tree
,
output
=
None
)
:
pass
class
GoModule
(
object
)
:
def
__init__
(
self
,
srcpath
)
:
self
.
path
=
os
.
path
.
splitext
(
srcpath
)[
0
]
def
load
(
tree
,
name
=
"net"
)
:
pass
def
update_gopath
()
:
# TODO: fix this wrt installation path
path
=
os
.
path
.
join
(
os
.
path
.
dirname
(
os
.
path
.
dirname
(
inspect
.
getfile
(
snakes
))),
"libs"
,
"go"
)
if
"GOPATH"
not
in
os
.
environ
:
os
.
environ
[
"GOPATH"
]
=
path
elif
path
not
in
os
.
environ
[
"GOPATH"
]
.
split
(
":"
)
:
os
.
environ
[
"GOPATH"
]
=
":"
.
join
([
path
,
os
.
environ
[
"GOPATH"
]])
def
build
(
ast
,
src
,
name
)
:
update_gopath
()
try
:
subprocess
.
check_output
([
"go"
,
"build"
,
src
],
stderr
=
subprocess
.
STDOUT
)
except
Exception
as
err
:
out
=
err
.
output
.
decode
()
for
line
in
out
.
splitlines
()
:
try
:
path
,
lineno
,
message
=
line
.
split
(
":"
,
2
)
if
path
.
endswith
(
src
)
:
raise
CompilationError
(
ast
,
name
,
message
.
strip
(),
int
(
lineno
),
out
)
except
ValueError
:
continue
raise
CompilationError
(
ast
,
name
,
out
)
return
GoModule
(
src
)
...
...
snakes/compil/python/__init__.py
View file @
ee353c7
import
io
,
types
,
traceback
,
sys
from
.
import
codegen
as
_codegen
import
types
,
traceback
,
sys
,
importlib
from
snakes.compil
import
CompilationError
,
BaseDeclare
from
snakes.compil.python.rename
import
rename
from
.
import
codegen
as
codegen
from
.rename
import
rename
NONETYPE
=
True
BOOL
=
"bool"
EXT
=
".py"
INMEM
=
True
class
Declare
(
BaseDeclare
)
:
pass
def
ast2code
(
tree
,
output
=
None
)
:
if
output
is
None
:
out
=
io
.
StringIO
()
elif
isinstance
(
output
,
str
)
:
out
=
open
(
output
)
else
:
out
=
output
gen
=
_codegen
.
CodeGenerator
(
out
)
gen
.
visit
(
tree
)
if
output
is
None
:
return
gen
def
load
(
tree
,
name
=
"net"
)
:
gen
=
ast2code
(
tree
)
def
build
(
ast
,
src
,
name
)
:
if
isinstance
(
src
,
str
)
:
src
=
open
(
src
)
ctx
=
{}
try
:
exec
(
gen
.
output
.
getvalue
(),
ctx
)
spec
=
importlib
.
util
.
spec_from_file_location
(
module_name
,
file_path
)
mod
=
importlib
.
util
.
module_from_spec
(
spec
)
spec
.
loader
.
exec_module
(
mod
)
except
Exception
as
err
:
c
,
v
,
t
=
sys
.
exc_info
()
msg
=
traceback
.
format_exception_only
(
c
,
v
)
msg
.
insert
(
0
,
"[ERROR] "
+
msg
.
pop
(
-
1
))
if
hasattr
(
err
,
"lineno"
)
and
hasattr
(
err
,
"offset"
)
:
l
ine
,
column
=
err
.
lineno
-
1
,
err
.
offset
-
1
l
oc
=
(
err
.
lineno
-
1
,
err
.
offset
-
1
)
else
:
tb
=
t
while
tb
.
tb_next
:
tb
=
tb
.
tb_next
line
,
column
=
tb
.
tb_lineno
,
0
blame
=
tree
.
blame
(
line
,
column
)
if
blame
:
raise
CompilationError
(
"
%
s[BLAME]
%
s"
%
(
""
.
join
(
msg
),
blame
),
blame
)
raise
CompilationError
(
""
.
join
(
msg
)
.
rstrip
(),
None
)
ctx
[
"__succfunc__"
]
=
gen
.
succfunc
ctx
[
"__succproc__"
]
=
gen
.
succproc
ctx
[
"__initfunc__"
]
=
gen
.
initfunc
mod
=
types
.
ModuleType
(
name
)
mod
.
__dict__
.
update
(
ctx
)
loc
=
tb
.
tb_lineno
raise
CompilationError
(
ast
,
name
,
msg
[
-
1
],
loc
,
""
.
join
(
msg
)
.
rstrip
())
return
mod
...
...
snakes/nets.py
View file @
ee353c7
...
...
@@ -5,7 +5,6 @@ from snakes.data import *
from
snakes.tokens
import
*
import
snakes.compil
from
snakes.compil
import
Context
class
PetriNet
(
object
)
:
def
__init__
(
self
,
name
,
lang
=
"python"
)
:
...
...
@@ -17,13 +16,15 @@ class PetriNet (object) :
self
.
_node
=
{}
def
__repr__
(
self
)
:
return
"
%
s(
%
r,
%
r)"
%
(
self
.
__class__
.
__name__
,
self
.
name
,
self
.
lang
.
name
)
def
build
(
self
,
name
=
"net"
,
saveto
=
None
)
:
return
snakes
.
compil
.
build
(
self
.
lang
,
self
.
__ast__
(
name
),
saveto
)
def
__ast__
(
self
,
name
=
"net"
)
:
ctx
=
Context
(
net
=
self
)
ctx
=
snakes
.
compil
.
Context
(
net
=
self
)
mod
=
ctx
.
Module
(
name
,
[
ctx
.
Context
(
self
.
declare
.
copy
()),
ctx
.
DefineMarking
(
list
(
self
.
_place
.
values
()))])
for
name
,
trans
in
sorted
(
self
.
_trans
.
items
())
:
mod
.
body
.
extend
(
trans
.
__ast__
(
Context
(
net
=
self
)))
mod
.
body
.
extend
(
trans
.
__ast__
(
snakes
.
compil
.
Context
(
net
=
self
)))
mod
.
body
.
append
(
ctx
.
DefSuccProc
(
ctx
.
SuccProcName
(),
"marking"
,
"succ"
,
[
ctx
.
CallSuccProc
(
ctx
.
SuccProcName
(
t
.
name
),
"marking"
,
"succ"
)
for
n
,
t
in
sorted
(
self
.
_trans
.
items
())]))
...
...
@@ -33,7 +34,7 @@ class PetriNet (object) :
ctx
.
ReturnSucc
(
"succ"
)]))
mod
.
body
.
append
(
ctx
.
DefSuccIter
(
ctx
.
SuccIterName
(),
"marking"
,
[
ctx
.
SuccIterName
(
t
.
name
)
for
n
,
t
in
sorted
(
self
.
_trans
.
items
())]))
marking
=
self
.
get_marking
()
.
__ast__
(
Context
(
net
=
self
))
marking
=
self
.
get_marking
()
.
__ast__
(
snakes
.
compil
.
Context
(
net
=
self
))
mod
.
body
.
extend
([
ctx
.
DefInitFunc
(
ctx
.
InitName
(),
marking
),
ctx
.
SuccProcTable
(),
ctx
.
SuccFuncTable
(),
...
...
test/simple-python.snk
View file @
ee353c7
...
...
@@ -5,7 +5,7 @@ MAX = 5
"""
net "my net" :
place p1 int = 0, 1, 2
place p1 int = 0, 1, 2
, FOO
place p2 int = 1, 2, 3
place p3 int = MAX
place p4
...
...
Please
register
or
login
to post a comment