diff --git a/testdata/connector/duo/1.apdl b/testdata/connector/duo/1.apdl new file mode 100644 index 0000000000000000000000000000000000000000..8eab469cf3ef8f6833122305f02e61df3d1c733c --- /dev/null +++ b/testdata/connector/duo/1.apdl @@ -0,0 +1,23 @@ +// Network Topology: +// two nodes, a and b, and two channels +// Node a: +// Two ports, a0 and a1, where a0 is passive and a1 is active +// Node b: +// Two ports, b0 and b1, where b0 is active and b1 is passive +// Channel a0--b0, where b0 initiates +// Channel a1--b1, where a1 initiates + +primitive main(in a0, in a1) { + while (true) { + synchronous { + if (fires(a0)) { + msg x = get(a0); + } + } + synchronous { + if (fires(a1)) { + msg y = get(a1); + } + } + } +} \ No newline at end of file diff --git a/testdata/connector/duo/1.bpdl b/testdata/connector/duo/1.bpdl new file mode 100644 index 0000000000000000000000000000000000000000..6a77860c3aa8030a626cf8cca60790d185e411f1 --- /dev/null +++ b/testdata/connector/duo/1.bpdl @@ -0,0 +1,25 @@ +// Network Topology: +// two nodes, a and b, and two channels +// Node a: +// Two ports, a0 and a1, where a0 is passive and a1 is active +// Node b: +// Two ports, b0 and b1, where b0 is active and b1 is passive +// Channel a0--b0, where b0 initiates +// Channel a1--b1, where a1 initiates + +primitive main(out b0, out b1) { + synchronous {} + synchronous {} + synchronous { + msg x = create(0); + put(b0, x); + } + synchronous {} + synchronous { + msg y = create(0); + put(b1, y); + } + while (true) { + synchronous {} + } +} \ No newline at end of file diff --git a/testdata/eval/positive/1.pdl b/testdata/eval/positive/1.pdl new file mode 100644 index 0000000000000000000000000000000000000000..4259004f787203b44a41ab6f49b7d3faa2a5a3ae --- /dev/null +++ b/testdata/eval/positive/1.pdl @@ -0,0 +1,9 @@ +#version 100 + +composite main() {} + +int test() { + int x = 5; + x++; + return x; +} \ No newline at end of file diff --git a/testdata/eval/positive/1.txt b/testdata/eval/positive/1.txt new file mode 100644 index 0000000000000000000000000000000000000000..62f9457511f879886bb7728c986fe10b0ece6bcb --- /dev/null +++ b/testdata/eval/positive/1.txt @@ -0,0 +1 @@ +6 \ No newline at end of file diff --git a/testdata/eval/positive/2.pdl b/testdata/eval/positive/2.pdl new file mode 100644 index 0000000000000000000000000000000000000000..681755ccbd90b04470a775ae7832e94f94ec4533 --- /dev/null +++ b/testdata/eval/positive/2.pdl @@ -0,0 +1,12 @@ +#version 100 + +composite main() {} + +int test() { + int x = 5; + if (x < 5) { + x = --x; + } + x++; + return x; +} \ No newline at end of file diff --git a/testdata/eval/positive/2.txt b/testdata/eval/positive/2.txt new file mode 100644 index 0000000000000000000000000000000000000000..62f9457511f879886bb7728c986fe10b0ece6bcb --- /dev/null +++ b/testdata/eval/positive/2.txt @@ -0,0 +1 @@ +6 \ No newline at end of file diff --git a/testdata/eval/positive/3.pdl b/testdata/eval/positive/3.pdl new file mode 100644 index 0000000000000000000000000000000000000000..fd442115c3c35db488ba0c5c4554b589d4a73104 --- /dev/null +++ b/testdata/eval/positive/3.pdl @@ -0,0 +1,13 @@ +#version 100 + +composite main() {} + +int test() { + int x = 5; + if (x >= 5) { // true + int y = 2; + x -= --y; // --y is 1, so x -= 1 results in 4 + } + x++; // becomes 5 + return x; +} \ No newline at end of file diff --git a/testdata/eval/positive/3.txt b/testdata/eval/positive/3.txt new file mode 100644 index 0000000000000000000000000000000000000000..7813681f5b41c028345ca62a2be376bae70b7f61 --- /dev/null +++ b/testdata/eval/positive/3.txt @@ -0,0 +1 @@ +5 \ No newline at end of file diff --git a/testdata/eval/positive/4.pdl b/testdata/eval/positive/4.pdl new file mode 100644 index 0000000000000000000000000000000000000000..b085c1e190fc0b5055c3f83c27036321c2adc923 --- /dev/null +++ b/testdata/eval/positive/4.pdl @@ -0,0 +1,12 @@ +#version 100 + +composite main() {} + +int test() { + int x = 5; + while (x < 10) { + x += 2; + if (x == 10) return x; // never taken + } + return x; +} \ No newline at end of file diff --git a/testdata/eval/positive/4.txt b/testdata/eval/positive/4.txt new file mode 100644 index 0000000000000000000000000000000000000000..9d607966b721abde8931ddd052181fae905db503 --- /dev/null +++ b/testdata/eval/positive/4.txt @@ -0,0 +1 @@ +11 \ No newline at end of file diff --git a/testdata/eval/positive/5.pdl b/testdata/eval/positive/5.pdl new file mode 100644 index 0000000000000000000000000000000000000000..1642e91304f0d026f706663e59e1e3fca896f4e2 --- /dev/null +++ b/testdata/eval/positive/5.pdl @@ -0,0 +1,19 @@ +#version 100 + +composite main() {} + +int test() { + int x = 5; +l: while (x < 10) { + if (x % 2 == 0) { + x += 1; // if even, add one, making it odd + } else { + x += 3; // if odd, add three, making it even + } + } + if (x > 10) { + x -= 10; // keep under 10 + goto l; + } + return x; +} \ No newline at end of file diff --git a/testdata/eval/positive/5.txt b/testdata/eval/positive/5.txt new file mode 100644 index 0000000000000000000000000000000000000000..9a037142aa3c1b4c490e1a38251620f113465330 --- /dev/null +++ b/testdata/eval/positive/5.txt @@ -0,0 +1 @@ +10 \ No newline at end of file diff --git a/testdata/eval/positive/6.pdl b/testdata/eval/positive/6.pdl new file mode 100644 index 0000000000000000000000000000000000000000..aa7186ef07c9aebf79a3657c590158d42eb47af6 --- /dev/null +++ b/testdata/eval/positive/6.pdl @@ -0,0 +1,13 @@ +#version 100 + +composite main() {} + +int test() { + msg x = create(5); + x[0] = 1; + x[1] = 2; + x[2] = 3; + x[3] = 4; + x[4] = 5; + return x; +} \ No newline at end of file diff --git a/testdata/eval/positive/6.txt b/testdata/eval/positive/6.txt new file mode 100644 index 0000000000000000000000000000000000000000..16e83a29e649922efaf0950ebfbb40e7e8fe54f1 --- /dev/null +++ b/testdata/eval/positive/6.txt @@ -0,0 +1 @@ +#msg(5;1,2,3,4,5) \ No newline at end of file diff --git a/testdata/parser/negative/1.pdl b/testdata/parser/negative/1.pdl new file mode 100644 index 0000000000000000000000000000000000000000..4f0fafc1f9d3ade96980f3dd09e93b65e97225e7 --- /dev/null +++ b/testdata/parser/negative/1.pdl @@ -0,0 +1,10 @@ +#version 100 + +// sync block nested twice in primitive +primitive main(in a, out b) { + while (true) { + synchronous { + synchronous {} + } + } +} diff --git a/testdata/parser/negative/1.txt b/testdata/parser/negative/1.txt new file mode 100644 index 0000000000000000000000000000000000000000..c058a7760693fbb6d6d4dc63b4f34c4b8de76e8c --- /dev/null +++ b/testdata/parser/negative/1.txt @@ -0,0 +1,3 @@ +Parse error at 1.pdl:7:4: Illegal nested synchronous statement + synchronous {} + ^ diff --git a/testdata/parser/negative/10.pdl b/testdata/parser/negative/10.pdl new file mode 100644 index 0000000000000000000000000000000000000000..60a8f81d01887a82d29e983b883efae781be3da4 --- /dev/null +++ b/testdata/parser/negative/10.pdl @@ -0,0 +1,14 @@ +#version 100 + +// sync block nested in sync block +primitive main(in a, out b) { + while (true) { + synchronous { + if (false || true) { + synchronous { + skip; + } + } + } + } +} diff --git a/testdata/parser/negative/10.txt b/testdata/parser/negative/10.txt new file mode 100644 index 0000000000000000000000000000000000000000..439a71d657dd786f5f5f8f14e75563f06360d437 --- /dev/null +++ b/testdata/parser/negative/10.txt @@ -0,0 +1,3 @@ +Parse error at 10.pdl:8:5: Illegal nested synchronous statement + synchronous { + ^ diff --git a/testdata/parser/negative/12.pdl b/testdata/parser/negative/12.pdl new file mode 100644 index 0000000000000000000000000000000000000000..049b2b4539efcd49d3a04651aa5be79336571e3d --- /dev/null +++ b/testdata/parser/negative/12.pdl @@ -0,0 +1,9 @@ +#version 100 + +// illegal node declaration +primitive main(in a, out b) { + while (true) { + channel x -> y; + synchronous {} + } +} diff --git a/testdata/parser/negative/12.txt b/testdata/parser/negative/12.txt new file mode 100644 index 0000000000000000000000000000000000000000..20ad8c4be5e80c3022c57c4783a34c7709dd9c77 --- /dev/null +++ b/testdata/parser/negative/12.txt @@ -0,0 +1,3 @@ +Parse error at 12.pdl:6:3: Illegal channel delcaration + channel x -> y; + ^ diff --git a/testdata/parser/negative/13.pdl b/testdata/parser/negative/13.pdl new file mode 100644 index 0000000000000000000000000000000000000000..cde45e52b256e23b8a7fd07ea66fa353267514a9 --- /dev/null +++ b/testdata/parser/negative/13.pdl @@ -0,0 +1,20 @@ +#version 100 + +// function statement must return +int myfun(int x) { + if (x > 0) { + while (x > 0) { + x--; + if (x == 0) skip; // illegal! + else return x; + } + } else { + int y = 0; +label: if (y >= 0) { + goto label; + } else { + y = 5; + return myfun(x + 1); + } + } +} diff --git a/testdata/parser/negative/13.txt b/testdata/parser/negative/13.txt new file mode 100644 index 0000000000000000000000000000000000000000..e3dc7b18f329a5303a00270962226dc2c67e6f25 --- /dev/null +++ b/testdata/parser/negative/13.txt @@ -0,0 +1,3 @@ +Parse error at 13.pdl:8:16: Function definition must return + if (x == 0) skip; // illegal! + ^ diff --git a/testdata/parser/negative/14.pdl b/testdata/parser/negative/14.pdl new file mode 100644 index 0000000000000000000000000000000000000000..9d9074ee79de1035911d73b683ed6dc97a3d391f --- /dev/null +++ b/testdata/parser/negative/14.pdl @@ -0,0 +1,7 @@ +#version 100 + +// illegal builtin +composite main(in a, out b) { + int x = get(a); + skip; +} \ No newline at end of file diff --git a/testdata/parser/negative/14.txt b/testdata/parser/negative/14.txt new file mode 100644 index 0000000000000000000000000000000000000000..c6f809c03644be0ae111bc83b2592f2e2b0823c9 --- /dev/null +++ b/testdata/parser/negative/14.txt @@ -0,0 +1,3 @@ +Parse error at 14.pdl:5:10: Illegal built-in occurrence + int x = get(a); + ^ diff --git a/testdata/parser/negative/17.pdl b/testdata/parser/negative/17.pdl new file mode 100644 index 0000000000000000000000000000000000000000..28b1bd0f9f9ebd0b8ea3870edc4c37851a591e3a --- /dev/null +++ b/testdata/parser/negative/17.pdl @@ -0,0 +1,8 @@ +#version 100 + +// illegal assignment +primitive main(in a, out b) { + int x = 0; + int y = 0; + x + y = 0; +} \ No newline at end of file diff --git a/testdata/parser/negative/17.txt b/testdata/parser/negative/17.txt new file mode 100644 index 0000000000000000000000000000000000000000..a900a293c64892c8ad668d72471ad85d1a6a420d --- /dev/null +++ b/testdata/parser/negative/17.txt @@ -0,0 +1,3 @@ +Parse error at 17.pdl:7:4: Unassignable expression + x + y = 0; + ^ diff --git a/testdata/parser/negative/18.pdl b/testdata/parser/negative/18.pdl new file mode 100644 index 0000000000000000000000000000000000000000..a49586c8dad897d6180d6c8c6fb12ba8728a4166 --- /dev/null +++ b/testdata/parser/negative/18.pdl @@ -0,0 +1,8 @@ +#version 100 + +// illegal subject +primitive main(in a, out b) { + int x = 0; + int[] y = {x, x, x}; + y[0] = (x+y)[0]; +} \ No newline at end of file diff --git a/testdata/parser/negative/18.txt b/testdata/parser/negative/18.txt new file mode 100644 index 0000000000000000000000000000000000000000..ada41541886229d2f5b288bfda713d5c92eaf328 --- /dev/null +++ b/testdata/parser/negative/18.txt @@ -0,0 +1,3 @@ +Parse error at 18.pdl:7:11: Unindexable expression + y[0] = (x+y)[0]; + ^ diff --git a/testdata/parser/negative/19.pdl b/testdata/parser/negative/19.pdl new file mode 100644 index 0000000000000000000000000000000000000000..66a30eed35ce366e127cde061aefad4d89bc8336 --- /dev/null +++ b/testdata/parser/negative/19.pdl @@ -0,0 +1,13 @@ +#version 100 + +primitive main(in a) { + while (true) { + synchronous { + if (fires(a)) { + return 5; + } else { + block(a); + } + } + } +} \ No newline at end of file diff --git a/testdata/parser/negative/19.txt b/testdata/parser/negative/19.txt new file mode 100644 index 0000000000000000000000000000000000000000..aa5cb7039c66681204d2465a399bb6bdc03c2f6d --- /dev/null +++ b/testdata/parser/negative/19.txt @@ -0,0 +1,3 @@ +Parse error at 19.pdl:7:5: Component definition must not return + return 5; + ^ diff --git a/testdata/parser/negative/2.pdl b/testdata/parser/negative/2.pdl new file mode 100644 index 0000000000000000000000000000000000000000..f23f1298b182c2f01b0be40ba8127f3a8d3c0b31 --- /dev/null +++ b/testdata/parser/negative/2.pdl @@ -0,0 +1,10 @@ +#version 100 + +// duplicate procedures +composite main(in a, out b) { + id(a, d); +} + +primitive main(in a, out b) { + skip; +} diff --git a/testdata/parser/negative/2.txt b/testdata/parser/negative/2.txt new file mode 100644 index 0000000000000000000000000000000000000000..8c7f4e2082d58c59766c74d920fbcb7002c9b0c2 --- /dev/null +++ b/testdata/parser/negative/2.txt @@ -0,0 +1,3 @@ +Parse error at 2.pdl:8:1: Defined symbol clash: main +primitive main(in a, out b) { +^ diff --git a/testdata/parser/negative/20.pdl b/testdata/parser/negative/20.pdl new file mode 100644 index 0000000000000000000000000000000000000000..5b840e4fa1506b1b76ea3230c61ea2db69ff3c71 --- /dev/null +++ b/testdata/parser/negative/20.pdl @@ -0,0 +1,7 @@ +#version 100 + +primitive main(in a) { + int[] x = {1,2,3}; + x[1] = (x[0] < x[2] ? x[1:2] : x[0:1])[0:0][0]; + x[1] = x[1][0:1]; +} \ No newline at end of file diff --git a/testdata/parser/negative/20.txt b/testdata/parser/negative/20.txt new file mode 100644 index 0000000000000000000000000000000000000000..41f6d4d1d7e99f9f2719619dab57624c85068f43 --- /dev/null +++ b/testdata/parser/negative/20.txt @@ -0,0 +1,3 @@ +Parse error at 20.pdl:6:10: Unindexable expression + x[1] = x[1][0:1]; + ^ diff --git a/testdata/parser/negative/22.pdl b/testdata/parser/negative/22.pdl new file mode 100644 index 0000000000000000000000000000000000000000..6c5aca60684cad2332ecb0cf383b993e055fdf9a --- /dev/null +++ b/testdata/parser/negative/22.pdl @@ -0,0 +1,14 @@ +#version 100 + +int main(int a) { +dupl: + while (a >= 2) { + a -= 2; +dupl: while (a < 10) { + a++; + if (a % 5 == 0) + break dupl; + } + } + goto dupl; +} \ No newline at end of file diff --git a/testdata/parser/negative/22.txt b/testdata/parser/negative/22.txt new file mode 100644 index 0000000000000000000000000000000000000000..2256dd6e96da539dd0930ae936e867af55dff358 --- /dev/null +++ b/testdata/parser/negative/22.txt @@ -0,0 +1,3 @@ +Parse error at 22.pdl:7:1: Duplicate label +dupl: while (a < 10) { +^ diff --git a/testdata/parser/negative/23.pdl b/testdata/parser/negative/23.pdl new file mode 100644 index 0000000000000000000000000000000000000000..a737914568840c723779867c487a772d09b7ee19 --- /dev/null +++ b/testdata/parser/negative/23.pdl @@ -0,0 +1,14 @@ +#version 100 + +int main(int a) { +outer: + while (a >= 2) { + a -= 2; + while (a < 10) { +unreach: a++; + if (a % 5 == 0) + break outer; + } + } + goto unreach; +} \ No newline at end of file diff --git a/testdata/parser/negative/23.txt b/testdata/parser/negative/23.txt new file mode 100644 index 0000000000000000000000000000000000000000..820e916998e4112ddc422f41bc41c2a633ec3fd4 --- /dev/null +++ b/testdata/parser/negative/23.txt @@ -0,0 +1,3 @@ +Parse error at 23.pdl:13:7: Unresolved label + goto unreach; + ^ diff --git a/testdata/parser/negative/24.pdl b/testdata/parser/negative/24.pdl new file mode 100644 index 0000000000000000000000000000000000000000..aa44bdda2068eb610250dd1932822fa70c0b8afa --- /dev/null +++ b/testdata/parser/negative/24.pdl @@ -0,0 +1,14 @@ +#version 100 + +primitive main(in a, out b) { + int x = 0; + int y = 0; + x += y + 5; + y %= x -= 3; + x *= x * x *= 5; + while (true) { + synchronous { + assert fires(a) == fires(b); + } + } +} \ No newline at end of file diff --git a/testdata/parser/negative/24.txt b/testdata/parser/negative/24.txt new file mode 100644 index 0000000000000000000000000000000000000000..5b99ecbf434acc3a8979524a0f480d748a081745 --- /dev/null +++ b/testdata/parser/negative/24.txt @@ -0,0 +1,3 @@ +Parse error at 24.pdl:8:9: Unassignable expression + x *= x * x *= 5; + ^ diff --git a/testdata/parser/negative/25.pdl b/testdata/parser/negative/25.pdl new file mode 100644 index 0000000000000000000000000000000000000000..621eb43c219cf9628496e49592b7f9a3ca8178e6 --- /dev/null +++ b/testdata/parser/negative/25.pdl @@ -0,0 +1,11 @@ +#version 100 + +primitive main(in a, out b) { + int x = 0; + int y = 0; + while (true) { + synchronous (int x) { // illegal + assert fires(a) == fires(b); + } + } +} \ No newline at end of file diff --git a/testdata/parser/negative/25.txt b/testdata/parser/negative/25.txt new file mode 100644 index 0000000000000000000000000000000000000000..770f8b706322074a3e9111379e93ff6092545d22 --- /dev/null +++ b/testdata/parser/negative/25.txt @@ -0,0 +1,3 @@ +Parse error at 25.pdl:7:20: Declared variable clash + synchronous (int x) { // illegal + ^ diff --git a/testdata/parser/negative/26.pdl b/testdata/parser/negative/26.pdl new file mode 100644 index 0000000000000000000000000000000000000000..315fce8008e1edf815c0bd483e20e9b2cd3cbfb5 --- /dev/null +++ b/testdata/parser/negative/26.pdl @@ -0,0 +1,5 @@ +#version 100 + +primitive main(in a, out b) { + break; // illegal +} \ No newline at end of file diff --git a/testdata/parser/negative/26.txt b/testdata/parser/negative/26.txt new file mode 100644 index 0000000000000000000000000000000000000000..d878e6e726cb65f38f61ae8d5b7079166b9dd0fb --- /dev/null +++ b/testdata/parser/negative/26.txt @@ -0,0 +1,3 @@ +Parse error at 26.pdl:4:2: Illegal break: no surrounding while statement + break; // illegal + ^ diff --git a/testdata/parser/negative/27.pdl b/testdata/parser/negative/27.pdl new file mode 100644 index 0000000000000000000000000000000000000000..b6ac49ea5828439c3d5e97afdb39073f6756312c --- /dev/null +++ b/testdata/parser/negative/27.pdl @@ -0,0 +1,15 @@ +#version 100 + +int main(int a) { + while (a >= 2) { + a -= 2; +dupl: while (a < 10) { + a++; + if (a % 5 == 0) + break dupl; + } + } + skip; +dupl: + while (true) goto dupl; +} \ No newline at end of file diff --git a/testdata/parser/negative/27.txt b/testdata/parser/negative/27.txt new file mode 100644 index 0000000000000000000000000000000000000000..2d77c49e26197b389c54f6514875a7b277a3c2ce --- /dev/null +++ b/testdata/parser/negative/27.txt @@ -0,0 +1,3 @@ +Parse error at 27.pdl:6:1: Duplicate label +dupl: while (a < 10) { +^ diff --git a/testdata/parser/negative/28.pdl b/testdata/parser/negative/28.pdl new file mode 100644 index 0000000000000000000000000000000000000000..b88d510225d8e269a2d0ca02e22d4f15fdcca56b --- /dev/null +++ b/testdata/parser/negative/28.pdl @@ -0,0 +1,7 @@ +#version 100 + +int main(int a) { + int x = 0; + (x + 5)++; // not assignable + return x; +} \ No newline at end of file diff --git a/testdata/parser/negative/28.txt b/testdata/parser/negative/28.txt new file mode 100644 index 0000000000000000000000000000000000000000..89580285f2fba602ae3df5d471ab293c29481eee --- /dev/null +++ b/testdata/parser/negative/28.txt @@ -0,0 +1,3 @@ +Parse error at 28.pdl:5:8: Unassignable expression + (x + 5)++; // not assignable + ^ diff --git a/testdata/parser/negative/29.pdl b/testdata/parser/negative/29.pdl new file mode 100644 index 0000000000000000000000000000000000000000..1c28e137265c80749520d69f5a826dbab096e289 --- /dev/null +++ b/testdata/parser/negative/29.pdl @@ -0,0 +1,7 @@ +#version 100 + +int main(int a) { + int[] x = {}; + ++(x[0..5][2 - x[0]].length); // not assignable + return x; +} \ No newline at end of file diff --git a/testdata/parser/negative/29.txt b/testdata/parser/negative/29.txt new file mode 100644 index 0000000000000000000000000000000000000000..9cc1cc21214d0c4045d2dd959c1fb5727e5bf4b6 --- /dev/null +++ b/testdata/parser/negative/29.txt @@ -0,0 +1,3 @@ +Parse error at 29.pdl:5:25: Unassignable expression + ++(x[0..5][2 - x[0]].length); // not assignable + ^ diff --git a/testdata/parser/negative/3.pdl b/testdata/parser/negative/3.pdl new file mode 100644 index 0000000000000000000000000000000000000000..67caa9d0a862f387cb25a7d1c04c81df7eead3c3 --- /dev/null +++ b/testdata/parser/negative/3.pdl @@ -0,0 +1,11 @@ +#version 100 + +// sync block nested deeply in composite +composite main(in a, out b) { + channel x -> y; + while (true) { + synchronous { + skip; + } + } +} diff --git a/testdata/parser/negative/3.txt b/testdata/parser/negative/3.txt new file mode 100644 index 0000000000000000000000000000000000000000..010dcbaa770c39d19aa5ad9b8d20902b4ba12a62 --- /dev/null +++ b/testdata/parser/negative/3.txt @@ -0,0 +1,3 @@ +Parse error at 3.pdl:7:3: Illegal nested synchronous statement + synchronous { + ^ diff --git a/testdata/parser/negative/30.pdl b/testdata/parser/negative/30.pdl new file mode 100644 index 0000000000000000000000000000000000000000..a10bd74e391efaacb23153c4083b9a84144dc3fc --- /dev/null +++ b/testdata/parser/negative/30.pdl @@ -0,0 +1,7 @@ +#version 100 + +int main(int a) { + int x = 5; + int y = x + 5; + int z = z; // now allowed +} \ No newline at end of file diff --git a/testdata/parser/negative/30.txt b/testdata/parser/negative/30.txt new file mode 100644 index 0000000000000000000000000000000000000000..171946064e34d086b770e427e4826d84174f424f --- /dev/null +++ b/testdata/parser/negative/30.txt @@ -0,0 +1,3 @@ +Parse error at 30.pdl:6:13: Unresolved variable + int z = z; // now allowed + ^ diff --git a/testdata/parser/negative/31.pdl b/testdata/parser/negative/31.pdl new file mode 100644 index 0000000000000000000000000000000000000000..d4aa9911681b1145e612483995e90856766bca56 --- /dev/null +++ b/testdata/parser/negative/31.pdl @@ -0,0 +1,9 @@ +#version 100 + +primitive main(int a) { + while (true) { + synchronous { + break; // not allowed + } + } +} \ No newline at end of file diff --git a/testdata/parser/negative/31.txt b/testdata/parser/negative/31.txt new file mode 100644 index 0000000000000000000000000000000000000000..12a2a31ea40959e7d0475f821c0b272877b00deb --- /dev/null +++ b/testdata/parser/negative/31.txt @@ -0,0 +1,3 @@ +Parse error at 31.pdl:6:13: Illegal break: synchronous statement escape + break; // not allowed + ^ diff --git a/testdata/parser/negative/32.pdl b/testdata/parser/negative/32.pdl new file mode 100644 index 0000000000000000000000000000000000000000..0d9cecc51e6e4f4019b88889b6714e6cc64a7c30 --- /dev/null +++ b/testdata/parser/negative/32.pdl @@ -0,0 +1,9 @@ +#version 100 + +primitive main(int a) { + loop: { + synchronous { + goto loop; // not allowed + } + } +} \ No newline at end of file diff --git a/testdata/parser/negative/32.txt b/testdata/parser/negative/32.txt new file mode 100644 index 0000000000000000000000000000000000000000..84200c1aa116144af914299e0a5e85bf7043863d --- /dev/null +++ b/testdata/parser/negative/32.txt @@ -0,0 +1,3 @@ +Parse error at 32.pdl:6:13: Illegal goto: synchronous statement escape + goto loop; // not allowed + ^ diff --git a/testdata/parser/negative/4.pdl b/testdata/parser/negative/4.pdl new file mode 100644 index 0000000000000000000000000000000000000000..bf323606bd952b1d97999d4a9f14d35e1e4bfadc --- /dev/null +++ b/testdata/parser/negative/4.pdl @@ -0,0 +1,13 @@ +#version 100 + +// built-in outside sync block +primitive main(in a, out b) { + int x = 0; + msg y = create(0); // legal + while (x < 10) { + y = get(a); // illegal + synchronous { + y = get(a); // legal + } + } +} diff --git a/testdata/parser/negative/4.txt b/testdata/parser/negative/4.txt new file mode 100644 index 0000000000000000000000000000000000000000..b79ed8d04631163e22ac00d574020f8de1ad9de4 --- /dev/null +++ b/testdata/parser/negative/4.txt @@ -0,0 +1,3 @@ +Parse error at 4.pdl:8:7: Illegal built-in occurrence + y = get(a); // illegal + ^ diff --git a/testdata/parser/negative/5.pdl b/testdata/parser/negative/5.pdl new file mode 100644 index 0000000000000000000000000000000000000000..555829b8c5f225b6b63eff1081b3749dab0645db --- /dev/null +++ b/testdata/parser/negative/5.pdl @@ -0,0 +1,6 @@ +#version 100 + +// unresolved component +composite main(in a, out b) { + sync(a, b); +} diff --git a/testdata/parser/negative/5.txt b/testdata/parser/negative/5.txt new file mode 100644 index 0000000000000000000000000000000000000000..291dfac63f7640267cda53743c24a2494059f3d1 --- /dev/null +++ b/testdata/parser/negative/5.txt @@ -0,0 +1,3 @@ +Parse error at 5.pdl:5:2: Unresolved method + sync(a, b); + ^ diff --git a/testdata/parser/negative/6.pdl b/testdata/parser/negative/6.pdl new file mode 100644 index 0000000000000000000000000000000000000000..7f523a40d6a8bf1b7912888956be1a8da25803c6 --- /dev/null +++ b/testdata/parser/negative/6.pdl @@ -0,0 +1,8 @@ +#version 100 + +import std.reo; + +// duplicate formal parameters +composite main(in a, out a) { + new sync(a, a); +} diff --git a/testdata/parser/negative/6.txt b/testdata/parser/negative/6.txt new file mode 100644 index 0000000000000000000000000000000000000000..ad0990bd36ea84ed546ff9df09b8d40b3f1e4ef1 --- /dev/null +++ b/testdata/parser/negative/6.txt @@ -0,0 +1,3 @@ +Parse error at 6.pdl:6:26: Declared variable clash +composite main(in a, out a) { + ^ diff --git a/testdata/parser/negative/7.pdl b/testdata/parser/negative/7.pdl new file mode 100644 index 0000000000000000000000000000000000000000..b37b28604db2ba82798625f4cbcb04ca35b8f69f --- /dev/null +++ b/testdata/parser/negative/7.pdl @@ -0,0 +1,9 @@ +#version 100 + +import std.reo; + +// shadowing formal parameter +composite main(in a, out b) { + channel c -> a; + new sync(a, b); +} diff --git a/testdata/parser/negative/7.txt b/testdata/parser/negative/7.txt new file mode 100644 index 0000000000000000000000000000000000000000..b70d27ae99446d727ad7a7e73e7911f51ff07ccd --- /dev/null +++ b/testdata/parser/negative/7.txt @@ -0,0 +1,3 @@ +Parse error at 7.pdl:7:15: Declared variable clash + channel c -> a; + ^ diff --git a/testdata/parser/negative/8.pdl b/testdata/parser/negative/8.pdl new file mode 100644 index 0000000000000000000000000000000000000000..af9f36c5b48055bad30484961575675acaa8a77c --- /dev/null +++ b/testdata/parser/negative/8.pdl @@ -0,0 +1,20 @@ +#version 100 + +import std.reo; + +composite main(in a, out b) { + channel c -> d; + syncdrain(a, b); +} + +// shadowing import +primitive syncdrain(in a, in b) { + while (true) { + synchronous { + if (!fires(a) || !fires(b)) { + block(a); + block(b); + } + } + } +} diff --git a/testdata/parser/negative/8.txt b/testdata/parser/negative/8.txt new file mode 100644 index 0000000000000000000000000000000000000000..dcd940f242d739124eae55dd86db74510fff1943 --- /dev/null +++ b/testdata/parser/negative/8.txt @@ -0,0 +1,3 @@ +Parse error at 8.pdl:11:1: Defined symbol clash: syncdrain +primitive syncdrain(in a, in b) { +^ diff --git a/testdata/parser/negative/9.pdl b/testdata/parser/negative/9.pdl new file mode 100644 index 0000000000000000000000000000000000000000..8d39b6ae5ffaaed68173748de342f266cae9599e --- /dev/null +++ b/testdata/parser/negative/9.pdl @@ -0,0 +1,9 @@ +#version 100 + +// node declaration deeply nested in primitive +primitive main(in a, out b) { + while (true) { + channel yo -> yi; + skip; + } +} diff --git a/testdata/parser/negative/9.txt b/testdata/parser/negative/9.txt new file mode 100644 index 0000000000000000000000000000000000000000..96c258e43b702a2806a73fc182ca7b2de70cd214 --- /dev/null +++ b/testdata/parser/negative/9.txt @@ -0,0 +1,3 @@ +Parse error at 9.pdl:6:3: Illegal channel delcaration + channel yo -> yi; + ^ diff --git a/testdata/parser/positive/1.pdl b/testdata/parser/positive/1.pdl new file mode 100644 index 0000000000000000000000000000000000000000..9e88a779636f927945eae0fd3a4ed04379deac03 --- /dev/null +++ b/testdata/parser/positive/1.pdl @@ -0,0 +1,93 @@ +#version 100 + +composite main(in asend, out arecv, in bsend, out brecv) { + channel xo -> xi; + channel yo -> yi; + new replicator(asend, xo, brecv); + new replicator(bsend, yo, arecv); + // x fires first, then y, then x, et cetera + new sequencer(xi, yi); +} + +primitive replicator(in a, out b, out c) { + while (true) { + synchronous { + if (fires(a) && fires(b) && fires(c)) { + msg x = get(a); + put(b, x); + put(c, x); + } else { + assert !fires(a) && !fires(b) && !fires(c); + } + } + } +} + +composite sequencer(in x, in y) { + channel ao -> ai; + channel bo -> bi; + channel co -> ci; + channel do -> di; + channel eo -> ei; + channel fo -> fi; + new syncdrain(x, ai); + new syncdrain(y, bi); + new replicator(ei, ao, co); + new replicator(fi, bo, do); + new fifo(ci, fo, null); + new fifo(di, eo, create(0)); +} + +primitive syncdrain(in a, in b) { + while (true) { + synchronous { + if (fires(a) && fires(b)) { + get(a); + get(b); + } else { + assert !fires(a) && !fires(b); + } + } + } +} + +primitive fifo(in a, out b, msg init) { + msg c = init; + while (true) { + synchronous { + if (c != null) { + assert !fires(a); + if (fires(b)) { + put(b, c); + c = null; + } + } else { + assert !fires(b); + if (fires(a)) { + c = get(a); + } + } + } + } +} + +primitive sequencer2(in x, in y) { + while (true) { + boolean b = false; + while (!b) { + synchronous { + assert !fires(y); + if (fires(x)) + b = true; + } + } + b = false; + while (!b) { + synchronous { + assert !fires(x); + if (fires(y)) + b = true; + } + } + } +} diff --git a/testdata/parser/positive/10.pdl b/testdata/parser/positive/10.pdl new file mode 100644 index 0000000000000000000000000000000000000000..0c5d30773f0a2016c9910948ff7b9de81e2c4cb2 --- /dev/null +++ b/testdata/parser/positive/10.pdl @@ -0,0 +1,27 @@ +#version 100 + +composite main() {} + +primitive example(in a, out[] b) { + while (true) { + synchronous { + if (fires(a)) { + int i = 0; + while (i < b.length) { + if (fires(b[i])) { + int j = i + 1; + while (j < b.length) + assert !fires(b[j++]); + break; + } + i++; + } + assert i < b.length; + } else { + int i = 0; + while (i < b.length) + assert !fires(b[i++]); + } + } + } +} \ No newline at end of file diff --git a/testdata/parser/positive/11.pdl b/testdata/parser/positive/11.pdl new file mode 100644 index 0000000000000000000000000000000000000000..43fea6c6c4c47556c13694ea8a084d31ce21be93 --- /dev/null +++ b/testdata/parser/positive/11.pdl @@ -0,0 +1,17 @@ +#version 100 + +primitive main(in a, out b) { + msg x = null; + while (x == null) { + synchronous { + if (fires(a)) + x = get(a); + } + } + while (true) { + synchronous { + if (fires(b)) + put(b, x); + } + } +} \ No newline at end of file diff --git a/testdata/parser/positive/12.pdl b/testdata/parser/positive/12.pdl new file mode 100644 index 0000000000000000000000000000000000000000..1ac91cd80217398a5d0b89f821a4a03c521ff563 --- /dev/null +++ b/testdata/parser/positive/12.pdl @@ -0,0 +1,14 @@ +#version 100 + +primitive main(in a, out b) { + int x = 0; + int y = 0; + x += y + 5; + y %= x -= 3; + x *= x * (x *= 5); + while (true) { + synchronous { + assert fires(a) == fires(b); + } + } +} \ No newline at end of file diff --git a/testdata/parser/positive/13.pdl b/testdata/parser/positive/13.pdl new file mode 100644 index 0000000000000000000000000000000000000000..a146785267d8b5ad9a95990187756968d6c969b4 --- /dev/null +++ b/testdata/parser/positive/13.pdl @@ -0,0 +1,42 @@ +#version 100 + +/* +Adaptation of 7.pdl +*/ + +composite main() {} + +composite example(in[] a, in[] b, out x) { + new async(a); + new async(b); + new resolve(a, b, x); +} + +primitive resolve(in[] a, in[] b, out x) { + while (true) { + synchronous { + int i = 0; + while (i < a.length && i < b.length) { + if (fires(a[i]) && fires(b[i])) { + put(x, create(0)); // send token to x + break; + } + i++; + } + if (i >= a.length || i >= b.length) + assert !fires(x); + } + } +} + +primitive async(in[] a) { + while (true) { + synchronous { + int i = 0; + while (i < a.length) + if (fires(a[i++])) break; + while (i < a.length) + assert !fires(a[i++]); + } + } +} diff --git a/testdata/parser/positive/14.pdl b/testdata/parser/positive/14.pdl new file mode 100644 index 0000000000000000000000000000000000000000..2d8e9216148e30f4e08f4fdb07c93b8c0fc2e419 --- /dev/null +++ b/testdata/parser/positive/14.pdl @@ -0,0 +1,35 @@ +#version 100 + +composite main(out c) { + channel ao -> ai; + channel bo -> bi; + new sync(ai, bo); + new binary_replicator(bi, ao, c); +} + +primitive sync(in a, out b) { + while (true) { + synchronous { + if (fires(a) && fires(b)) { + msg x = get(a); + put(b, x); + } else { + assert !fires(a) && !fires(b); + } + } + } +} + +primitive binary_replicator(in b, out a, out c) { + while (true) { + synchronous { + if (fires(b) && fires(a) && fires(c)) { + msg x = get(b); + put(a, x); + put(c, x); + } else { + assert !fires(a) && !fires(b) && !fires(c); + } + } + } +} \ No newline at end of file diff --git a/testdata/parser/positive/15.pdl b/testdata/parser/positive/15.pdl new file mode 100644 index 0000000000000000000000000000000000000000..8c4ceabd007701e0e5089e763fbaa866d7b56e7d --- /dev/null +++ b/testdata/parser/positive/15.pdl @@ -0,0 +1,28 @@ +#version + +import std.reo; + +composite main(out c) { + channel ao -> ai; + channel bo -> bi; + channel axo -> axi; + channel zo -> zi; + new sync(ai, bo); + new replicator(bi, {axo, c}); + new consensus({axi, zi}, ao); + new generator(zo); +} + +primitive generator(out z) { + while (true) { + synchronous (msg x) { + if (x == null) { + put(z, x); + assert !fires(x); + } else { + put(z, x); + assert fires(x); + } + } + } +} diff --git a/testdata/parser/positive/16.pdl b/testdata/parser/positive/16.pdl new file mode 100644 index 0000000000000000000000000000000000000000..604bdf0bd56c3344fc9ff34aa8e2919924f348b5 --- /dev/null +++ b/testdata/parser/positive/16.pdl @@ -0,0 +1,37 @@ +#version 100 + +composite main() { + channel xo -> xi; + new a(xi); + new c(xo); +} + +primitive a(in x) { + synchronous { + msg m = get(x); + assert m.length == 5; + assert m[0] == 'h'; + assert m[1] == 'e'; + assert m[2] == 'l'; + assert m[3] == 'l'; + assert m[4] == 'o'; + } +} + +primitive b(out x) { + synchronous (msg m) { + put(x, m); + } +} +// or +primitive c(out x) { + synchronous { + msg m = create(5); + m[0] = 'h'; + m[1] = 'e'; + m[2] = 'l'; + m[3] = 'l'; + m[4] = 'o'; + put(x, m); + } +} \ No newline at end of file diff --git a/testdata/parser/positive/17.pdl b/testdata/parser/positive/17.pdl new file mode 100644 index 0000000000000000000000000000000000000000..6b3934d0a050516cac284b7a5684f1918c27d421 --- /dev/null +++ b/testdata/parser/positive/17.pdl @@ -0,0 +1,50 @@ +#version 100 + +composite main(in x, out y) { + new prophet(x, y); +} + +primitive prophet(in b, out a) { + msg c = null; + while (true) { + if (c != null) { + synchronous { + assert !fires(a); + if (fires(b)) { + assert get(b) == c; + c = null; + } + } + } else { + synchronous (msg x) { + assert !fires(b); + if (fires(a)) { + put(a, x); + c = x; + } + } + } + } +} + +primitive fifo(in a, out b, msg init) { + msg c = init; + while (true) { + if (c != null) { + synchronous { + assert !fires(a); + if (fires(b)) { + put(b, c); + c = null; + } + } + } else { + synchronous { + assert !fires(b); + if (fires(a)) { + c = get(a); + } + } + } + } +} \ No newline at end of file diff --git a/testdata/parser/positive/18.pdl b/testdata/parser/positive/18.pdl new file mode 100644 index 0000000000000000000000000000000000000000..5482cb85c351f86974ce4d87eb7b4936c98719d0 --- /dev/null +++ b/testdata/parser/positive/18.pdl @@ -0,0 +1,42 @@ +#version 100 + +import std.reo; + +composite main() {} + +primitive main1(in a, out c) { + int x = 0; + int y = 0; + msg z = null; + msg w = null; + x = 1; + y = 1; + while (true) { + synchronous { + if (x > 0 && fires(a)) { + z = get(a); + x--; + } + if (w != null && fires(c)) { + put(c, w); + w = null; + y++; + } + } + synchronous { + assert !fires(a) && !fires(c); + if (z != null && y > 0) { + w = z; + z = null; + y--; + x++; + } + } + } +} + +composite main2(in a, out c) { + channel xo -> xi; + new fifo(a, xo, null); + new fifo(xi, c, null); +} diff --git a/testdata/parser/positive/19.pdl b/testdata/parser/positive/19.pdl new file mode 100644 index 0000000000000000000000000000000000000000..4084ce9e3962ab5893ccff2dbbd566060e0160f3 --- /dev/null +++ b/testdata/parser/positive/19.pdl @@ -0,0 +1,11 @@ +#version 100 + +composite main() {} + +primitive example(int a) { + synchronous { + loop: { + goto loop; // allowed + } + } +} \ No newline at end of file diff --git a/testdata/parser/positive/2.pdl b/testdata/parser/positive/2.pdl new file mode 100644 index 0000000000000000000000000000000000000000..dedfb7e3075677fafdf54038b47287aec80f28cf --- /dev/null +++ b/testdata/parser/positive/2.pdl @@ -0,0 +1,29 @@ +#version 100 + +import std.reo; + +composite main(in asend, out arecv, in bsend, out brecv, in csend, out crecv) { + channel xo -> xi; + channel yo -> yi; + channel zo -> zi; + // Every synchronous round, at most one message is sent (to determine a global order) + new mymerger(asend, bsend, xo); + new mymerger(csend, xi, yo); + // If a message is sent, it is broadcast to every recipient + new replicator(yi, {arecv, zo}); + new replicator(zi, {brecv, crecv}); +} + +primitive mymerger(in a, in b, out c) { + while (true) { + synchronous { + if (fires(a) && !fires(b) && fires(c)) { + put(c, get(a)); + } else if (!fires(a) && fires(b) && fires(c)) { + put(c, get(b)); + } else { + assert !fires(a) && !fires(b) && !fires(c); + } + } + } +} diff --git a/testdata/parser/positive/3.pdl b/testdata/parser/positive/3.pdl new file mode 100644 index 0000000000000000000000000000000000000000..11fb1a52fb3b3a1f5b7b6efa41abb16b1c47291a --- /dev/null +++ b/testdata/parser/positive/3.pdl @@ -0,0 +1,57 @@ +#version 100 + +import std.reo; + +composite main(in ai, out ao, in bi, out bo, in ci, out co, in di, out do) { + // Three parts: + channel xo -> xi; + { + channel afo -> aii; + channel bfo -> bii; + channel cfo -> cii; + channel dfo -> dii; + // Part 1. Collect all in msgs. + new fifo(ai, afo, null); + new fifo(bi, bfo, null); + new fifo(ci, cfo, null); + new fifo(di, dfo, null); + // Part 2. Compute maximum. + new computeMax(aii, bii, cii, dii, xo); + } + // Part 3. Send maximum to all out msgs, and repeat. + { + channel xxo -> xxi; + channel xxxo -> xxxi; + new replicator(xi, xxo, ao); + new replicator(xxi, xxxo, bo); + new replicator(xxxi, co, do); + } +} + +primitive computeMax(in a, in b, in c, in d, out x) { + while (true) { + synchronous { + if (fires(a) && fires(b) && fires(c) && fires(d) && fires(x)) { + msg aa = get(a); + msg bb = get(b); + msg cc = get(c); + msg dd = get(d); + uint16_t aaa = aa[0] & aa[1] << 8; + uint16_t bbb = bb[0] & bb[1] << 8; + uint16_t ccc = cc[0] & cc[1] << 8; + uint16_t ddd = dd[0] & dd[1] << 8; + // broadcast message with highest header + uint16_t max = aaa; + if (bbb > max) max = bbb; + if (ccc > max) max = ccc; + if (ddd > max) max = ddd; + if (max == aaa) put(x, aa); + else if (max == bbb) put(x, bb); + else if (max == ccc) put(x, cc); + else if (max == ddd) put(x, dd); + } else { + assert !fires(a) && !fires(b) && !fires(c) && !fires(d) && !fires(x); + } + } + } +} diff --git a/testdata/parser/positive/4.pdl b/testdata/parser/positive/4.pdl new file mode 100644 index 0000000000000000000000000000000000000000..9b0df3b2e3d8967e5e6fe21c4131553dd7163513 --- /dev/null +++ b/testdata/parser/positive/4.pdl @@ -0,0 +1,9 @@ +#version 100 + +import std.reo; + +composite main(in a, out b) { + msg x = create(1); + x[0] = 'X'; + new fifo(a, b, x); +} diff --git a/testdata/parser/positive/5.pdl b/testdata/parser/positive/5.pdl new file mode 100644 index 0000000000000000000000000000000000000000..4f3d6a9663bbe4901a06f0c31688497c94603e4a --- /dev/null +++ b/testdata/parser/positive/5.pdl @@ -0,0 +1,20 @@ +#version 100 + +import std.reo; +import std.buf; + +primitive main(in a, out b) { + while (true) { + synchronous { + if (fires(a) && fires(b)) { + msg x = get(a); + short y = readShort(x, 0); + y++; + writeShort(x, 0, y); + put(b, x); + } else { + assert !fires(a) && !fires(b); + } + } + } +} diff --git a/testdata/parser/positive/6.pdl b/testdata/parser/positive/6.pdl new file mode 100644 index 0000000000000000000000000000000000000000..77e1fc1425fa1f815789da3388fb394cdfe017a2 --- /dev/null +++ b/testdata/parser/positive/6.pdl @@ -0,0 +1,89 @@ +#version 100 + +composite main(in a1, in a2, in a3, out b1, out b2) { + new reonode({a1, a2, a3}, {b1, b2}); +} + +composite reonode(in[] a, out[] b) { + channel co -> ci; + new merger(a, co); + new replicator(ci, b); +} + +composite replicator(in a, out[] b) { + if (b.length == 0) { + new blocking(a); + } else if (b.length == 1) { + new sync(a, b[0]); + } else { + channel xo -> xi; + new binary_replicator(a, b[0], xo); + new replicator(xi, b[1 : b.length - 1]); + } +} +primitive binary_replicator(in a, out b, out c) { + while (true) { + synchronous { + if (fires(a) && fires(b) && fires(c)) { + msg x = get(a); + put(b, x); + put(c, x); + } else { + assert !fires(a) && !fires(b) && !fires(c); + } + } + } +} +primitive blocking(in a) { + while (true) synchronous { + assert !fires(a); + } +} + +composite merger(in[] a, out b) { + if (a.length == 0) { + new silent(b); + } else { + in prev = a[0]; + int i = 1; + while (i < a.length) { + channel yi -> yo; + new binary_merger(prev, a[i], yo); + prev = yi; + i++; + } + new sync(prev, b); + } +} +primitive binary_merger(in a, in b, out c) { + while (true) { + synchronous { + if (fires(a) && fires(c)) { + assert !fires(b); + put(c, get(a)); + } else if (fires(b) && fires(c)) { + assert !fires(a); + put(c, get(b)); + } else { + assert !fires(a) && !fires(b) && !fires(c); + } + } + } +} +primitive silent(out a) { + while (true) synchronous { + assert !fires(a); + } +} + +primitive sync(in a, out b) { + while (true) { + synchronous { + if (fires(a) && fires(b)) { + put(b, get(a)); + } else { + assert !fires(a) && !fires(b); + } + } + } +} diff --git a/testdata/parser/positive/7.pdl b/testdata/parser/positive/7.pdl new file mode 100644 index 0000000000000000000000000000000000000000..ffa6bbf17b4a7a656efeaee75ed0d48491c049ae --- /dev/null +++ b/testdata/parser/positive/7.pdl @@ -0,0 +1,82 @@ +#version 100 + +/* +Suggested by Benjamin Lion. +Source: http://www.wisdom.weizmann.ac.il/~naor/PUZZLES/compare.html + +Bob comes to Ron, a manager at his company, with a complaint about a +sensitive matter; he asks Ron to keep his identity confidential. A few +months later, Moshe (another manager) tells Ron that someone has +complained to him, also with a confidentiality request, about the same +matter. + +Ron and Moshe would like to determine whether the same person has +complained to each of them, but, if there are two complainers, Ron and +Moshe want to give no information to each other about their identities. + +The protocol typically used in a situation like this one is akin to the +game ``twenty questions,'' but goes by the name of ``delicate +conversational probing.'' Ron might ask Moshe if Moshe's complainer is +male, and if the answer is ``yes'' Moshe might then ask Ron if Ron's +complainer's surname begins with a letter preceding ``M'' in the +alphabet. This goes on until Ron and Moshe have ascertained whether they +have the same person in mind. When they do not, however (particularly +when the first ``no'' occurs late in the game) a great deal of +information may have been exchanged. + +What can Ron and Moshe do in order not leak more information than necessary? + +Here is one of our favorite solutions suggested by Miki Ajtai of the IBM +Almaden Research Center. His proposal is "physical" in the sense that +Ron and Moshe must be together. We need to assume that there is a fairly +small pool of candidates, say twenty. Ron and Moshe obtain twenty +identical containers (perhaps by purchasing disposable cups (paper or +plastic)), arrange them in a line, and write labels in front of each +cup, one for each candidate. Ron then puts a folded slip of paper saying +``Yes'' in the cup of the person who complained to him, and a slip +saying ``No'' in the other nineteen cups. Moshe does the same. Ron and +Moshe then remove the labels, and shuffle the cups at random. They then +look inside the cups to see whether one of them contains two slips +saying ``Yes'' and decide accordingly. +*/ + +composite main() {} + +composite puzzle(in[] a, in[] b, out x) { + new async(a); + new async(b); + new resolve(a, b, x); +} + +primitive resolve(in[] a, in[] b, out x) { + while (true) { + synchronous { + int i = 0; + while (i < a.length && i < b.length) { + if (fires(a[i]) && fires(b[i])) { + put(x, create(0)); // send token to x + goto end; + } + i++; + } + assert !fires(x); + end: skip; + } + } +} + +primitive async(in[] a) { + while (true) { + synchronous { + int i = 0; + int j = 0; + while (i < a.length) { + if (fires(a[i])) break; + i++; + } + while (j < a.length) { + assert i == j || !fires(a[j]); + } + } + } +} diff --git a/testdata/parser/positive/8.pdl b/testdata/parser/positive/8.pdl new file mode 100644 index 0000000000000000000000000000000000000000..d7b37e7c5089fe3b04637d38e03992b9b77e9c10 --- /dev/null +++ b/testdata/parser/positive/8.pdl @@ -0,0 +1,73 @@ +#version 100 + +/* +Suggested by Luc Edixhoven. +Source: https://en.wikipedia.org/wiki/Thue%E2%80%93Morse_sequence + +In mathematics, the Thue–Morse sequence, or Prouhet–Thue–Morse sequence, +is the binary sequence (an infinite sequence of 0s and 1s) obtained by +starting with 0 and successively appending the Boolean complement of the +sequence obtained thus far. + +To compute the nth element t_n, write the number n in binary. If the +number of ones in this binary expansion is odd then t_n = 1, if even +then t_n = 0. For this reason John H. Conway et al. call numbers n +satisfying t_n = 1 odious (for odd) numbers and numbers for which +t_n = 0 evil (for even) numbers. In other words, t_n = 0 if n is +an evil number and t_n = 1 if n is an odious number. + +*/ + +import std.reo; + +composite main(out x) { + channel ao -> ai; + channel bo -> bi; + channel co -> ci; + new evil_or_odious(ai, bo); + new replicator(bi, {co, x}); + new recorder(ao, ci); +} + +primitive evil_or_odious(in x, out y) { + while (true) { + synchronous { + if (fires(x) && fires(y)) { + msg a = get(x); + msg result = create(1); + boolean even = true; + int i = 0; + while (i < a.length) { + if (a[i++] == '1') + even = !even; + } + result[0] = even ? '1' : '0'; + put(y, result); + } else { + assert !fires(x); + assert !fires(y); + } + } + } +} +primitive recorder(out h, in a) { + msg c = create(0); + while (true) { + synchronous { + if (fires(h) && fires(a)) { + put(h, c); + { + msg x = get(a); + msg n = create(c.length + 1); + int i = 0; + while (i < c.length) { + n[i] = c[i]; + i++; + } + n[c.length] = x[0]; + c = n; + } + } + } + } +} diff --git a/testdata/parser/positive/9.pdl b/testdata/parser/positive/9.pdl new file mode 100644 index 0000000000000000000000000000000000000000..a72998693c23c3d05efdd822b26d43025828b393 --- /dev/null +++ b/testdata/parser/positive/9.pdl @@ -0,0 +1,16 @@ +#version 100 + +import std.reo; + +composite main(in A, in B, out C) { + channel xo -> xi; + channel yo -> yi; + channel zo -> zi; + channel do -> di; + channel eo -> ei; + new replicator(A, {xo, yo}); + new replicator(B, {zo, do}); + new syncdrain(xi, zi); + new fifo(di, eo); + new merger({yi, ei}, C); +} \ No newline at end of file diff --git a/testdata/parser/positive/tarry.pdl b/testdata/parser/positive/tarry.pdl new file mode 100644 index 0000000000000000000000000000000000000000..78582acc437fe5cfff483421127fae22f21786ff --- /dev/null +++ b/testdata/parser/positive/tarry.pdl @@ -0,0 +1,197 @@ +#version 100 + +/* +Example distributed algorithm: Tarry's algorithm. + +A token passes around the network, starting at some initiator. The initiator +starts the algorithm, and when the algorithm ends the token is back again at +the initiator. The non-initiators are signaled when they receive the token +for the first time; when the token is handled traversal continues. + +The network topology is defined by applications: they create an initiator or +non-initiator component, and establish bidirectional channels in between. +In this example, the whole network is created statically for simulation +purposes: there are 4 processes and some channels in between. + +Ports: initiator start, initiator end, three pairs of signals. +*/ + +import std.reo; + +composite main(in start, out end, out s1o, in s1i, out s2o, in s2i, out s3o, in s3i) { + // Processes: p, q, r, s + // Channels: pq, pr, qr, rs + channel p_pq -> pq_q; + channel q_pq -> pq_p; + channel p_pr -> pr_r; + channel r_pr -> pr_p; + channel q_qr -> qr_r; + channel r_qr -> qr_q; + channel r_rs -> rs_s; + channel s_rs -> rs_r; + + new initiator(start, end, {pq_p, pr_p}, {p_pq, p_pr}); + new noninitiator(s1o, s1i, {pq_q, qr_q}, {q_pq, q_qr}); + new noninitiator(s2o, s2i, {pr_r, rs_r}, {r_pr, r_rs}); + new noninitiator(s3o, s3i, {rs_s}, {s_rs}); +} +primitive initiator(in start, out end, in[] peeri, out[] peero) { + msg token = null; + in[] neighbori = {}; + out[] neighboro = {}; + assert peeri.length == peero.length; + while (true) { + // Step 1. Initiator waits for token + while (token == null) { + synchronous { + if (fires(start)) { + token = get(start); + } + } + } + // Reset neighbors + neighbori = peeri; + peeri = {}; + neighboro = peero; + peero = {}; + // Step 2. Keep sending token to processes + while (neighbori.length > 0) { + int idx = 0; + // Select first channel that accepts our token + while (token != null) { + synchronous { + int i = 0; + while (i < neighboro.length) { + if (fires(neighboro[i])) { + put(neighboro[i], token); + idx = i; + token = null; + break; + } else i++; + } + } + } + // Eliminate from neighbor set + peeri = {neighbori[idx]} @ peeri; + peero = {neighboro[idx]} @ peero; + neighbori = neighbori[0:idx] @ neighbori[idx:neighbori.length]; + neighboro = neighboro[0:idx] @ neighboro[idx:neighboro.length]; + // Step 3. Await return of token + while (token == null) { + synchronous { + int i = 0; + while (i < peeri.length + neighbori.length) { + if (fires(peeri@neighbori[i])) { + token = get(peeri@neighbori[i]); + break; + } else i++; + } + } + } + } + // Step 4. Token is back and all neighbors visited + while (token != null) { + synchronous { + if (fires(end)) { + put(end, token); + token = null; + } + } + } + } +} +primitive noninitiator(out start, in end, in[] peeri, out[] peero) { + msg token = null; + in[] neighbori = {}; + out[] neighboro = {}; + in[] parenti = {}; + out[] parento = {}; + assert peeri.length == peero.length; + while (true) { + int idx = 0; + // Step 1. Await token for first time + while (token == null) { + synchronous { + int i = 0; + while (i < peeri.length) { + if (fires(peeri[i])) { + token = get(peeri[i]); + idx = i; + break; + } else i++; + } + } + } + // Reset neighbors + neighbori = peeri[0:idx] @ peeri[idx:peeri.length]; + neighboro = peero[0:idx] @ peero[idx:peero.length]; + parenti = {peeri[idx]}; + parento = {peero[idx]}; + peeri = {}; + peero = {}; + // Step 2. Non-initiator signals + while (token != null) { + synchronous { + if (fires(end)) { + put(end, token); + token = null; + } + } + } + while (token == null) { + synchronous { + if (fires(start)) { + token = get(start); + } + } + } + // Step 3. Keep sending token to processes + while (neighbori.length > 0) { + idx = 0; + // Select first channel that accepts our token + while (token != null) { + synchronous { + int i = 0; + while (i < neighboro.length) { + if (fires(neighboro[i])) { + put(neighboro[i], token); + idx = i; + token = null; + break; + } else i++; + } + } + } + // Eliminate from neighbor set + peeri = {neighbori[idx]} @ peeri; + peero = {neighboro[idx]} @ peero; + neighbori = neighbori[0:idx] @ neighbori[idx:neighbori.length]; + neighboro = neighboro[0:idx] @ neighboro[idx:neighboro.length]; + // Step 4. Await return of token + while (token == null) { + synchronous { + int i = 0; + while (i < peeri.length + neighbori.length) { + if (fires(peeri@neighbori[i])) { + token = get(peeri@neighbori[i]); + break; + } else i++; + } + } + } + } + // Step 5. Token is back, pass to parent + while (token != null) { + synchronous { + if (fires(parento[0])) { + put(parento[0], token); + token = null; + } + } + } + peeri = {parenti[0]} @ peeri; + peero = {parento[0]} @ peero; + parenti = {}; + parento = {}; + } +}