Franck Pommereau

CoffeeScript (lib & codegen) complete but still buggy

......@@ -109,6 +109,14 @@ class Dict
for key, val of init
@set(key, val)
clear: ->
"""
coffee> a = new dicts.Dict(a:1, b:2, c:3)
coffee> a.empty()
false
coffee> a.clear()
coffee> a.empty()
true
"""
@indices = {}
@itemlist = []
@used = 0
......@@ -120,6 +128,14 @@ class Dict
2
"""
return @used
empty: ->
"""
coffee> (new dicts.Dict()).empty()
true
coffee> (new dicts.Dict(a:1, b:2)).empty()
false
"""
return @used == 0
_gen_probes: (hashvalue) ->
PERTURB_SHIFT = 5
if hashvalue < 0
......@@ -164,11 +180,24 @@ class Dict
@used++
else
@itemlist[index] = {key: key, value: value, hash: hashvalue}
fetch: (key, otherwise=null) ->
getitem: (key, def=undefined) ->
"""
coffee> a = new dicts.Dict(a:1, b:2)
coffee> a.getitem("a")
[ 'a', 1 ]
coffee> a.getitem("x")
Thrown: ...
coffee> a.getitem("x", null)
[ 'x', null ]
"""
[index, i] = @_lookup(key, hash(key))
if index < 0
return otherwise
return @itemlist[index].value
if def is undefined
throw new KeyError("key #{key} not found")
else
return [key, def]
item = @itemlist[index]
return [item.key, item.value]
get: (key, def=undefined) ->
"""
coffee> a = new dicts.Dict(a:1, b:2)
......@@ -179,13 +208,7 @@ class Dict
coffee> a.get("x", null)
null
"""
[index, i] = @_lookup(key, hash(key))
if index < 0
if def is undefined
throw new KeyError("key #{key} not found")
else
return def
return @itemlist[index].value
return @getitem(key, def)[1]
del: (key) ->
"""
coffee> a = new dicts.Dict(a:1, b:2)
......@@ -207,23 +230,72 @@ class Dict
@itemlist[index] = lastitem
@itemlist.pop()
iter: ->
"""
coffee> a = new dicts.Dict(a:1, b:2)
coffee> ([k, v] for [k, v] from a.iter())
[ [ 'a', 1 ], [ 'b', 2 ] ]
coffee> b = new dicts.Dict()
coffee> ([k, v] for [k, v] from b.iter())
[]
"""
for item in @itemlist
yield [item.key, item.value]
copy: ->
"""
coffee> a = new dicts.Dict(a:1, b:2)
coffee> a.copy().eq(a)
true
coffee> a.eq(a.copy())
true
coffee> a is a.copy()
false
"""
copy = new Dict()
for item in @itemlist
copy.set(item.key, item.value)
return copy
has: (key) ->
"""
coffee> a = new dicts.Dict(a:1, b:2)
coffee> (a.has(x) for x in "abcd")
[ true, true, false, false ]
"""
[index, i] = @_lookup(key, hash(key))
return index >= 0
pop: ->
if @user == 0
"""
coffee> a = new dicts.Dict(a:1, b:2, c:3)
coffee> a.pop()
[ 'c', 3 ]
coffee> a.pop()
[ 'b', 2 ]
coffee> a.pop()
[ 'a', 1 ]
coffee> a.pop()
Thrown: ...
"""
if @used == 0
throw new KeyError("cannot pop from empty dict")
item = @itemlist[@itemlist.length - 1]
@del(key)
@del(item.key)
return [item.key, item.value]
eq: (other) ->
"""
coffee> a = new dicts.Dict(a:1, b:2, c:3)
coffee> b = new dicts.Dict(a:1, b:2)
coffee> c = new dicts.Dict(c:3, b:2, a:1)
coffee> e = new dicts.Dict()
coffee> a.eq(c)
true
coffee> a.eq(b)
false
coffee> c.eq(a)
true
coffee> e.eq(a)
false
coffee> e.eq(new dicts.Dict())
true
"""
if other not instanceof Dict
return false
if @used != other.used
......
......@@ -102,6 +102,7 @@
}
clear() {
"coffee> a = new dicts.Dict(a:1, b:2, c:3)\ncoffee> a.empty()\nfalse\ncoffee> a.clear()\ncoffee> a.empty()\ntrue";
this.indices = {};
this.itemlist = [];
return this.used = 0;
......@@ -112,6 +113,11 @@
return this.used;
}
empty() {
"coffee> (new dicts.Dict()).empty()\ntrue\ncoffee> (new dicts.Dict(a:1, b:2)).empty()\nfalse";
return this.used === 0;
}
* _gen_probes(hashvalue) {
var PERTURB_SHIFT, i, perturb, results;
PERTURB_SHIFT = 5;
......@@ -178,27 +184,24 @@
}
}
fetch(key, otherwise = null) {
var i, index;
[index, i] = this._lookup(key, hash(key));
if (index < 0) {
return otherwise;
}
return this.itemlist[index].value;
}
get(key, def = void 0) {
"coffee> a = new dicts.Dict(a:1, b:2)\ncoffee> a.get(\"a\")\n1\ncoffee> a.get(\"x\")\nThrown: ...\ncoffee> a.get(\"x\", null)\nnull";
var i, index;
getitem(key, def = void 0) {
"coffee> a = new dicts.Dict(a:1, b:2)\ncoffee> a.getitem(\"a\")\n[ 'a', 1 ]\ncoffee> a.getitem(\"x\")\nThrown: ...\ncoffee> a.getitem(\"x\", null)\n[ 'x', null ]";
var i, index, item;
[index, i] = this._lookup(key, hash(key));
if (index < 0) {
if (def === void 0) {
throw new KeyError(`key ${key} not found`);
} else {
return def;
return [key, def];
}
}
return this.itemlist[index].value;
item = this.itemlist[index];
return [item.key, item.value];
}
get(key, def = void 0) {
"coffee> a = new dicts.Dict(a:1, b:2)\ncoffee> a.get(\"a\")\n1\ncoffee> a.get(\"x\")\nThrown: ...\ncoffee> a.get(\"x\", null)\nnull";
return this.getitem(key, def)[1];
}
del(key) {
......@@ -220,6 +223,7 @@
}
* iter() {
"coffee> a = new dicts.Dict(a:1, b:2)\ncoffee> ([k, v] for [k, v] from a.iter())\n[ [ 'a', 1 ], [ 'b', 2 ] ]\ncoffee> b = new dicts.Dict()\ncoffee> ([k, v] for [k, v] from b.iter())\n[]";
var item, l, len, ref, results;
ref = this.itemlist;
results = [];
......@@ -231,6 +235,7 @@
}
copy() {
"coffee> a = new dicts.Dict(a:1, b:2)\ncoffee> a.copy().eq(a)\ntrue\ncoffee> a.eq(a.copy())\ntrue\ncoffee> a is a.copy()\nfalse";
var copy, item, l, len, ref;
copy = new Dict();
ref = this.itemlist;
......@@ -242,22 +247,25 @@
}
has(key) {
"coffee> a = new dicts.Dict(a:1, b:2)\ncoffee> (a.has(x) for x in \"abcd\")\n[ true, true, false, false ]";
var i, index;
[index, i] = this._lookup(key, hash(key));
return index >= 0;
}
pop() {
"coffee> a = new dicts.Dict(a:1, b:2, c:3)\ncoffee> a.pop()\n[ 'c', 3 ]\ncoffee> a.pop()\n[ 'b', 2 ]\ncoffee> a.pop()\n[ 'a', 1 ]\ncoffee> a.pop()\nThrown: ...";
var item;
if (this.user === 0) {
if (this.used === 0) {
throw new KeyError("cannot pop from empty dict");
}
item = this.itemlist[this.itemlist.length - 1];
this.del(key);
this.del(item.key);
return [item.key, item.value];
}
eq(other) {
"coffee> a = new dicts.Dict(a:1, b:2, c:3)\ncoffee> b = new dicts.Dict(a:1, b:2)\ncoffee> c = new dicts.Dict(c:3, b:2, a:1)\ncoffee> e = new dicts.Dict()\ncoffee> a.eq(c)\ntrue\ncoffee> a.eq(b)\nfalse\ncoffee> c.eq(a)\ntrue\ncoffee> e.eq(a)\nfalse\ncoffee> e.eq(new dicts.Dict())\ntrue";
var k, ref, v, x, y;
if (!(other instanceof Dict)) {
return false;
......
This diff is collapsed. Click to expand it.
sets = require "./sets"
dicts =
statespace = (init, addsucc, print_states, print_succs, print_dead) ->
i = init()
i.id = 0
todo = new sets.Queue(i)
seen = new sets.Set()
dead = 0
while not todo.empty()
state = todo.get()
succ = new sets.Set()
addsucc(state, succ)
if succ.empty()
dead += 1
if (print_dead and succ.empty()) or print_states
console.log state.toString()
for s from succ.iter()
if seen.has(s)
s = seen.get(s)
else
s.id = seen.len()
seen.add(s)
todo.put(s)
if print_succs
console.log ">", s.toString()
return [seen.len(), dead]
lts = (init, itersucc) ->
i = init()
i.id = 0
todo = new sets.Queue(i)
seen = new sets.Set()
while not todo.empty()
state = todo.get()
console.log state.toString()
for [trans, mode, sub, add] from itersucc(state)
succ = state.copy().sub(sub).add(add)
if seen.has(succ)
succ = seen.get(s)
else
succ.id = seen.len()
seen.add(succ)
todo.put(succ)
console.log "@ #{ trans } = #{ mode }"
console.log " - #{ sub.toString() }"
console.log " + #{ add.toString() }"
console.log " > #{ succ.toString() }"
main = (name, init, addsucc, itersucc) ->
args = {s: false, d: false, m: false, g: false, l: false}
for c in process.argv[2..].join("")
if args[c]?
args[c] = true
else if c == "-"
# skip
else if c == "h"
console.log "usage: #{ name } [-s] (-d|-g|-m|-l|-h)"
console.log " options:"
console.log " -l labelled transitions system"
console.log " -g print marking graph"
console.log " -m only print markings"
console.log " -d only print deadlocks"
console.log " -s only print size"
console.log " -h print help and exit"
return
else
console.log "invalid option #{ c }, try -h for help"
return
if args.s
[s, d] = statespace(init, addsucc, false, false, false)
if args.d
console.log "#{ d } deadlocks"
else
console.log "#{ s } reachable states"
else if args.l
lts(init, itersucc)
else if args.g
statespace(init, addsucc, true, true, false)
else if args.m
statespace(init, addsucc, true, false, false)
else if args.d
statespace(init, addsucc, false, false, true)
else
console.log "missing option, try -h for help"
module.exports =
statespace: statespace
lts: lts
main: main
// Generated by CoffeeScript 2.0.2
(function() {
var dicts, lts, main, sets, statespace;
sets = require("./sets");
dicts = statespace = function(init, addsucc, print_states, print_succs, print_dead) {
var dead, i, ref, s, seen, state, succ, todo;
i = init();
i.id = 0;
todo = new sets.Queue(i);
seen = new sets.Set();
dead = 0;
while (!todo.empty()) {
state = todo.get();
succ = new sets.Set();
addsucc(state, succ);
if (succ.empty()) {
dead += 1;
}
if ((print_dead && succ.empty()) || print_states) {
console.log(state.toString());
}
ref = succ.iter();
for (s of ref) {
if (seen.has(s)) {
s = seen.get(s);
} else {
s.id = seen.len();
seen.add(s);
todo.put(s);
}
if (print_succs) {
console.log(">", s.toString());
}
}
}
return [seen.len(), dead];
};
lts = function(init, itersucc) {
var add, i, mode, results, seen, state, sub, succ, todo, trans;
i = init();
i.id = 0;
todo = new sets.Queue(i);
seen = new sets.Set();
results = [];
while (!todo.empty()) {
state = todo.get();
console.log(state.toString());
results.push((function() {
var ref, results1, x;
ref = itersucc(state);
results1 = [];
for (x of ref) {
[trans, mode, sub, add] = x;
succ = state.copy().sub(sub).add(add);
if (seen.has(succ)) {
succ = seen.get(s);
} else {
succ.id = seen.len();
seen.add(succ);
todo.put(succ);
}
console.log(`@ ${trans} = ${mode}`);
console.log(` - ${sub.toString()}`);
console.log(` + ${add.toString()}`);
results1.push(console.log(` > ${succ.toString()}`));
}
return results1;
})());
}
return results;
};
main = function(name, init, addsucc, itersucc) {
var args, c, d, j, len, ref, s;
args = {
s: false,
d: false,
m: false,
g: false,
l: false
};
ref = process.argv.slice(2).join("");
for (j = 0, len = ref.length; j < len; j++) {
c = ref[j];
if (args[c] != null) {
args[c] = true;
} else if (c === "-") {
// skip
} else if (c === "h") {
console.log(`usage: ${name} [-s] (-d|-g|-m|-l|-h)`);
console.log(" options:");
console.log(" -l labelled transitions system");
console.log(" -g print marking graph");
console.log(" -m only print markings");
console.log(" -d only print deadlocks");
console.log(" -s only print size");
console.log(" -h print help and exit");
return;
} else {
console.log(`invalid option ${c}, try -h for help`);
return;
}
}
if (args.s) {
[s, d] = statespace(init, addsucc, false, false, false);
if (args.d) {
return console.log(`${d} deadlocks`);
} else {
return console.log(`${s} reachable states`);
}
} else if (args.l) {
return lts(init, itersucc);
} else if (args.g) {
return statespace(init, addsucc, true, true, false);
} else if (args.m) {
return statespace(init, addsucc, true, false, false);
} else if (args.d) {
return statespace(init, addsucc, false, false, true);
} else {
return console.log("missing option, try -h for help");
}
};
module.exports = {
statespace: statespace,
lts: lts,
main: main
};
}).call(this);
//# sourceMappingURL=main.js.map
{
"version": 3,
"file": "main.js",
"sourceRoot": "../..",
"sources": [
"libs/js/main.coffee"
],
"names": [],
"mappings": "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",
"sourcesContent": [
"sets = require \"./sets\"\ndicts = \n\nstatespace = (init, addsucc, print_states, print_succs, print_dead) ->\n i = init()\n i.id = 0\n todo = new sets.Queue(i)\n seen = new sets.Set()\n dead = 0\n while not todo.empty()\n state = todo.get()\n succ = new sets.Set()\n addsucc(state, succ)\n if succ.empty()\n dead += 1\n if (print_dead and succ.empty()) or print_states\n console.log state.toString()\n for s from succ.iter()\n if seen.has(s)\n s = seen.get(s)\n else\n s.id = seen.len()\n seen.add(s)\n todo.put(s)\n if print_succs\n console.log \">\", s.toString()\n return [seen.len(), dead]\n \nlts = (init, itersucc) ->\n i = init()\n i.id = 0\n todo = new sets.Queue(i)\n seen = new sets.Set()\n while not todo.empty()\n state = todo.get()\n console.log state.toString()\n for [trans, mode, sub, add] from itersucc(state)\n succ = state.copy().sub(sub).add(add)\n if seen.has(succ)\n succ = seen.get(s)\n else\n succ.id = seen.len()\n seen.add(succ)\n todo.put(succ)\n console.log \"@ #{ trans } = #{ mode }\"\n console.log \" - #{ sub.toString() }\"\n console.log \" + #{ add.toString() }\"\n console.log \" > #{ succ.toString() }\"\n\nmain = (name, init, addsucc, itersucc) ->\n args = {s: false, d: false, m: false, g: false, l: false}\n for c in process.argv[2..].join(\"\")\n if args[c]?\n args[c] = true\n else if c == \"-\"\n # skip\n else if c == \"h\"\n console.log \"usage: #{ name } [-s] (-d|-g|-m|-l|-h)\"\n console.log \" options:\"\n console.log \" -l labelled transitions system\"\n console.log \" -g print marking graph\"\n console.log \" -m only print markings\"\n console.log \" -d only print deadlocks\"\n console.log \" -s only print size\"\n console.log \" -h print help and exit\"\n return\n else\n console.log \"invalid option #{ c }, try -h for help\"\n return\n if args.s\n [s, d] = statespace(init, addsucc, false, false, false)\n if args.d\n console.log \"#{ d } deadlocks\"\n else\n console.log \"#{ s } reachable states\"\n else if args.l\n lts(init, itersucc)\n else if args.g\n statespace(init, addsucc, true, true, false)\n else if args.m\n statespace(init, addsucc, true, false, false)\n else if args.d\n statespace(init, addsucc, false, false, true)\n else\n console.log \"missing option, try -h for help\"\n\nmodule.exports =\n statespace: statespace\n lts: lts\n main: main\n"
]
}
\ No newline at end of file
dicts = require "./dicts"
msets = require "./multisets"
class BlackToken
toString: -> "dot"
dot = new BlackToken()
class Marking
constructor: (@id=null) ->
"""
......@@ -182,7 +187,12 @@ class Marking
{'p1': [1, 2, 3], 'p2': [3, 4]}
"""
items = ("'#{ p }': #{ m.toString() }" for [p, m] from @iter())
return "{#{ items.join(', ') }}"
if @id != null
return "[#{ @id }] {#{ items.join(', ') }}"
else
return "{#{ items.join(', ') }}"
module.exports =
Marking: Marking
dot: dot
BlackToken: BlackToken
......
// Generated by CoffeeScript 2.0.2
(function() {
var Marking, dicts, msets;
var BlackToken, Marking, dicts, dot, msets;
dicts = require("./dicts");
msets = require("./multisets");
BlackToken = class BlackToken {
toString() {
return "dot";
}
};
dot = new BlackToken();
Marking = class Marking {
constructor(id1 = null) {
this.id = id1;
......@@ -138,13 +147,19 @@
}
return results;
}).call(this);
return `{${items.join(', ')}}`;
if (this.id !== null) {
return `[${this.id}] {${items.join(', ')}}`;
} else {
return `{${items.join(', ')}}`;
}
}
};
module.exports = {
Marking: Marking
Marking: Marking,
dot: dot,
BlackToken: BlackToken
};
}).call(this);
......
This diff is collapsed. Click to expand it.
dicts = require "./dicts"
class Set
constructor: (markings...) ->
@d = new dicts.Dict()
for m in markings
@add(m)
empty: ->
return @d.empty()
len: ->
return @d.len()
add: (marking) ->
@d.set(marking, null)
get: (marking) ->
return @d.getitem(marking)[0]
has: (marking) ->
return @d.has(marking)
iter: ->
for [m, _] from @d.iter()
yield m
class QueueError
constructor: (@message) ->
@name = "QueueError"
class Queue
constructor: (markings...) ->
@data = {}
@head = 0
@tail = 0
for m in markings
@put(m)
empty: ->
return @head == @tail
full: ->
return @head == @tail+1
put: (marking) ->
if @full()
throw new QueueError("cannot put on full queue")
@data[@tail] = marking
@tail++
get: ->
if @empty()
throw new QueueError("cannot get from empty queue")
m = @data[@head]
delete @data[@head]
@head++
return m
module.exports =
Set: Set
QueueError: QueueError
Queue: Queue
// Generated by CoffeeScript 2.0.2
(function() {
var Queue, QueueError, Set, dicts;
dicts = require("./dicts");
Set = class Set {
constructor(...markings) {
var i, len, m;
this.d = new dicts.Dict();
for (i = 0, len = markings.length; i < len; i++) {
m = markings[i];
this.add(m);
}
}
empty() {
return this.d.empty();
}
len() {
return this.d.len();
}
add(marking) {
return this.d.set(marking, null);
}
get(marking) {
return this.d.getitem(marking)[0];
}
has(marking) {
return this.d.has(marking);
}
* iter() {
var _, m, ref, results, x;
ref = this.d.iter();
results = [];
for (x of ref) {
[m, _] = x;
results.push((yield m));
}
return results;
}
};
QueueError = class QueueError {
constructor(message) {
this.message = message;
this.name = "QueueError";
}
};
Queue = class Queue {
constructor(...markings) {
var i, len, m;
this.data = {};
this.head = 0;
this.tail = 0;
for (i = 0, len = markings.length; i < len; i++) {
m = markings[i];
this.put(m);
}
}
empty() {
return this.head === this.tail;
}
full() {
return this.head === this.tail + 1;
}
put(marking) {
if (this.full()) {
throw new QueueError("cannot put on full queue");
}
this.data[this.tail] = marking;
return this.tail++;
}
get() {
var m;
if (this.empty()) {
throw new QueueError("cannot get from empty queue");
}
m = this.data[this.head];
delete this.data[this.head];
this.head++;
return m;
}
};
module.exports = {
Set: Set,
QueueError: QueueError,
Queue: Queue
};
}).call(this);
//# sourceMappingURL=sets.js.map
{
"version": 3,
"file": "sets.js",
"sourceRoot": "../..",
"sources": [
"libs/js/sets.coffee"
],
"names": [],
"mappings": ";AAAA;AAAA,MAAA,KAAA,EAAA,UAAA,EAAA,GAAA,EAAA;;EAAA,KAAA,GAAQ,OAAA,CAAQ,SAAR;;EAEF,MAAN,MAAA,IAAA;IACI,WAAa,CAAA,GAAC,QAAD,CAAA;AACT,UAAA,CAAA,EAAA,GAAA,EAAA;MAAA,IAAC,CAAA,CAAD,GAAK,IAAI,KAAK,CAAC,IAAV,CAAA;MACL,KAAA,0CAAA;;QACI,IAAC,CAAA,GAAD,CAAK,CAAL;MADJ;IAFS;;IAIb,KAAO,CAAA,CAAA;AACH,aAAO,IAAC,CAAA,CAAC,CAAC,KAAH,CAAA;IADJ;;IAEP,GAAK,CAAA,CAAA;AACD,aAAO,IAAC,CAAA,CAAC,CAAC,GAAH,CAAA;IADN;;IAEL,GAAK,CAAC,OAAD,CAAA;aACD,IAAC,CAAA,CAAC,CAAC,GAAH,CAAO,OAAP,EAAgB,IAAhB;IADC;;IAEL,GAAK,CAAC,OAAD,CAAA;AACD,aAAO,IAAC,CAAA,CAAC,CAAC,OAAH,CAAW,OAAX,CAAoB,CAAA,CAAA;IAD1B;;IAEL,GAAK,CAAC,OAAD,CAAA;AACD,aAAO,IAAC,CAAA,CAAC,CAAC,GAAH,CAAO,OAAP;IADN;;IAEC,EAAN,IAAM,CAAA,CAAA;AACF,UAAA,CAAA,EAAA,CAAA,EAAA,GAAA,EAAA,OAAA,EAAA;AAAA;AAAA;MAAA,KAAA,QAAA;QAAI,CAAC,CAAD,EAAI,CAAJ;qBACA,CAAA,MAAM,CAAN;MADJ,CAAA;;IADE;;EAfV;;EAmBM,aAAN,MAAA,WAAA;IACI,WAAa,QAAA,CAAA;MAAC,IAAC,CAAA;MACX,IAAC,CAAA,IAAD,GAAQ;IADC;;EADjB;;EAIM,QAAN,MAAA,MAAA;IACI,WAAa,CAAA,GAAC,QAAD,CAAA;AACT,UAAA,CAAA,EAAA,GAAA,EAAA;MAAA,IAAC,CAAA,IAAD,GAAQ,CAAA;MACR,IAAC,CAAA,IAAD,GAAQ;MACR,IAAC,CAAA,IAAD,GAAQ;MACR,KAAA,0CAAA;;QACI,IAAC,CAAA,GAAD,CAAK,CAAL;MADJ;IAJS;;IAMb,KAAO,CAAA,CAAA;AACH,aAAO,IAAC,CAAA,IAAD,KAAS,IAAC,CAAA;IADd;;IAEP,IAAM,CAAA,CAAA;AACF,aAAO,IAAC,CAAA,IAAD,KAAS,IAAC,CAAA,IAAD,GAAM;IADpB;;IAEN,GAAK,CAAC,OAAD,CAAA;MACD,IAAG,IAAC,CAAA,IAAD,CAAA,CAAH;QACI,MAAM,IAAI,UAAJ,CAAe,0BAAf,EADV;;MAEA,IAAC,CAAA,IAAK,CAAA,IAAC,CAAA,IAAD,CAAN,GAAe;aACf,IAAC,CAAA,IAAD;IAJC;;IAKL,GAAK,CAAA,CAAA;AACD,UAAA;MAAA,IAAG,IAAC,CAAA,KAAD,CAAA,CAAH;QACI,MAAM,IAAI,UAAJ,CAAe,6BAAf,EADV;;MAEA,CAAA,GAAI,IAAC,CAAA,IAAK,CAAA,IAAC,CAAA,IAAD;MACV,OAAO,IAAC,CAAA,IAAK,CAAA,IAAC,CAAA,IAAD;MACb,IAAC,CAAA,IAAD;AACA,aAAO;IANN;;EAhBT;;EAwBA,MAAM,CAAC,OAAP,GACI;IAAA,GAAA,EAAK,GAAL;IACA,UAAA,EAAY,UADZ;IAEA,KAAA,EAAO;EAFP;AAlDJ",
"sourcesContent": [
"dicts = require \"./dicts\"\n\nclass Set\n constructor: (markings...) ->\n @d = new dicts.Dict()\n for m in markings\n @add(m)\n empty: ->\n return @d.empty()\n len: ->\n return @d.len()\n add: (marking) ->\n @d.set(marking, null)\n get: (marking) ->\n return @d.getitem(marking)[0]\n has: (marking) ->\n return @d.has(marking)\n iter: ->\n for [m, _] from @d.iter()\n yield m\n\nclass QueueError\n constructor: (@message) ->\n @name = \"QueueError\"\n\nclass Queue\n constructor: (markings...) ->\n @data = {}\n @head = 0\n @tail = 0\n for m in markings\n @put(m)\n empty: ->\n return @head == @tail\n full: ->\n return @head == @tail+1\n put: (marking) ->\n if @full()\n throw new QueueError(\"cannot put on full queue\")\n @data[@tail] = marking\n @tail++\n get: ->\n if @empty()\n throw new QueueError(\"cannot get from empty queue\")\n m = @data[@head]\n delete @data[@head]\n @head++\n return m\n\nmodule.exports =\n Set: Set\n QueueError: QueueError\n Queue: Queue\n"
]
}
\ No newline at end of file
......@@ -366,8 +366,9 @@ class Indent (object) :
self.gen._indent -= self.inc
class CodeGenerator (object) :
def __init__ (self, output) :
def __init__ (self, output, **options) :
self.output = output
self.options = options
self.succfunc = {}
self.succproc = {}
self.succiter = {}
......
import subprocess
from snakes.compil import CompilationError, BaseDeclare
from . import codegen as codegen
from .rename import rename
NONETYPE = True
BOOL = "Boolean"
EXT = ".coffee"
INMEM = False
class Declare (BaseDeclare) :
pass
def build (ast, src, name) :
try :
subprocess.check_output(["coffee", src], stderr=subprocess.STDOUT)
except Exception as err :
out = err.output.decode()
TODO
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)
This diff is collapsed. Click to expand it.
import re
elements = {
"comment" : r"(#[^\n].*[\n\r]|###.*?###)",
"string" : "|".join("(%s)" % s for s in [
r"'([^\'\\]|\\[^\n])*'",
r'"([^\"\\]|\\[^\n])*"',
r"'''.*?'''",
r'""".*?"""',
]),
"keyword" : "|".join(
"""case default function var void with const let enum export import
native __hasProp __extends __slice __bind __indexOf implements else
interface package private protected public static yield true false
null this new delete typeof in arguments eval instanceof return throw
break continue debugger if else switch for while do try catch finally
class extends super undefined then unless until loop of by when and or
is isnt not yes no on off""".split()),
"name" : r"[\w$_](?<!\d)[\w$_]*",
"dot_at" : r"[.@]"}
lexer = re.compile("|".join("(?P<%s>%s)" % pair for pair in elements.items()),
re.DOTALL|re.MULTILINE)
def _tokenize (text) :
pos = 0
for match in lexer.finditer(text) :
s, e = match.span()
if s > pos :
yield "text", text[pos:s]
for name, value in match.groupdict().items() :
if value :
yield name, value
break
pos = e
def rename (text, tr) :
def ren() :
dot_at = False
for typ, txt in _tokenize(text) :
if typ == "name" and not dot_at :
yield tr.get(txt, txt)
else :
yield txt
dot_at = typ == "dot_at"
return "".join(ren())
......@@ -16,17 +16,22 @@ elements = {
"continue for import return var"
.split()),
"name" : r"[^\W\d]\w*",
"dot" : r"\.",
"text" : "[^.]"}
"dot" : r"\."}
lexer = re.compile("|".join("(?P<%s>%s)" % pair for pair in elements.items()),
re.DOTALL|re.MULTILINE)
def _tokenize (text) :
pos = 0
for match in lexer.finditer(text) :
s, e = match.span()
if s > pos :
yield "text", text[pos:s]
for name, value in match.groupdict().items() :
if value :
yield name, value
break
pos = e
def rename (text, tr) :
def ren() :
......
......@@ -3,7 +3,7 @@ import os, os.path, subprocess, re
def walk (root='libs/js') :
for dirpath, dirnames, filenames in os.walk(root) :
for name in filenames :
if name.endswith('.coffee') :
if name.endswith('.coffee') and not name.startswith(".") :
yield os.path.relpath(os.path.join(dirpath, name), root)
class Test (object) :
......
# test net with all features
lang coffee
declare """
MAX = 5
abs = Math.abs
max = Math.max
"""
net "test net" :
place p0 = dot # ensure finite execution
place p1 Number = 0, 1, 2
place p2 Number = 1, 2, 3
place p3 Number = MAX, {MAX+1}
# values
trans t01 :
< p0 val = dot
< p1 val = 1
> p2 val = 2
# variables
trans t02 x > 0 :
< p0 val = dot
< p1 var = x
> p2 var = x
# input multiarc, expressions
trans t03 x != y :
< p0 val = dot
< p1 var = x
< p1 var = y
> p2 expr = x+y
# input expressions
trans t04 x > 0 :
< p0 val = dot
< p1 var = x
< p1 expr = x+1
> p2 expr = x+2
# output multiarc, expressions reuse, untyped output
trans t05 x != y :
< p0 val = dot
< p1 var = x
< p1 var = y
< p1 expr = abs(x - y)
> p2 var = x
> p2 expr = y+1
> p3 expr = abs(x - y)
# test on input
trans t06 x != y :
< p0 val = dot
< p1 var = x
< p2 ?var = y
> p3 expr = x+y
# test on input multiarc
trans t07 x != y :
< p0 val = dot
< p1 var = x
< p1 ?var = y
> p3 expr = x+y
# only test inputs
trans t08 x != y :
< p0 val = dot
< p1 ?var = x
< p2 ?var = y
> p3 expr = x+y
# only tests in input multiarc
trans t09 x != y :
< p0 val = dot
< p1 ?var = x
< p1 ?var = y
> p3 expr = x+y
# test on output
trans t10 x != y :
< p0 val = dot
< p1 var = x
< p2 var = y
> p3 ?expr = x+y
# flush and fill arcs
trans t11 m.len() > 0 :
< p0 val = dot
< p1 flush = m
< p3 flush+ = n
> p2 fill = m.copy().add(n)
# test flush and test fill
trans t12 m.len() > 0 :
< p0 val = dot
< p1 ?flush = m
> p2 ?fill = m.copy().add(m)
# multiarc fill
trans t13 m.len() > 0 :
< p0 val = dot
< p1 flush = m
> p1 fill = m
> p1 fill = (x+1 for x in m)
# inhibitor value
trans t14 :
< p0 val = dot
< p1 !val = 1
> p2 val = 2
# inhibitor variable
trans t15 :
< p0 val = dot
< p1 var = x
< p2 ![y<x]var = y
> p3 val = 2
# inhibitor expression
trans t16 :
< p0 val = dot
< p1 var = x
< p2 !expr = x+1
> p3 val = 2
# tuples
place p5 (Number, Number)
place p6 (String, (Number, Number), Boolean)
# input/output and nested
trans t17 :
< p0 val = dot
< p5 (var, var) = (x, y)
< p6 (var, (var, var), var) = (z, (x, y), b)
> p6 (expr, (var, var), expr) = (["#{x}+#{y}"], (x, y), {x==y})
# partially matched tuples
trans t18 :
< p0 val = dot
< p5 var = x
> p6 (expr, var, expr) = (["#{x}"], x, {max(x...)>0})
# tests
trans t19 :
< p0 val = dot
< p5 ?(var, val) = (x, 0)
> p6 ?(var, expr, val) = (x, {[x+1, x]}, true)
# multiarc
trans t20 :
< p0 val = dot
< p5 (var, val) = (x, 0)
< p5 var = y
> p6 (expr, var, val) = (["#{x}"], y, true)
> p6 (expr, (var, expr), val) = (["#{x}"], (x, {x-1}), true)
# inhibitor
trans t22 :
< p0 val = dot
< p5 !(var, val) = (x, 0)