Jordan de la Houssaye

started andy integration. cloned from abcd

1 +#!/usr/bin/env python
2 +import snakes.utils.andy.main as andymain
3 +andymain.main()
1 +"""This package features the ABCD compiler, this is mainly a
2 +command-line tool but it can be called also from Python. The API is
3 +very simple and mimics the command line interface
4 +
5 +### Function `snakes.utils.abcd.main.main` ###
6 +
7 + :::python
8 + def main (args=sys.argv[1:], src=None) : ...
9 +
10 +Entry point of the compiler
11 +
12 +##### Call API #####
13 +
14 + * `list args`:
15 + * `str src`:
16 + * `return PetriNet`:
17 +
18 +##### Exceptions #####
19 +
20 + * `DeclarationError`: when
21 + * `CompilationError`: when
22 +
23 +"""
24 +
25 +# apidoc stop
26 +from snakes import SnakesError
27 +
28 +class CompilationError (SnakesError) :
29 + pass
30 +
31 +class DeclarationError (SnakesError) :
32 + pass
This diff is collapsed. Click to expand it.
1 +import heapq
2 +from snakes.nets import StateGraph
3 +import snakes.lang
4 +import snkast as ast
5 +
6 +class Checker (object) :
7 + def __init__ (self, net) :
8 + self.g = StateGraph(net)
9 + self.f = [self.build(f) for f in net.label("asserts")]
10 + def build (self, tree) :
11 + src = """
12 +def check (_) :
13 + return %s
14 +""" % tree.st.source()[7:]
15 + ctx = dict(self.g.net.globals)
16 + ctx["bounded"] = self.bounded
17 + exec(src, ctx)
18 + fun = ctx["check"]
19 + fun.lineno = tree.lineno
20 + return fun
21 + def bounded (self, marking, max) :
22 + return all(len(marking(p)) == 1 for p in marking)
23 + def run (self) :
24 + for state in self.g :
25 + marking = self.g.net.get_marking()
26 + for place in marking :
27 + if max(marking(place).values()) > 1 :
28 + return None, self.trace(state)
29 + for check in self.f :
30 + try :
31 + if not check(marking) :
32 + return check.lineno, self.trace(state)
33 + except :
34 + pass
35 + return None, None
36 + def path (self, tgt, src=0) :
37 + q = [(0, src, ())]
38 + visited = set()
39 + while True :
40 + (c, v1, path) = heapq.heappop(q)
41 + if v1 not in visited :
42 + path = path + (v1,)
43 + if v1 == tgt :
44 + return path
45 + visited.add(v1)
46 + for v2 in self.g.successors(v1) :
47 + if v2 not in visited :
48 + heapq.heappush(q, (c+1, v2, path))
49 + def trace (self, state) :
50 + path = self.path(state)
51 + return tuple(self.g.successors(i)[j]
52 + for i, j in zip(path[:-1], path[1:]))
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
1 +<div class="about">
2 + <p><span class="title">ABCD simulator is part of the SNAKES
3 + toolkit</span><br/> (C) 2014 Franck Pommereau</p>
4 + <p><a href="http://www.ibisc.univ-evry.fr/~fpommereau/SNAKES"
5 + target="_blank">SNAKES homepage</a></p>
6 +</div>
1 +Well, you can tell by the way I use my walk,
2 +I'm a woman's man: no time to talk.
3 +Music loud and women warm, I've been kicked around
4 +Since I was born.
5 +And now it's all right. it's ok.
6 +And you may look the other way.
7 +We can try to understand
8 +The new york times effect on man.
9 +Whether you're a brother or whether you're a mother,
10 +You're stayin alive, stayin alive.
11 +Feel the city breakin and everybody shakin,
12 +And were stayin alive, stayin alive.
13 +Ah, ha, ha, ha, stayin alive, stayin alive.
14 +Ah, ha, ha, ha, stayin alive.
15 +Well now, I get low and I get high,
16 +And if I can't get either, I really try.
17 +Got the wings of heaven on my shoes.
18 +I'm a dancin man and I just can't lose.
19 +You know it's all right.its ok.
20 +I'll live to see another day.
21 +We can try to understand
22 +The new york times effect on man.
23 +Whether you're a brother or whether you're a mother,
24 +You're stayin alive, stayin alive.
25 +Feel the city breakin and everybody shakin,
26 +And were stayin alive, stayin alive.
27 +Ah, ha, ha, ha, stayin alive, stayin alive.
28 +Ah, ha, ha, ha, stayin alive.
29 +Life goin nowhere.somebody help me.
30 +Somebody help me, yeah.
31 +Life goin nowhere.somebody help me.
32 +Somebody help me, yeah. stayin alive.
33 +Well, you can tell by the way I use my walk,
34 +I'm a woman's man: no time to talk.
35 +Music loud and women warm,
36 +I've been kicked around since I was born.
37 +And now it's all right. it's ok.
38 +And you may look the other way.
39 +We can try to understand
40 +The new york times effect on man.
41 +Whether you're a brother or whether you're a mother,
42 +You're stayin alive, stayin alive.
43 +Feel the city breakin and everybody shakin,
44 +And were stayin alive, stayin alive.
45 +Ah, ha, ha, ha, stayin alive, stayin alive.
46 +Ah, ha, ha, ha, stayin alive.
47 +Life goin nowhere.somebody help me.
48 +Somebody help me, yeah.
49 +Life goin nowhere.somebody help me, yeah.
50 +I'm stayin alive.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
1 +<!DOCTYPE html>
2 +<html>
3 + <head>
4 + <link type="text/css" href="r/css/bootstrap-theme.css" rel="stylesheet"/>
5 + <link type="text/css" href="r/css/bootstrap.css" rel="stylesheet"/>
6 + <link type="text/css" href="r/css/docs.css" rel="stylesheet"/>
7 + <link type="text/css" href="r/simulator.css" rel="stylesheet"/>
8 + <link type="text/css" href="r/model.css" rel="stylesheet"/>
9 + <script src="r/jquery.min.js"></script>
10 + <script src="r/js/bootstrap.min.js"></script>
11 + <script src="r/jquery.periodic.js"></script>
12 + <script src="r/js/bootstrap.file-input.js"></script>
13 + <script src="r/d3.min.js"></script>
14 + <script src="r/js/petri.js"></script>
15 + <script src="r/simulator.js"></script>
16 + </head>
17 + <style>
18 + path {
19 + stroke: steelblue;
20 + stroke-width: 2;
21 + fill: none;
22 + }
23 +
24 + line {
25 + stroke: black;
26 + }
27 +
28 + text {
29 + font-family: Arial;
30 + font-size: 9pt;
31 + }
32 +
33 + </style>
34 + <body>
35 +
36 + <header class="navbar navbar-static-top">
37 + <div class="container">
38 + <nav class="navbar navbar-default" role="navigation">
39 + <div class="container-fluid">
40 + <div class="navbar-header"><button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-6"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Simulation SNAKES</a></div>
41 + <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-6">
42 + <ul id="nav_sim" class="nav navbar-nav">
43 + <li><a href="#" id="ui-reset">Reset Simulation</a></li>
44 + <li><a href="#" id="ui-quit">Stop Simulation</a></li>
45 + <li><a href="#" id="ui-help">Help</a></li>
46 + </ul>
47 + </div>
48 + </div>
49 + </nav>
50 + </div>
51 + </header>
52 + <div class="container">
53 +
54 + %(model)s
55 +
56 + <div class="modal fade" id="about" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
57 + <div class="modal-dialog">
58 + <div class="modal-content">
59 + <div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
60 + <h4 class="modal-title" id="myModalLabel">Petri Net</h4>
61 + </div>
62 + <div class="modal-body">
63 + <p><span class="title">ABCD simulator is part of the SNAKES toolkit</span><br /> (C) 2014 Franck Pommereau</p>
64 + <p><a href="http://www.ibisc.univ-evry.fr/~fpommereau/SNAKES" target="_blank">SNAKES homepage</a></p>
65 + </div>
66 + <div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">Close</button></div>
67 + </div>
68 + </div>
69 + </div>
70 +<script>
71 + $(document).ready(function(){
72 + $.simisc({
73 + "nav":{
74 + "about": {
75 + "text": "About",
76 + "attr": {
77 + "id":"ui-about",
78 + "data-toggle": "modal",
79 + "data-target": "#about"
80 + }
81 + },
82 + "net": {
83 + "text": "Petri Net",
84 + "attr": {
85 + "id":"ui-net",
86 + "data-toggle": "modal",
87 + "data-target": "#net"
88 + }
89 + }
90 + },
91 + "graph": {
92 + "activate": false
93 + }
94 + });
95 + });
96 +</script>
97 +</body>
98 +</html>
This diff could not be displayed because it is too large.
1 +/*!
2 + * jQuery periodic plugin
3 + *
4 + * Copyright 2010, Tom Anderson
5 + * Dual licensed under the MIT or GPL Version 2 licenses.
6 + *
7 + */
8 +
9 +$.periodic = function (options, callback) {
10 +
11 + // if the first argument is a function then assume the options aren't being passed
12 + if (jQuery.isFunction(options)) {
13 + callback = options;
14 + options = {};
15 + }
16 +
17 + // Merge passed settings with default values
18 + var settings = jQuery.extend({}, jQuery.periodic.defaults, {
19 + ajax_complete : ajaxComplete,
20 + increment : increment,
21 + reset : reset,
22 + cancel : cancel
23 + }, options);
24 +
25 + // bookkeeping variables
26 + settings.cur_period = settings.period;
27 + settings.tid = false;
28 + var prev_ajax_response = '';
29 +
30 + run();
31 +
32 + // return settings so user can tweak them externally
33 + return settings;
34 +
35 + // run (or restart if already running) the looping construct
36 + function run() {
37 + // clear/stop existing timer (multiple calls to run() won't result in multiple timers)
38 + cancel();
39 + // let it rip!
40 + settings.tid = setTimeout(function() {
41 + // set the context (this) for the callback to the settings object
42 + callback.call(settings);
43 +
44 + // compute the next value for cur_period
45 + increment();
46 +
47 + // queue up the next run
48 + if(settings.tid)
49 + run();
50 + }, settings.cur_period);
51 + }
52 +
53 + // utility function for use with ajax calls
54 + function ajaxComplete(xhr, status) {
55 + if (status === 'success' && prev_ajax_response !== xhr.responseText) {
56 + // reset the period whenever the response changes
57 + prev_ajax_response = xhr.responseText;
58 + reset();
59 + }
60 + }
61 +
62 + // compute the next delay
63 + function increment() {
64 + settings.cur_period *= settings.decay;
65 + if (settings.cur_period < settings.period) {
66 + // don't let it drop below the minimum
67 + reset();
68 + } else if (settings.cur_period > settings.max_period) {
69 + settings.cur_period = settings.max_period;
70 + if (settings.on_max !== undefined) {
71 + // call the user-supplied callback if we reach max_period
72 + settings.on_max.call(settings);
73 + }
74 + }
75 + }
76 +
77 + function reset() {
78 + settings.cur_period = settings.period;
79 + // restart with the new timeout
80 + run();
81 + }
82 +
83 + function cancel() {
84 + clearTimeout(settings.tid);
85 + settings.tid = null;
86 + }
87 +
88 + // other functions we might want to implement
89 + function pause() {}
90 + function resume() {}
91 + function log() {}
92 +};
93 +
94 +jQuery.periodic.defaults = {
95 + period : 4000, // 4 sec.
96 + max_period : 1800000, // 30 min.
97 + decay : 1.5, // time period multiplier
98 + on_max : undefined // called if max_period is reached
99 +};
...\ No newline at end of file ...\ No newline at end of file
1 +/*
2 + Bootstrap - File Input
3 + ======================
4 +
5 + This is meant to convert all file input tags into a set of elements that displays consistently in all browsers.
6 +
7 + Converts all
8 + <input type="file">
9 + into Bootstrap buttons
10 + <a class="btn">Browse</a>
11 +
12 +*/
13 +$(function() {
14 +
15 +$.fn.bootstrapFileInput = function() {
16 +
17 + this.each(function(i,elem){
18 +
19 + var $elem = $(elem);
20 +
21 + // Maybe some fields don't need to be standardized.
22 + if (typeof $elem.attr('data-bfi-disabled') != 'undefined') {
23 + return;
24 + }
25 +
26 + // Set the word to be displayed on the button
27 + var buttonWord = 'Browse';
28 +
29 + if (typeof $elem.attr('title') != 'undefined') {
30 + buttonWord = $elem.attr('title');
31 + }
32 +
33 + // Start by getting the HTML of the input element.
34 + // Thanks for the tip http://stackoverflow.com/a/1299069
35 + var input = $('<div>').append( $elem.eq(0).clone() ).html();
36 + var className = '';
37 +
38 + if (!!$elem.attr('class')) {
39 + className = ' ' + $elem.attr('class');
40 + }
41 +
42 + // Now we're going to replace that input field with a Bootstrap button.
43 + // The input will actually still be there, it will just be float above and transparent (done with the CSS).
44 + $elem.replaceWith('<a class="file-input-wrapper btn btn-default' + className + '">'+buttonWord+input+'</a>');
45 + })
46 +
47 + // After we have found all of the file inputs let's apply a listener for tracking the mouse movement.
48 + // This is important because the in order to give the illusion that this is a button in FF we actually need to move the button from the file input under the cursor. Ugh.
49 + .promise().done( function(){
50 +
51 + // As the cursor moves over our new Bootstrap button we need to adjust the position of the invisible file input Browse button to be under the cursor.
52 + // This gives us the pointer cursor that FF denies us
53 + $('.file-input-wrapper').mousemove(function(cursor) {
54 +
55 + var input, wrapper,
56 + wrapperX, wrapperY,
57 + inputWidth, inputHeight,
58 + cursorX, cursorY;
59 +
60 + // This wrapper element (the button surround this file input)
61 + wrapper = $(this);
62 + // The invisible file input element
63 + input = wrapper.find("input");
64 + // The left-most position of the wrapper
65 + wrapperX = wrapper.offset().left;
66 + // The top-most position of the wrapper
67 + wrapperY = wrapper.offset().top;
68 + // The with of the browsers input field
69 + inputWidth= input.width();
70 + // The height of the browsers input field
71 + inputHeight= input.height();
72 + //The position of the cursor in the wrapper
73 + cursorX = cursor.pageX;
74 + cursorY = cursor.pageY;
75 +
76 + //The positions we are to move the invisible file input
77 + // The 20 at the end is an arbitrary number of pixels that we can shift the input such that cursor is not pointing at the end of the Browse button but somewhere nearer the middle
78 + moveInputX = cursorX - wrapperX - inputWidth + 20;
79 + // Slides the invisible input Browse button to be positioned middle under the cursor
80 + moveInputY = cursorY- wrapperY - (inputHeight/2);
81 +
82 + // Apply the positioning styles to actually move the invisible file input
83 + input.css({
84 + left:moveInputX,
85 + top:moveInputY
86 + });
87 + });
88 +
89 + $('.file-input-wrapper input[type=file]').change(function(){
90 +
91 + var fileName;
92 + fileName = $(this).val();
93 +
94 + // Remove any previous file names
95 + $(this).parent().next('.file-input-name').remove();
96 + if (!!$(this).prop('files') && $(this).prop('files').length > 1) {
97 + fileName = $(this)[0].files.length+' files';
98 + //$(this).parent().after('<span class="file-input-name">'+$(this)[0].files.length+' files</span>');
99 + }
100 + else {
101 + // var fakepath = 'C:\\fakepath\\';
102 + // fileName = $(this).val().replace('C:\\fakepath\\','');
103 + fileName = fileName.substring(fileName.lastIndexOf('\\')+1,fileName.length);
104 + }
105 +
106 + $(this).parent().after('<span class="file-input-name">'+fileName+'</span>');
107 + });
108 +
109 + });
110 +
111 +};
112 +
113 +// Add the styles before the first stylesheet
114 +// This ensures they can be easily overridden with developer styles
115 +var cssHtml = '<style>'+
116 + '.file-input-wrapper { overflow: hidden; position: relative; cursor: pointer; z-index: 1; }'+
117 + '.file-input-wrapper input[type=file], .file-input-wrapper input[type=file]:focus, .file-input-wrapper input[type=file]:hover { position: absolute; top: 0; left: 0; cursor: pointer; opacity: 0; filter: alpha(opacity=0); z-index: 99; outline: 0; }'+
118 + '.file-input-name { margin-left: 8px; }'+
119 + '</style>';
120 +$('link[rel=stylesheet]').eq(0).before(cssHtml);
121 +
122 +});
...\ No newline at end of file ...\ No newline at end of file
This diff is collapsed. Click to expand it.
1 +$(document).ready(function(){
2 + $(".abcd .action, .abcd .instance").each(function(){
3 + var objet = this;
4 + $(".action, .instance").each(function(){
5 + if ($(this).attr("data-abcd") == "#" + $(objet).attr("id")){
6 + $(this).html($(objet).html());
7 + }
8 + });
9 + });
10 +
11 + $(".action, .instance, .buffer, .proto").mouseover(function(){
12 +
13 + $(this).addClass("highlight_simul");
14 + $($(this).attr("data-abcd")).addClass("highlight_simul");
15 + $($(this).attr("data-tree")).addClass("highlight_simul");
16 + $($(this).attr("data-net")).addClass("highlight_simul");
17 +
18 + }).mouseout(function(){
19 +
20 + $(this).removeClass("highlight_simul");
21 + $($(this).attr("data-abcd")).removeClass("highlight_simul");
22 + $($(this).attr("data-tree")).removeClass("highlight_simul");
23 + $($(this).attr("data-net")).removeClass("highlight_simul");
24 +
25 + });
26 +});
...\ No newline at end of file ...\ No newline at end of file
1 +/* ABCD source code */
2 +
3 +#model .abcd .comment {
4 + color: #888;
5 +}
6 +
7 +#model .abcd .ident {
8 + color: #808;
9 +}
10 +
11 +#model .abcd .string {
12 + color: #088;
13 +}
14 +
15 +#model .abcd .kw {
16 + color: #800;
17 + font-weight: bold;
18 +}
19 +
20 +#model .abcd .flow {
21 + color: #800;
22 + font-weight: bold;
23 +}
24 +
25 +#model .abcd .buffer .decl {
26 + color: #080;
27 + font-weight: bold;
28 +}
29 +
30 +#model .abcd .net .decl {
31 + color: #008;
32 + font-weight: bold;
33 +}
34 +
35 +#model .abcd .instance .name {
36 + color: #008;
37 +}
38 +
39 +#model .abcd .action .delim {
40 + font-weight: bold;
41 +}
42 +
43 +#model .abcd .action .name {
44 + color: #080;
45 +}
46 +
47 +#model .abcd .active {
48 + background-color: #B6F8AE;
49 +}
50 +
51 +#model .abcd .highlight_simul {
52 + background-color: yellow;
53 +}
54 +
55 +
56 +#model .tree .buffer .kw {
57 + color: #800;
58 + font-weight: bold;
59 +}
60 +
61 +#model .tree .buffer .name {
62 + color: #080;
63 + font-weight: bold;
64 +}
65 +
66 +#model .tree .ident {
67 + color: #808;
68 +}
69 +
70 +#model .tree .instance .name {
71 + color: #008;
72 +}
73 +
74 +#model .tree .action .delim {
75 + font-weight: bold;
76 +}
77 +
78 +#model .tree .action .name {
79 + color: #080;
80 +}
81 +
82 +#model .tree .string {
83 + color: #088;
84 +}
85 +
86 +#model .tree .modes li {
87 + margin: 12px 0px;
88 +}
89 +
90 +#model .tree .modes a {
91 + background-color: #B6F8AE;
92 + border: solid 1px #AAA;
93 + border-radius: 5px;
94 + padding: 5px 10px;
95 + text-decoration: none;
96 + color: #333;
97 +}
98 +
99 +#model .tree .modes a:hover {
100 + color: #A33;
101 + background-color: #F8B6AE;
102 +}
103 +
104 +#model .tree .active {
105 + background-color: #B6F8AE;
106 +}
107 +
108 +#model .tree .highlight_simul {
109 + background-color: yellow;
110 +}
111 +
112 +
1 +<div class="page-header">
2 + <h1><tt>%(filename)s</tt> <small> powered by Franck</small></h1>
3 +</div>
4 +<div class="row">
5 + <div class="col-md-3">
6 +
7 + <div class="row">
8 + <h3>Player</h3>
9 + <div id="player"></div>
10 + </div>
11 + </div>
12 +</div>
13 +<div id="model" class="row">
14 + <div class="col-md-6">
15 + <div class="row">
16 + <h3>ABCD</h3>
17 + <div class="abcd">%(abcd)s</div>
18 + </div>
19 +
20 + </div>
21 + <div class=col-md-6>
22 + <div class="row">
23 + <h3>Tree</h3>
24 + <div class="tree">%(tree)s</div>
25 + </div>
26 + </div>
27 +
28 + <div class="col-md-12">
29 + <div id="trace_zone"></div>
30 + </div>
31 +</div>
32 +
33 +<div class="modal fade" id="net" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
34 + <div class="modal-dialog" style="width:auto;">
35 + <div class="modal-content" style="overflow: scroll;">
36 + %(net)s
37 + </div>
38 + </div>
39 +</div>
...\ No newline at end of file ...\ No newline at end of file
1 +var nodeColor;
2 +
3 +function abcdon () {
4 + obj = $(this);
5 + if (obj.attr("class") == "node") {
6 + node = obj.children().children().first();
7 + nodeColor = node.attr("fill");
8 + node.attr("fill", "yellow");
9 + } else {
10 + obj.addClass("highlight");
11 + }
12 + $(obj.attr("data-abcd")).addClass("highlight");
13 +};
14 +
15 +function abcdoff () {
16 + obj = $(this);
17 + if (obj.attr("class") == "node") {
18 + node = obj.children().children().first();
19 + node.attr("fill", nodeColor);
20 + } else {
21 + obj.removeClass("highlight");
22 + }
23 + $(obj.attr("data-abcd")).removeClass("highlight");
24 +};
25 +
26 +function treeon () {
27 + obj = $(this);
28 + if (obj.attr("class") != "node") {
29 + obj.addClass("highlight");
30 + }
31 + $(obj.attr("data-tree")).addClass("highlight");
32 +};
33 +
34 +function treeoff () {
35 + obj = $(this);
36 + if (obj.attr("class") != "node") {
37 + obj.removeClass("highlight");
38 + }
39 + $(obj.attr("data-tree")).removeClass("highlight");
40 +};
41 +
42 +function neton () {
43 + obj = $(this);
44 + $(obj.attr("data-net")).each(function () {
45 + node = $(this).children().children().first();
46 + nodeColor = node.attr("fill");
47 + node.attr("fill", "yellow");
48 + });
49 + obj.addClass("highlight");
50 +};
51 +
52 +function netoff () {
53 + obj = $(this);
54 + $(obj.attr("data-net")).each(function () {
55 + node = $(this).children().children().first();
56 + node.attr("fill", nodeColor);
57 + });
58 + obj.removeClass("highlight");
59 +};
60 +
61 +$(document).ready(function() {
62 + $("#model [data-abcd]").hover(abcdon, abcdoff);
63 + $("#model [data-tree]").hover(treeon, treeoff);
64 + $("#model [data-net]").hover(neton, netoff);
65 + $(".tree .instance, .tree .action").each(function () {
66 + obj = $(this);
67 + obj.html($(obj.attr("data-abcd")).html());
68 + });
69 +});
1 +body {
2 + font-family: sans-serif;
3 +}
4 +
5 +#alive {
6 + border: solid 1px #AAA;
7 + border-radius: 5px;
8 + padding: 5px 10px;
9 + margin: 5px;
10 + background-color: #DDD;
11 + overflow:auto;
12 +}
13 +
14 +#alive .ui {
15 + display: inline;
16 + list-style: none;
17 + margin: 0px;
18 + padding: 0px;
19 +}
20 +
21 +#alive .ui li {
22 + display: inline;
23 + border: solid 1px #AAA;
24 + padding: 5px 10px;
25 + margin: 0px 3px;
26 + background-color: #EEE;
27 +}
28 +
29 +#alive .ui a {
30 + text-decoration: none;
31 + color: #333;
32 +}
33 +
34 +#alive .ui li:hover {
35 + background-color: #FFF;
36 +}
37 +
38 +#alive .ui a:hover {
39 + color: #A33;
40 +}
41 +
42 +#alive .ping {
43 + color: #DDD;
44 + float: right;
45 +}
46 +
47 +#model {
48 + border: solid 1px #AAA;
49 + border-radius: 5px;
50 + padding: 5px 10px;
51 + margin: 5px;
52 + background-color: #EEE;
53 + overflow:auto;
54 +}
55 +
56 +#trace {
57 + border: solid 1px #AAA;
58 + border-radius: 5px;
59 + padding: 5px 10px;
60 + margin: 5px;
61 + background-color: #EEE;
62 + overflow:auto;
63 +}
64 +
65 +#about {
66 + display: none;
67 +}
68 +
69 +#dialog {
70 + display: none;
71 + position: fixed;
72 + z-index: 2;
73 + top: 10%;
74 + left: 20%;
75 + width: 60%;
76 + border: solid 2px #AAA;
77 + border-radius: 5px;
78 + padding: 20px;
79 + background-color: #FFF;
80 + overflow:auto;
81 +}
82 +
83 +#dialog-bg {
84 + display: none;
85 + position: fixed;
86 + z-index: 1;
87 + top: 0px;
88 + left: 0px;
89 + width: 100%;
90 + height: 100%;
91 + background-color: #000;
92 + margin: 0px;
93 +}
94 +
95 +#dialog-close {
96 + /* TODO: fix position when dialog has a horizontal scrollbar */
97 + display: block;
98 + float: right;
99 + border: solid 1px #AAA;
100 + padding: 5px 10px;
101 + margin: 0px 3px;
102 + background-color: #EEE;
103 + text-decoration: none;
104 + color: #333;
105 +}
106 +
107 +#dialog-close:hover {
108 + background-color: #FFF;
109 + color: #A33;
110 +}
111 +
112 +.dialog p {
113 + margin: 10px 20px 0px 20px;
114 +}
115 +
116 +.dialog .title {
117 + margin: 0px 20px 5px 20px;
118 + font-weight: bold;
119 + text-align: center;
120 +}
121 +
122 +.dialog .subtitle {
123 + margin: 0px 20px 5px 20px;
124 + text-align: center;
125 +}
...\ No newline at end of file ...\ No newline at end of file
This diff is collapsed. Click to expand it.
1 +from snakes.utils.simul import BaseSimulator, BaseHTTPSimulator
2 +import snakes.utils.abcd.html as html
3 +
4 +class ABCDSimulator (BaseSimulator) :
5 + def __init__ (self, node, net, gv) :
6 + BaseSimulator.__init__(self, net)
7 + a2html = html.ABCD2HTML(node)
8 + n2html = html.Net2HTML(net, gv, a2html)
9 + self.info = {"filename" : node.st.filename,
10 + "abcd" : a2html.html(),
11 + "tree" : n2html.html(),
12 + "net" : n2html.svg()}
13 + self.tree = {}
14 + for node in net.node() :
15 + nid = gv.nodemap[node.name]
16 + if nid in n2html.n2t :
17 + self.tree[node.name] = "#" + n2html.n2t[nid]
18 + self.places = [place.name for place in net.place()
19 + if place.name in self.tree]
20 + self.abcd = {}
21 + self.transid = []
22 + for trans in net.transition() :
23 + nid = gv.nodemap[trans.name]
24 + self.transid.append(self.tree[trans.name])
25 + if nid in n2html.n2a :
26 + self.abcd[trans.name] = ", ".join("#" + i for i in
27 + n2html.n2a[nid])
28 + def init (self, state=-1) :
29 + res = BaseSimulator.init(self, state)
30 + res.update(self.info)
31 + res["help"] = self.init_help()
32 + return res
33 + def init_help (self) :
34 + help = BaseSimulator.init_help(self)
35 + help.update({
36 + "#model .abcd" : {
37 + "title" : "Source",
38 + "content" : "ABCD source code"
39 + },
40 + "#model .tree" : {
41 + "title" : "State",
42 + "content" : "hierarchy of ABCD objects",
43 + },
44 + "#model .petrinet" : {
45 + "title" : "Net",
46 + "content" : "Petri nets semantics"
47 + }})
48 + return help
49 + def getstate (self, state) :
50 + marking = self.states[state]
51 + modes = dict((t, []) for t in self.transid)
52 + for i, (trans, mode) in enumerate(marking.modes) :
53 + modes[self.tree[trans.name]].append({"state" : state,
54 + "mode" : i,
55 + "html" : str(mode)})
56 + return {"id" : state,
57 + "states" :
58 + [{"do" : "dropclass",
59 + "select" : "#model .active",
60 + "class" : "active"}]
61 + + [{"do" : "addclass",
62 + "select" : self.abcd[trans.name],
63 + "class" : "active"} for trans, mode in marking.modes]
64 + + [{"do" : "addclass",
65 + "select" : self.tree[trans.name],
66 + "class" : "active"} for trans, mode in marking.modes]
67 + + [{"do" : "settext",
68 + "select" : "%s .content" % self.tree[place],
69 + "text" : "{}"} for place in self.places
70 + if place not in marking]
71 + + [{"do" : "settext",
72 + "select" : "%s .content" % self.tree[place],
73 + "text" : str(marking[place])} for place in marking
74 + if place in self.tree],
75 + "modes" : [{"select" : "%s + .modes" % trans,
76 + "items" : items}
77 + for trans, items in modes.items()],
78 + }
79 +
80 +class Simulator (BaseHTTPSimulator) :
81 + def __init__ (self, node, net, gv, port) :
82 + simul = ABCDSimulator(node, net, gv)
83 + BaseHTTPSimulator.__init__(self, net, simulator=simul, port=port)
84 + def init_model (self) :
85 + return self.res["model.html"] % self.simul.info
86 + def init_ui (self) :
87 + return BaseHTTPSimulator.init_ui(self)[:-1] + [{
88 + "label" : "Show net",
89 + "id" : "ui-shownet",
90 + "href" : "#",
91 + "script" : "dialog($('#model .petrinet').html())"
92 + }]
1 +from snakes.lang.abcd.parser import ast
2 +
3 +class NodeCopier (ast.NodeTransformer) :
4 + def copy (self, node, **replace) :
5 + args = {}
6 + for name in node._fields + node._attributes :
7 + old = getattr(node, name, None)
8 + if name in replace :
9 + new = replace[name]
10 + elif isinstance(old, list):
11 + new = []
12 + for val in old :
13 + if isinstance(val, ast.AST) :
14 + new.append(self.visit(val))
15 + else :
16 + new.append(val)
17 + elif isinstance(old, ast.AST):
18 + new = self.visit(old)
19 + else :
20 + new = old
21 + args[name] = new
22 + if hasattr(node, "st") :
23 + args["st"] = node.st
24 + return node.__class__(**args)
25 + def generic_visit (self, node) :
26 + return self.copy(node)
27 +
28 +class ArgsBinder (NodeCopier) :
29 + def __init__ (self, args, buffers, nets, tasks) :
30 + NodeCopier.__init__(self)
31 + self.args = args
32 + self.buffers = buffers
33 + self.nets = nets
34 + self.tasks = tasks
35 + def visit_Name (self, node) :
36 + if node.id in self.args :
37 + return self.copy(self.args[node.id])
38 + else :
39 + return self.copy(node)
40 + def visit_Instance (self, node) :
41 + if node.net in self.nets :
42 + return self.copy(node, net=self.nets[node.net])
43 + else :
44 + return self.copy(node)
45 + def _visit_access (self, node) :
46 + if node.buffer in self.buffers :
47 + return self.copy(node, buffer=self.buffers[node.buffer])
48 + else :
49 + return self.copy(node)
50 + def visit_SimpleAccess (self, node) :
51 + return self._visit_access(node)
52 + def visit_FlushAccess (self, node) :
53 + return self._visit_access(node)
54 + def visit_SwapAccess (self, node) :
55 + return self._visit_access(node)
56 + def _visit_task (self, node) :
57 + if node.net in self.tasks :
58 + return self.copy(node, net=self.tasks[node.net])
59 + else :
60 + return self.copy(node)
61 + def visit_Spawn (self, node) :
62 + return self._visit_task(node)
63 + def visit_Wait (self, node) :
64 + return self._visit_task(node)
65 + def visit_Suspend (self, node) :
66 + return self._visit_task(node)
67 + def visit_Resume (self, node) :
68 + return self._visit_task(node)
69 + def visit_AbcdNet (self, node) :
70 + args = self.args.copy()
71 + buffers = self.buffers.copy()
72 + nets = self.nets.copy()
73 + tasks = self.tasks.copy()
74 + netargs = ([a.arg for a in node.args.args + node.args.kwonlyargs]
75 + + [node.args.vararg, node.args.kwarg])
76 + copy = True
77 + for a in netargs :
78 + for d in (args, buffers, nets, tasks) :
79 + if a in d :
80 + del d[a]
81 + copy = False
82 + if copy :
83 + return self.copy(node)
84 + else :
85 + return self.__class__(args, buffers, nets, tasks).visit(node)
86 +
87 +if __name__ == "__main__" :
88 + import doctest
89 + doctest.testmod()