implement type inference for multidef
This commit is contained in:
parent
b4ad991bde
commit
b32ccc5e4f
39 changed files with 545 additions and 1286 deletions
|
@ -2,5 +2,5 @@ def sub(field a) -> (field):
|
|||
field a = a + 3
|
||||
return a
|
||||
|
||||
def main():
|
||||
def main() -> (field):
|
||||
return sub(4)
|
|
@ -1,6 +1,6 @@
|
|||
def main(field a):
|
||||
def main(field a) -> (field):
|
||||
field b = (a + 5) * 6
|
||||
2 * b == a * 12 + 60
|
||||
field c = 7 * (b + a)
|
||||
field c == 7 * b + 7 * a
|
||||
c == 7 * b + 7 * a
|
||||
return b + c
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
def main(field a) -> (field):
|
||||
field x = 7
|
||||
for i in 0..10 do
|
||||
for field i in 0..10 do
|
||||
// x = x + a
|
||||
field x = x + a
|
||||
endfor
|
||||
|
|
|
@ -3,7 +3,7 @@ def add(field a,field b) -> (field):
|
|||
return v
|
||||
|
||||
// Expected for inputs 1,1: c=4, d=7, e=10
|
||||
def main(a,b):
|
||||
def main(field a,field b) -> (field):
|
||||
field c = add(a*2+3*b-a,b-1)
|
||||
field d = add(a*b+2, a*b*c)
|
||||
field e = add(add(a,d),add(a,b))
|
||||
|
|
|
@ -5,6 +5,6 @@ def add(field a,field b) -> (field):
|
|||
field a=const()
|
||||
return a+b
|
||||
|
||||
def main(a,b) -> (field):
|
||||
def main(field a,field b) -> (field):
|
||||
field c = add(a, b+const())
|
||||
return const()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
def foo(field a) -> (field):
|
||||
def foo(field a) -> (field, field, field, field):
|
||||
field b = 12*a
|
||||
return a, 2*a, 5*b, a*b
|
||||
|
||||
def main(i) -> (field):
|
||||
x, y, z, t = foo(i)
|
||||
def main(field i) -> (field):
|
||||
field x, field y, field z, field t = foo(i)
|
||||
return 1
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
def foo() -> (field, field):
|
||||
return 1, 2
|
||||
def main() -> (field, field):
|
||||
a, b = foo()
|
||||
field a, field b = foo()
|
||||
return a + b, b - a
|
|
@ -1,4 +1,4 @@
|
|||
def main(field x):
|
||||
def main(field x) -> (field):
|
||||
field a = x + 5
|
||||
field b = a + x
|
||||
a = 7
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
import "./halfadd.code" as HALFADD
|
||||
import "./or.code" as OR
|
||||
|
||||
def main(field a, field b, field car) -> (field):
|
||||
def main(field a, field b, field car) -> (field, field):
|
||||
out1, car1 = HALFADD(a, b)
|
||||
out2, car2 = HALFADD(out1, car)
|
||||
car3 = OR(car1, car2)
|
||||
field car3 = OR(car1, car2)
|
||||
return out2, car3
|
|
@ -3,5 +3,5 @@
|
|||
import "./xor.code" as XOR
|
||||
import "./and.code" as AND
|
||||
|
||||
def main(field a, field b):
|
||||
def main(field a, field b) -> (field, field):
|
||||
return XOR(a, b), AND(a, b)
|
|
@ -2,5 +2,5 @@
|
|||
|
||||
import "./../../binary/and.code" as AND
|
||||
|
||||
def main(field b31, field b30, field b29, field b28, field b27, field b26, field b25, field b24, field b23, field b22, field b21, field b20, field b19, field b18, field b17, field b16, field b15, field b14, field b13, field b12, field b11, field b10, field b9, field b8, field b7, field b6, field b5, field b4, field b3, field b2, field b1, field b0, field c31, field c30, field c29, field c28, field c27, field c26, field c25, field c24, field c23, field c22, field c21, field c20, field c19, field c18, field c17, field c16, field c15, field c14, field c13, field c12, field c11, field c10, field c9, field c8, field c7, field c6, field c5, field c4, field c3, field c2, field c1, field c0):
|
||||
def main(field b31, field b30, field b29, field b28, field b27, field b26, field b25, field b24, field b23, field b22, field b21, field b20, field b19, field b18, field b17, field b16, field b15, field b14, field b13, field b12, field b11, field b10, field b9, field b8, field b7, field b6, field b5, field b4, field b3, field b2, field b1, field b0, field c31, field c30, field c29, field c28, field c27, field c26, field c25, field c24, field c23, field c22, field c21, field c20, field c19, field c18, field c17, field c16, field c15, field c14, field c13, field c12, field c11, field c10, field c9, field c8, field c7, field c6, field c5, field c4, field c3, field c2, field c1, field c0) -> (field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field):
|
||||
return AND(b31, c31), AND(b30, c30), AND(b29, c29), AND(b28, c28), AND(b27, c27), AND(b26, c26), AND(b25, c25), AND(b24, c24), AND(b23, c23), AND(b22, c22), AND(b21, c21), AND(b20, c20), AND(b19, c19), AND(b18, c18), AND(b17, c17), AND(b16, c16), AND(b15, c15), AND(b14, c14), AND(b13, c13), AND(b12, c12), AND(b11, c11), AND(b10, c10), AND(b9, c9), AND(b8, c8), AND(b7, c7), AND(b6, c6), AND(b5, c5), AND(b4, c4), AND(b3, c3), AND(b2, c2), AND(b1, c1), AND(b0, c0)
|
|
@ -1,6 +1,6 @@
|
|||
// ANDXORANDXORAND
|
||||
|
||||
import "./../../field binary/andxorandxorand.code" as ANDXORANDXORAND
|
||||
import "./../../binary/andxorandxorand.code" as ANDXORANDXORAND
|
||||
|
||||
def main(field a31, field a30, field a29, field a28, field a27, field a26, field a25, field a24, field a23, field a22, field a21, field a20, field a19, field a18, field a17, field a16, field a15, field a14, field a13, field a12, field a11, field a10, field a9, field a8, field a7, field a6, field a5, field a4, field a3, field a2, field a1, field a0, field b31, field b30, field b29, field b28, field b27, field b26, field b25, field b24, field b23, field b22, field b21, field b20, field b19, field b18, field b17, field b16, field b15, field b14, field b13, field b12, field b11, field b10, field b9, field b8, field b7, field b6, field b5, field b4, field b3, field b2, field b1, field b0, field c31, field c30, field c29, field c28, field c27, field c26, field c25, field c24, field c23, field c22, field c21, field c20, field c19, field c18, field c17, field c16, field c15, field c14, field c13, field c12, field c11, field c10, field c9, field c8, field c7, field c6, field c5, field c4, field c3, field c2, field c1, field c0) -> (field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field):
|
||||
return ANDXORANDXORAND(a31, field b31, c31), ANDXORANDXORAND(a30, b30, c30), ANDXORANDXORAND(a29, b29, c29), ANDXORANDXORAND(a28, b28, c28), ANDXORANDXORAND(a27, b27, c27), ANDXORANDXORAND(a26, b26, c26), ANDXORANDXORAND(a25, b25, c25), ANDXORANDXORAND(a24, b24, c24), ANDXORANDXORAND(a23, b23, c23), ANDXORANDXORAND(a22, b22, c22), ANDXORANDXORAND(a21, b21, c21), ANDXORANDXORAND(a20, b20, c20), ANDXORANDXORAND(a19, b19, c19), ANDXORANDXORAND(a18, b18, c18), ANDXORANDXORAND(a17, b17, c17), ANDXORANDXORAND(a16, b16, c16), ANDXORANDXORAND(a15, b15, c15), ANDXORANDXORAND(a14, b14, c14), ANDXORANDXORAND(a13, b13, c13), ANDXORANDXORAND(a12, b12, c12), ANDXORANDXORAND(a11, b11, c11), ANDXORANDXORAND(a10, b10, c10), ANDXORANDXORAND(a9, b9, c9), ANDXORANDXORAND(a8, b8, c8), ANDXORANDXORAND(a7, b7, c7), ANDXORANDXORAND(a6, b6, c6), ANDXORANDXORAND(a5, b5, c5), ANDXORANDXORAND(a4, b4, c4), ANDXORANDXORAND(a3, b3, c3), ANDXORANDXORAND(a2, b2, c2), ANDXORANDXORAND(a1, b1, c1), ANDXORANDXORAND(a0, b0, c0)
|
||||
return ANDXORANDXORAND(a31, b31, c31), ANDXORANDXORAND(a30, b30, c30), ANDXORANDXORAND(a29, b29, c29), ANDXORANDXORAND(a28, b28, c28), ANDXORANDXORAND(a27, b27, c27), ANDXORANDXORAND(a26, b26, c26), ANDXORANDXORAND(a25, b25, c25), ANDXORANDXORAND(a24, b24, c24), ANDXORANDXORAND(a23, b23, c23), ANDXORANDXORAND(a22, b22, c22), ANDXORANDXORAND(a21, b21, c21), ANDXORANDXORAND(a20, b20, c20), ANDXORANDXORAND(a19, b19, c19), ANDXORANDXORAND(a18, b18, c18), ANDXORANDXORAND(a17, b17, c17), ANDXORANDXORAND(a16, b16, c16), ANDXORANDXORAND(a15, b15, c15), ANDXORANDXORAND(a14, b14, c14), ANDXORANDXORAND(a13, b13, c13), ANDXORANDXORAND(a12, b12, c12), ANDXORANDXORAND(a11, b11, c11), ANDXORANDXORAND(a10, b10, c10), ANDXORANDXORAND(a9, b9, c9), ANDXORANDXORAND(a8, b8, c8), ANDXORANDXORAND(a7, b7, c7), ANDXORANDXORAND(a6, b6, c6), ANDXORANDXORAND(a5, b5, c5), ANDXORANDXORAND(a4, b4, c4), ANDXORANDXORAND(a3, b3, c3), ANDXORANDXORAND(a2, b2, c2), ANDXORANDXORAND(a1, b1, c1), ANDXORANDXORAND(a0, b0, c0)
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
|
||||
import "./../../binary/xor.code" as XOR
|
||||
|
||||
def main(field b31, field b30, field b29, field b28, field b27, field b26, field b25, field b24, field b23, field b22, field b21, field b20, field b19, field b18, field b17, field b16, field b15, field b14, field b13, field b12, field b11, field b10, field b9, field b8, field b7, field b6, field b5, field b4, field b3, field b2, field b1, field b0, field c31, field c30, field c29, field c28, field c27, field c26, field c25, field c24, field c23, field c22, field c21, field c20, field c19, field c18, field c17, field c16, field c15, field c14, field c13, field c12, field c11, field c10, field c9, field c8, field c7, field c6, field c5, field c4, field c3, field c2, field c1, field c0):
|
||||
def main(field b31, field b30, field b29, field b28, field b27, field b26, field b25, field b24, field b23, field b22, field b21, field b20, field b19, field b18, field b17, field b16, field b15, field b14, field b13, field b12, field b11, field b10, field b9, field b8, field b7, field b6, field b5, field b4, field b3, field b2, field b1, field b0, field c31, field c30, field c29, field c28, field c27, field c26, field c25, field c24, field c23, field c22, field c21, field c20, field c19, field c18, field c17, field c16, field c15, field c14, field c13, field c12, field c11, field c10, field c9, field c8, field c7, field c6, field c5, field c4, field c3, field c2, field c1, field c0) -> (field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field):
|
||||
return XOR(b31, c31), XOR(b30, c30), XOR(b29, c29), XOR(b28, c28), XOR(b27, c27), XOR(b26, c26), XOR(b25, c25), XOR(b24, c24), XOR(b23, c23), XOR(b22, c22), XOR(b21, c21), XOR(b20, c20), XOR(b19, c19), XOR(b18, c18), XOR(b17, c17), XOR(b16, c16), XOR(b15, c15), XOR(b14, c14), XOR(b13, c13), XOR(b12, c12), XOR(b11, c11), XOR(b10, c10), XOR(b9, c9), XOR(b8, c8), XOR(b7, c7), XOR(b6, c6), XOR(b5, c5), XOR(b4, c4), XOR(b3, c3), XOR(b2, c2), XOR(b1, c1), XOR(b0, c0)
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,71 +0,0 @@
|
|||
def NOT(x):
|
||||
return 1 - x
|
||||
|
||||
def AND(x, y):
|
||||
return x * y
|
||||
|
||||
def OR(x, y):
|
||||
return NOT(AND(NOT(x), NOT(y)))
|
||||
|
||||
def XOR(x, y):
|
||||
return AND(OR(x, y), NOT(AND(x,y)))
|
||||
|
||||
def XOR(b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0, c31, c30, c29, c28, c27, c26, c25, c24, c23, c22, c21, c20, c19, c18, c17, c16, c15, c14, c13, c12, c11, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0):
|
||||
return XOR(b31, c31), XOR(b30, c30), XOR(b29, c29), XOR(b28, c28), XOR(b27, c27), XOR(b26, c26), XOR(b25, c25), XOR(b24, c24), XOR(b23, c23), XOR(b22, c22), XOR(b21, c21), XOR(b20, c20), XOR(b19, c19), XOR(b18, c18), XOR(b17, c17), XOR(b16, c16), XOR(b15, c15), XOR(b14, c14), XOR(b13, c13), XOR(b12, c12), XOR(b11, c11), XOR(b10, c10), XOR(b9, c9), XOR(b8, c8), XOR(b7, c7), XOR(b6, c6), XOR(b5, c5), XOR(b4, c4), XOR(b3, c3), XOR(b2, c2), XOR(b1, c1), XOR(b0, c0)
|
||||
|
||||
def RIGHTROTATE10(b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0):
|
||||
return b9, b8, b7, b6, b5, b4, b3, b2, b1, b0, b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10
|
||||
|
||||
def RIGHTROTATE17(b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0):
|
||||
return b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0, b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17
|
||||
|
||||
def RIGHTROTATE19(b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0):
|
||||
return b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0, b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19
|
||||
|
||||
def AR17XORAR19XORAR10(a31, a30, a29, a28, a27, a26, a25, a24, a23, a22, a21, a20, a19, a18, a17, a16, a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0):
|
||||
u31, u30, u29, u28, u27, u26, u25, u24, u23, u22, u21, u20, u19, u18, u17, u16, u15, u14, u13, u12, u11, u10, u9, u8, u7, u6, u5, u4, u3, u2, u1, u0 = RIGHTROTATE17(a31, a30, a29, a28, a27, a26, a25, a24, a23, a22, a21, a20, a19, a18, a17, a16, a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0)
|
||||
v31, v30, v29, v28, v27, v26, v25, v24, v23, v22, v21, v20, v19, v18, v17, v16, v15, v14, v13, v12, v11, v10, v9, v8, v7, v6, v5, v4, v3, v2, v1, v0 = RIGHTROTATE19(a31, a30, a29, a28, a27, a26, a25, a24, a23, a22, a21, a20, a19, a18, a17, a16, a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0)
|
||||
w31, w30, w29, w28, w27, w26, w25, w24, w23, w22, w21, w20, w19, w18, w17, w16, w15, w14, w13, w12, w11, w10, w9, w8, w7, w6, w5, w4, w3, w2, w1, w0 = RIGHTROTATE10(a31, a30, a29, a28, a27, a26, a25, a24, a23, a22, a21, a20, a19, a18, a17, a16, a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0)
|
||||
x31, x30, x29, x28, x27, x26, x25, x24, x23, x22, x21, x20, x19, x18, x17, x16, x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0 = XOR(u31, u30, u29, u28, u27, u26, u25, u24, u23, u22, u21, u20, u19, u18, u17, u16, u15, u14, u13, u12, u11, u10, u9, u8, u7, u6, u5, u4, u3, u2, u1, u0, v31, v30, v29, v28, v27, v26, v25, v24, v23, v22, v21, v20, v19, v18, v17, v16, v15, v14, v13, v12, v11, v10, v9, v8, v7, v6, v5, v4, v3, v2, v1, v0)
|
||||
z31, z30, z29, z28, z27, z26, z25, z24, z23, z22, z21, z20, z19, z18, z17, z16, z15, z14, z13, z12, z11, z10, z9, z8, z7, z6, z5, z4, z3, z2, z1, z0 = XOR(w31, w30, w29, w28, w27, w26, w25, w24, w23, w22, w21, w20, w19, w18, w17, w16, w15, w14, w13, w12, w11, w10, w9, w8, w7, w6, w5, w4, w3, w2, w1, w0, x31, x30, x29, x28, x27, x26, x25, x24, x23, x22, x21, x20, x19, x18, x17, x16, x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0)
|
||||
return z31, z30, z29, z28, z27, z26, z25, z24, z23, z22, z21, z20, z19, z18, z17, z16, z15, z14, z13, z12, z11, z10, z9, z8, z7, z6, z5, z4, z3, z2, z1, z0
|
||||
|
||||
def AR17XORAR19XORAR10test():
|
||||
b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0 = AR17XORAR19XORAR10(0,1,0,1,0,1,0,0,0,1,0,1,0,1,1,0,0,0,1,0,0,0,1,0,0,1,1,0,1,1,0,1)
|
||||
b31 == 0
|
||||
b30 == 1
|
||||
b29 == 0
|
||||
b28 == 0
|
||||
b27 == 1
|
||||
b26 == 1
|
||||
b25 == 1
|
||||
b24 == 0
|
||||
b23 == 0
|
||||
b22 == 0
|
||||
b21 == 1
|
||||
b20 == 0
|
||||
b19 == 1
|
||||
b18 == 1
|
||||
b17 == 1
|
||||
b16 == 0
|
||||
b15 == 0
|
||||
b14 == 0
|
||||
b13 == 0
|
||||
b12 == 1
|
||||
b11 == 0
|
||||
b10 == 1
|
||||
b9 == 0
|
||||
b8 == 1
|
||||
b7 == 0
|
||||
b6 == 0
|
||||
b5 == 1
|
||||
b4 == 0
|
||||
b3 == 1
|
||||
b2 == 0
|
||||
b1 == 0
|
||||
b0 == 1
|
||||
return 1
|
||||
|
||||
def main():
|
||||
k = AR17XORAR19XORAR10test()
|
||||
return
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import "./../../binary/fulladd.code" as FULLADD
|
||||
|
||||
def main(b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0, c31, c30, c29, c28, c27, c26, c25, c24, c23, c22, c21, c20, c19, c18, c17, c16, c15, c14, c13, c12, c11, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0):
|
||||
def main(field b31, field b30, field b29, field b28, field b27, field b26, field b25, field b24, field b23, field b22, field b21, field b20, field b19, field b18, field b17, field b16, field b15, field b14, field b13, field b12, field b11, field b10, field b9, field b8, field b7, field b6, field b5, field b4, field b3, field b2, field b1, field b0, field c31, field c30, field c29, field c28, field c27, field c26, field c25, field c24, field c23, field c22, field c21, field c20, field c19, field c18, field c17, field c16, field c15, field c14, field c13, field c12, field c11, field c10, field c9, field c8, field c7, field c6, field c5, field c4, field c3, field c2, field c1, field c0) -> (field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field):
|
||||
d0, car1 = FULLADD(b0, c0, 0)
|
||||
d1, car2 = FULLADD(b1, c1, car1)
|
||||
d2, car3 = FULLADD(b2, c2, car2)
|
||||
|
|
|
@ -2,16 +2,16 @@
|
|||
|
||||
import "./../../bitwise/32/xor.code" as XOR
|
||||
|
||||
def RR17(b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0):
|
||||
def RR17(field b31, field b30, field b29, field b28, field b27, field b26, field b25, field b24, field b23, field b22, field b21, field b20, field b19, field b18, field b17, field b16, field b15, field b14, field b13, field b12, field b11, field b10, field b9, field b8, field b7, field b6, field b5, field b4, field b3, field b2, field b1, field b0) -> (field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field):
|
||||
return b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0, b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17
|
||||
|
||||
def RR19(b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0):
|
||||
def RR19(field b31, field b30, field b29, field b28, field b27, field b26, field b25, field b24, field b23, field b22, field b21, field b20, field b19, field b18, field b17, field b16, field b15, field b14, field b13, field b12, field b11, field b10, field b9, field b8, field b7, field b6, field b5, field b4, field b3, field b2, field b1, field b0) -> (field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field):
|
||||
return b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0, b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19
|
||||
|
||||
def RS10(b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0):
|
||||
def RS10(field b31, field b30, field b29, field b28, field b27, field b26, field b25, field b24, field b23, field b22, field b21, field b20, field b19, field b18, field b17, field b16, field b15, field b14, field b13, field b12, field b11, field b10, field b9, field b8, field b7, field b6, field b5, field b4, field b3, field b2, field b1, field b0) -> (field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field):
|
||||
return 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10
|
||||
|
||||
def main(a31, a30, a29, a28, a27, a26, a25, a24, a23, a22, a21, a20, a19, a18, a17, a16, a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0):
|
||||
def main(field a31, field a30, field a29, field a28, field a27, field a26, field a25, field a24, field a23, field a22, field a21, field a20, field a19, field a18, field a17, field a16, field a15, field a14, field a13, field a12, field a11, field a10, field a9, field a8, field a7, field a6, field a5, field a4, field a3, field a2, field a1, field a0) -> (field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field):
|
||||
u31, u30, u29, u28, u27, u26, u25, u24, u23, u22, u21, u20, u19, u18, u17, u16, u15, u14, u13, u12, u11, u10, u9, u8, u7, u6, u5, u4, u3, u2, u1, u0 = RR17(a31, a30, a29, a28, a27, a26, a25, a24, a23, a22, a21, a20, a19, a18, a17, a16, a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0)
|
||||
v31, v30, v29, v28, v27, v26, v25, v24, v23, v22, v21, v20, v19, v18, v17, v16, v15, v14, v13, v12, v11, v10, v9, v8, v7, v6, v5, v4, v3, v2, v1, v0 = RR19(a31, a30, a29, a28, a27, a26, a25, a24, a23, a22, a21, a20, a19, a18, a17, a16, a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0)
|
||||
w31, w30, w29, w28, w27, w26, w25, w24, w23, w22, w21, w20, w19, w18, w17, w16, w15, w14, w13, w12, w11, w10, w9, w8, w7, w6, w5, w4, w3, w2, w1, w0 = RS10(a31, a30, a29, a28, a27, a26, a25, a24, a23, a22, a21, a20, a19, a18, a17, a16, a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0)
|
||||
|
|
|
@ -2,16 +2,16 @@
|
|||
|
||||
import "./../../bitwise/32/xor.code" as XOR
|
||||
|
||||
def RR2(b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0):
|
||||
def RR2(field b31, field b30, field b29, field b28, field b27, field b26, field b25, field b24, field b23, field b22, field b21, field b20, field b19, field b18, field b17, field b16, field b15, field b14, field b13, field b12, field b11, field b10, field b9, field b8, field b7, field b6, field b5, field b4, field b3, field b2, field b1, field b0) -> (field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field):
|
||||
return b1, b0, b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2
|
||||
|
||||
def RR13(b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0):
|
||||
def RR13(field b31, field b30, field b29, field b28, field b27, field b26, field b25, field b24, field b23, field b22, field b21, field b20, field b19, field b18, field b17, field b16, field b15, field b14, field b13, field b12, field b11, field b10, field b9, field b8, field b7, field b6, field b5, field b4, field b3, field b2, field b1, field b0) -> (field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field):
|
||||
return b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0, b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13
|
||||
|
||||
def RR22(b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0):
|
||||
def RR22(field b31, field b30, field b29, field b28, field b27, field b26, field b25, field b24, field b23, field b22, field b21, field b20, field b19, field b18, field b17, field b16, field b15, field b14, field b13, field b12, field b11, field b10, field b9, field b8, field b7, field b6, field b5, field b4, field b3, field b2, field b1, field b0) -> (field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field):
|
||||
return b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0, b31, b30, b29, b28, b27, b26, b25, b24, b23, b22
|
||||
|
||||
def main(a31, a30, a29, a28, a27, a26, a25, a24, a23, a22, a21, a20, a19, a18, a17, a16, a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0):
|
||||
def main(field a31, field a30, field a29, field a28, field a27, field a26, field a25, field a24, field a23, field a22, field a21, field a20, field a19, field a18, field a17, field a16, field a15, field a14, field a13, field a12, field a11, field a10, field a9, field a8, field a7, field a6, field a5, field a4, field a3, field a2, field a1, field a0) -> (field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field):
|
||||
u31, u30, u29, u28, u27, u26, u25, u24, u23, u22, u21, u20, u19, u18, u17, u16, u15, u14, u13, u12, u11, u10, u9, u8, u7, u6, u5, u4, u3, u2, u1, u0 = RR2(a31, a30, a29, a28, a27, a26, a25, a24, a23, a22, a21, a20, a19, a18, a17, a16, a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0)
|
||||
v31, v30, v29, v28, v27, v26, v25, v24, v23, v22, v21, v20, v19, v18, v17, v16, v15, v14, v13, v12, v11, v10, v9, v8, v7, v6, v5, v4, v3, v2, v1, v0 = RR13(a31, a30, a29, a28, a27, a26, a25, a24, a23, a22, a21, a20, a19, a18, a17, a16, a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0)
|
||||
w31, w30, w29, w28, w27, w26, w25, w24, w23, w22, w21, w20, w19, w18, w17, w16, w15, w14, w13, w12, w11, w10, w9, w8, w7, w6, w5, w4, w3, w2, w1, w0 = RR22(a31, a30, a29, a28, a27, a26, a25, a24, a23, a22, a21, a20, a19, a18, a17, a16, a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0)
|
||||
|
|
|
@ -2,16 +2,16 @@
|
|||
|
||||
import "./../../bitwise/32/xor.code" as XOR
|
||||
|
||||
def RR6(b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0):
|
||||
def RR6(field b31, field b30, field b29, field b28, field b27, field b26, field b25, field b24, field b23, field b22, field b21, field b20, field b19, field b18, field b17, field b16, field b15, field b14, field b13, field b12, field b11, field b10, field b9, field b8, field b7, field b6, field b5, field b4, field b3, field b2, field b1, field b0) -> (field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field):
|
||||
return b5, b4, b3, b2, b1, b0, b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6
|
||||
|
||||
def RR11(b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0):
|
||||
def RR11(field b31, field b30, field b29, field b28, field b27, field b26, field b25, field b24, field b23, field b22, field b21, field b20, field b19, field b18, field b17, field b16, field b15, field b14, field b13, field b12, field b11, field b10, field b9, field b8, field b7, field b6, field b5, field b4, field b3, field b2, field b1, field b0) -> (field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field):
|
||||
return b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0, b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11
|
||||
|
||||
def RR25(b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0):
|
||||
def RR25(field b31, field b30, field b29, field b28, field b27, field b26, field b25, field b24, field b23, field b22, field b21, field b20, field b19, field b18, field b17, field b16, field b15, field b14, field b13, field b12, field b11, field b10, field b9, field b8, field b7, field b6, field b5, field b4, field b3, field b2, field b1, field b0) -> (field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field):
|
||||
return b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0, b31, b30, b29, b28, b27, b26, b25
|
||||
|
||||
def main(a31, a30, a29, a28, a27, a26, a25, a24, a23, a22, a21, a20, a19, a18, a17, a16, a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0):
|
||||
def main(field a31, field a30, field a29, field a28, field a27, field a26, field a25, field a24, field a23, field a22, field a21, field a20, field a19, field a18, field a17, field a16, field a15, field a14, field a13, field a12, field a11, field a10, field a9, field a8, field a7, field a6, field a5, field a4, field a3, field a2, field a1, field a0) -> (field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field):
|
||||
u31, u30, u29, u28, u27, u26, u25, u24, u23, u22, u21, u20, u19, u18, u17, u16, u15, u14, u13, u12, u11, u10, u9, u8, u7, u6, u5, u4, u3, u2, u1, u0 = RR6(a31, a30, a29, a28, a27, a26, a25, a24, a23, a22, a21, a20, a19, a18, a17, a16, a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0)
|
||||
v31, v30, v29, v28, v27, v26, v25, v24, v23, v22, v21, v20, v19, v18, v17, v16, v15, v14, v13, v12, v11, v10, v9, v8, v7, v6, v5, v4, v3, v2, v1, v0 = RR11(a31, a30, a29, a28, a27, a26, a25, a24, a23, a22, a21, a20, a19, a18, a17, a16, a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0)
|
||||
w31, w30, w29, w28, w27, w26, w25, w24, w23, w22, w21, w20, w19, w18, w17, w16, w15, w14, w13, w12, w11, w10, w9, w8, w7, w6, w5, w4, w3, w2, w1, w0 = RR25(a31, a30, a29, a28, a27, a26, a25, a24, a23, a22, a21, a20, a19, a18, a17, a16, a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0)
|
||||
|
|
|
@ -2,16 +2,16 @@
|
|||
|
||||
import "./../../bitwise/32/xor.code" as XOR
|
||||
|
||||
def RR7(b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0):
|
||||
def RR7(field b31, field b30, field b29, field b28, field b27, field b26, field b25, field b24, field b23, field b22, field b21, field b20, field b19, field b18, field b17, field b16, field b15, field b14, field b13, field b12, field b11, field b10, field b9, field b8, field b7, field b6, field b5, field b4, field b3, field b2, field b1, field b0) -> (field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field):
|
||||
return b6, b5, b4, b3, b2, b1, b0, b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7
|
||||
|
||||
def RR18(b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0):
|
||||
def RR18(field b31, field b30, field b29, field b28, field b27, field b26, field b25, field b24, field b23, field b22, field b21, field b20, field b19, field b18, field b17, field b16, field b15, field b14, field b13, field b12, field b11, field b10, field b9, field b8, field b7, field b6, field b5, field b4, field b3, field b2, field b1, field b0) -> (field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field):
|
||||
return b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0, b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18
|
||||
|
||||
def RS3(b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0):
|
||||
def RS3(field b31, field b30, field b29, field b28, field b27, field b26, field b25, field b24, field b23, field b22, field b21, field b20, field b19, field b18, field b17, field b16, field b15, field b14, field b13, field b12, field b11, field b10, field b9, field b8, field b7, field b6, field b5, field b4, field b3, field b2, field b1, field b0) -> (field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field):
|
||||
return 0, 0, 0, b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3
|
||||
|
||||
def main(a31, a30, a29, a28, a27, a26, a25, a24, a23, a22, a21, a20, a19, a18, a17, a16, a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0):
|
||||
def main(field a31, field a30, field a29, field a28, field a27, field a26, field a25, field a24, field a23, field a22, field a21, field a20, field a19, field a18, field a17, field a16, field a15, field a14, field a13, field a12, field a11, field a10, field a9, field a8, field a7, field a6, field a5, field a4, field a3, field a2, field a1, field a0) -> (field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field):
|
||||
u31, u30, u29, u28, u27, u26, u25, u24, u23, u22, u21, u20, u19, u18, u17, u16, u15, u14, u13, u12, u11, u10, u9, u8, u7, u6, u5, u4, u3, u2, u1, u0 = RR7(a31, a30, a29, a28, a27, a26, a25, a24, a23, a22, a21, a20, a19, a18, a17, a16, a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0)
|
||||
v31, v30, v29, v28, v27, v26, v25, v24, v23, v22, v21, v20, v19, v18, v17, v16, v15, v14, v13, v12, v11, v10, v9, v8, v7, v6, v5, v4, v3, v2, v1, v0 = RR18(a31, a30, a29, a28, a27, a26, a25, a24, a23, a22, a21, a20, a19, a18, a17, a16, a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0)
|
||||
w31, w30, w29, w28, w27, w26, w25, w24, w23, w22, w21, w20, w19, w18, w17, w16, w15, w14, w13, w12, w11, w10, w9, w8, w7, w6, w5, w4, w3, w2, w1, w0 = RS3(a31, a30, a29, a28, a27, a26, a25, a24, a23, a22, a21, a20, a19, a18, a17, a16, a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0)
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -4,13 +4,13 @@ import "./ar7xar18xars3.code" as AR7XAR18XAR3
|
|||
import "./ar17xar19xars10.code" as AR17XAR19XAR10
|
||||
import "./add.code" as ADD
|
||||
|
||||
def ADD(a31, a30, a29, a28, a27, a26, a25, a24, a23, a22, a21, a20, a19, a18, a17, a16, a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0, b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0, c31, c30, c29, c28, c27, c26, c25, c24, c23, c22, c21, c20, c19, c18, c17, c16, c15, c14, c13, c12, c11, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0, d31, d30, d29, d28, d27, d26, d25, d24, d23, d22, d21, d20, d19, d18, d17, d16, d15, d14, d13, d12, d11, d10, d9, d8, d7, d6, d5, d4, d3, d2, d1, d0):
|
||||
def ADD(field a31, field a30, field a29, field a28, field a27, field a26, field a25, field a24, field a23, field a22, field a21, field a20, field a19, field a18, field a17, field a16, field a15, field a14, field a13, field a12, field a11, field a10, field a9, field a8, field a7, field a6, field a5, field a4, field a3, field a2, field a1, field a0, field b31, field b30, field b29, field b28, field b27, field b26, field b25, field b24, field b23, field b22, field b21, field b20, field b19, field b18, field b17, field b16, field b15, field b14, field b13, field b12, field b11, field b10, field b9, field b8, field b7, field b6, field b5, field b4, field b3, field b2, field b1, field b0, field c31, field c30, field c29, field c28, field c27, field c26, field c25, field c24, field c23, field c22, field c21, field c20, field c19, field c18, field c17, field c16, field c15, field c14, field c13, field c12, field c11, field c10, field c9, field c8, field c7, field c6, field c5, field c4, field c3, field c2, field c1, field c0, field d31, field d30, field d29, field d28, field d27, field d26, field d25, field d24, field d23, field d22, field d21, field d20, field d19, field d18, field d17, field d16, field d15, field d14, field d13, field d12, field d11, field d10, field d9, field d8, field d7, field d6, field d5, field d4, field d3, field d2, field d1, field d0) -> (field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field):
|
||||
ab31, ab30, ab29, ab28, ab27, ab26, ab25, ab24, ab23, ab22, ab21, ab20, ab19, ab18, ab17, ab16, ab15, ab14, ab13, ab12, ab11, ab10, ab9, ab8, ab7, ab6, ab5, ab4, ab3, ab2, ab1, ab0 = ADD(a31, a30, a29, a28, a27, a26, a25, a24, a23, a22, a21, a20, a19, a18, a17, a16, a15, a14, a13, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3, a2, a1, a0, b31, b30, b29, b28, b27, b26, b25, b24, b23, b22, b21, b20, b19, b18, b17, b16, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5, b4, b3, b2, b1, b0)
|
||||
cd31, cd30, cd29, cd28, cd27, cd26, cd25, cd24, cd23, cd22, cd21, cd20, cd19, cd18, cd17, cd16, cd15, cd14, cd13, cd12, cd11, cd10, cd9, cd8, cd7, cd6, cd5, cd4, cd3, cd2, cd1, cd0 = ADD(c31, c30, c29, c28, c27, c26, c25, c24, c23, c22, c21, c20, c19, c18, c17, c16, c15, c14, c13, c12, c11, c10, c9, c8, c7, c6, c5, c4, c3, c2, c1, c0, d31, d30, d29, d28, d27, d26, d25, d24, d23, d22, d21, d20, d19, d18, d17, d16, d15, d14, d13, d12, d11, d10, d9, d8, d7, d6, d5, d4, d3, d2, d1, d0)
|
||||
abcd31, abcd30, abcd29, abcd28, abcd27, abcd26, abcd25, abcd24, abcd23, abcd22, abcd21, abcd20, abcd19, abcd18, abcd17, abcd16, abcd15, abcd14, abcd13, abcd12, abcd11, abcd10, abcd9, abcd8, abcd7, abcd6, abcd5, abcd4, abcd3, abcd2, abcd1, abcd0 = ADD(ab31, ab30, ab29, ab28, ab27, ab26, ab25, ab24, ab23, ab22, ab21, ab20, ab19, ab18, ab17, ab16, ab15, ab14, ab13, ab12, ab11, ab10, ab9, ab8, ab7, ab6, ab5, ab4, ab3, ab2, ab1, ab0, cd31, cd30, cd29, cd28, cd27, cd26, cd25, cd24, cd23, cd22, cd21, cd20, cd19, cd18, cd17, cd16, cd15, cd14, cd13, cd12, cd11, cd10, cd9, cd8, cd7, cd6, cd5, cd4, cd3, cd2, cd1, cd0)
|
||||
return abcd31, abcd30, abcd29, abcd28, abcd27, abcd26, abcd25, abcd24, abcd23, abcd22, abcd21, abcd20, abcd19, abcd18, abcd17, abcd16, abcd15, abcd14, abcd13, abcd12, abcd11, abcd10, abcd9, abcd8, abcd7, abcd6, abcd5, abcd4, abcd3, abcd2, abcd1, abcd0
|
||||
|
||||
def main(wm15b31, wm15b30, wm15b29, wm15b28, wm15b27, wm15b26, wm15b25, wm15b24, wm15b23, wm15b22, wm15b21, wm15b20, wm15b19, wm15b18, wm15b17, wm15b16, wm15b15, wm15b14, wm15b13, wm15b12, wm15b11, wm15b10, wm15b9, wm15b8, wm15b7, wm15b6, wm15b5, wm15b4, wm15b3, wm15b2, wm15b1, wm15b0, wm2b31, wm2b30, wm2b29, wm2b28, wm2b27, wm2b26, wm2b25, wm2b24, wm2b23, wm2b22, wm2b21, wm2b20, wm2b19, wm2b18, wm2b17, wm2b16, wm2b15, wm2b14, wm2b13, wm2b12, wm2b11, wm2b10, wm2b9, wm2b8, wm2b7, wm2b6, wm2b5, wm2b4, wm2b3, wm2b2, wm2b1, wm2b0, wm16b31, wm16b30, wm16b29, wm16b28, wm16b27, wm16b26, wm16b25, wm16b24, wm16b23, wm16b22, wm16b21, wm16b20, wm16b19, wm16b18, wm16b17, wm16b16, wm16b15, wm16b14, wm16b13, wm16b12, wm16b11, wm16b10, wm16b9, wm16b8, wm16b7, wm16b6, wm16b5, wm16b4, wm16b3, wm16b2, wm16b1, wm16b0, wm7b31, wm7b30, wm7b29, wm7b28, wm7b27, wm7b26, wm7b25, wm7b24, wm7b23, wm7b22, wm7b21, wm7b20, wm7b19, wm7b18, wm7b17, wm7b16, wm7b15, wm7b14, wm7b13, wm7b12, wm7b11, wm7b10, wm7b9, wm7b8, wm7b7, wm7b6, wm7b5, wm7b4, wm7b3, wm7b2, wm7b1, wm7b0):
|
||||
def main(field wm15b31, field wm15b30, field wm15b29, field wm15b28, field wm15b27, field wm15b26, field wm15b25, field wm15b24, field wm15b23, field wm15b22, field wm15b21, field wm15b20, field wm15b19, field wm15b18, field wm15b17, field wm15b16, field wm15b15, field wm15b14, field wm15b13, field wm15b12, field wm15b11, field wm15b10, field wm15b9, field wm15b8, field wm15b7, field wm15b6, field wm15b5, field wm15b4, field wm15b3, field wm15b2, field wm15b1, field wm15b0, field wm2b31, field wm2b30, field wm2b29, field wm2b28, field wm2b27, field wm2b26, field wm2b25, field wm2b24, field wm2b23, field wm2b22, field wm2b21, field wm2b20, field wm2b19, field wm2b18, field wm2b17, field wm2b16, field wm2b15, field wm2b14, field wm2b13, field wm2b12, field wm2b11, field wm2b10, field wm2b9, field wm2b8, field wm2b7, field wm2b6, field wm2b5, field wm2b4, field wm2b3, field wm2b2, field wm2b1, field wm2b0, field wm16b31, field wm16b30, field wm16b29, field wm16b28, field wm16b27, field wm16b26, field wm16b25, field wm16b24, field wm16b23, field wm16b22, field wm16b21, field wm16b20, field wm16b19, field wm16b18, field wm16b17, field wm16b16, field wm16b15, field wm16b14, field wm16b13, field wm16b12, field wm16b11, field wm16b10, field wm16b9, field wm16b8, field wm16b7, field wm16b6, field wm16b5, field wm16b4, field wm16b3, field wm16b2, field wm16b1, field wm16b0, field wm7b31, field wm7b30, field wm7b29, field wm7b28, field wm7b27, field wm7b26, field wm7b25, field wm7b24, field wm7b23, field wm7b22, field wm7b21, field wm7b20, field wm7b19, field wm7b18, field wm7b17, field wm7b16, field wm7b15, field wm7b14, field wm7b13, field wm7b12, field wm7b11, field wm7b10, field wm7b9, field wm7b8, field wm7b7, field wm7b6, field wm7b5, field wm7b4, field wm7b3, field wm7b2, field wm7b1, field wm7b0) -> (field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field, field):
|
||||
// s0 := (w[i-15] rightrotate 7) xor (w[i-15] rightrotate 18) xor (w[i-15] rightshift 3)
|
||||
szero31, szero30, szero29, szero28, szero27, szero26, szero25, szero24, szero23, szero22, szero21, szero20, szero19, szero18, szero17, szero16, szero15, szero14, szero13, szero12, szero11, szero10, szero9, szero8, szero7, szero6, szero5, szero4, szero3, szero2, szero1, szero0 = AR7XAR18XAR3(wm15b31, wm15b30, wm15b29, wm15b28, wm15b27, wm15b26, wm15b25, wm15b24, wm15b23, wm15b22, wm15b21, wm15b20, wm15b19, wm15b18, wm15b17, wm15b16, wm15b15, wm15b14, wm15b13, wm15b12, wm15b11, wm15b10, wm15b9, wm15b8, wm15b7, wm15b6, wm15b5, wm15b4, wm15b3, wm15b2, wm15b1, wm15b0)
|
||||
// s1 := (w[i-2] rightrotate 17) xor (w[i-2] rightrotate 19) xor (w[i-2] rightshift 10)
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// | c21 | c22 || d21 | d22 |
|
||||
|
||||
def checkEquality(field e11,field e12,field e21,field e22) -> (field):
|
||||
counter = if e11 == e12 then 1 else 0 fi
|
||||
field counter = if e11 == e12 then 1 else 0 fi
|
||||
counter = counter + if e11 == e21 then 1 else 0 fi
|
||||
counter = counter + if e11 == e22 then 1 else 0 fi
|
||||
counter = counter + if e12 == e21 then 1 else 0 fi
|
||||
|
|
|
@ -16,7 +16,7 @@ def isWaldo(field a, field p, field q) -> (field):
|
|||
return 1
|
||||
|
||||
// define all
|
||||
def main(field a0, field a1, field a2, field a3, private field index, private field p, private field q):
|
||||
def main(field a0, field a1, field a2, field a3, private field index, private field p, private field q) -> (field):
|
||||
// prover provides the index of Waldo
|
||||
field waldo = if index == 0 then a0 else 0 fi
|
||||
waldo = waldo + if index == 1 then a1 else 0 fi
|
||||
|
|
|
@ -540,12 +540,16 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn examples() {
|
||||
for p in glob("./examples/*.code").expect("Failed to read glob pattern") {
|
||||
for p in glob("./examples/**/*.code").expect("Failed to read glob pattern") {
|
||||
let path = match p {
|
||||
Ok(x) => x,
|
||||
Err(why) => panic!("Error: {:?}", why),
|
||||
};
|
||||
|
||||
if path.to_str().unwrap().contains("error") {
|
||||
continue
|
||||
}
|
||||
|
||||
println!("Testing {:?}", path);
|
||||
|
||||
let file = File::open(path.clone()).unwrap();
|
||||
|
@ -553,7 +557,7 @@ mod tests {
|
|||
let mut reader = BufReader::new(file);
|
||||
|
||||
let program_flattened: FlatProg<FieldPrime> =
|
||||
compile(&mut reader, path, Some(fs_resolve), true, false).unwrap();
|
||||
compile(&mut reader, path.parent().unwrap().to_path_buf(), Some(fs_resolve), true, false).unwrap();
|
||||
|
||||
let (..) = r1cs_program(&program_flattened);
|
||||
}
|
||||
|
@ -574,7 +578,7 @@ mod tests {
|
|||
let mut reader = BufReader::new(file);
|
||||
|
||||
let program_flattened: FlatProg<FieldPrime> =
|
||||
compile(&mut reader, path, Some(fs_resolve), true, false).unwrap();
|
||||
compile(&mut reader, path.parent().unwrap().to_path_buf(), Some(fs_resolve), true, false).unwrap();
|
||||
|
||||
let (..) = r1cs_program(&program_flattened);
|
||||
let _ = program_flattened.get_witness(vec![FieldPrime::from(0)]).unwrap();
|
||||
|
@ -596,7 +600,7 @@ mod tests {
|
|||
let mut reader = BufReader::new(file);
|
||||
|
||||
let program_flattened: FlatProg<FieldPrime> =
|
||||
compile(&mut reader, path, Some(fs_resolve), true, false).unwrap();
|
||||
compile(&mut reader, path.parent().unwrap().to_path_buf(), Some(fs_resolve), true, false).unwrap();
|
||||
|
||||
let (..) = r1cs_program(&program_flattened);
|
||||
|
||||
|
|
|
@ -123,16 +123,18 @@ impl<T: Field> fmt::Debug for Function<T> {
|
|||
#[derive(Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub enum Statement<T: Field> {
|
||||
Return(ExpressionList<T>),
|
||||
Definition(Variable, Expression<T>),
|
||||
Declaration(Variable),
|
||||
Definition(String, Expression<T>),
|
||||
Condition(Expression<T>, Expression<T>),
|
||||
For(Variable, T, T, Vec<Statement<T>>),
|
||||
MultipleDefinition(Vec<Variable>, Expression<T>),
|
||||
MultipleDefinition(Vec<String>, Expression<T>),
|
||||
}
|
||||
|
||||
impl<T: Field> fmt::Display for Statement<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Statement::Return(ref expr) => write!(f, "return {}", expr),
|
||||
Statement::Declaration(ref var) => write!(f, "{}", var),
|
||||
Statement::Definition(ref lhs, ref rhs) => write!(f, "{} = {}", lhs, rhs),
|
||||
Statement::Condition(ref lhs, ref rhs) => write!(f, "{} == {}", lhs, rhs),
|
||||
Statement::For(ref var, ref start, ref stop, ref list) => {
|
||||
|
@ -159,6 +161,7 @@ impl<T: Field> fmt::Debug for Statement<T> {
|
|||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Statement::Return(ref expr) => write!(f, "Return({:?})", expr),
|
||||
Statement::Declaration(ref var) => write!(f, "Declaration({:?})", var),
|
||||
Statement::Definition(ref lhs, ref rhs) => {
|
||||
write!(f, "Definition({:?}, {:?})", lhs, rhs)
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ pub struct Parameter {
|
|||
impl fmt::Display for Parameter {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let visibility = if self.private { "private " } else { "" };
|
||||
write!(f, "{}{} {}", visibility, self.id._type, self.id.id)
|
||||
write!(f, "{}{} {}", visibility, self.id.get_type(), self.id.id)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -85,6 +85,8 @@ fn compile_aux<T: Field, R: BufRead, S: BufRead, E: Into<imports::Error>>(reader
|
|||
for import in program_ast_without_imports.imports.iter() {
|
||||
// find the absolute path for the import, based on the path of the file which imports it
|
||||
let absolute_import_path = location.join(import.get_source());
|
||||
println!("compile {:?}", absolute_import_path);
|
||||
|
||||
match resolve(&absolute_import_path) {
|
||||
Ok(mut res) => {
|
||||
let compiled = compile_aux(&mut res, absolute_import_path.parent().unwrap().to_path_buf(), resolve_option, should_include_gadgets)?;
|
||||
|
@ -137,7 +139,7 @@ mod test {
|
|||
fn no_resolver_with_imports() {
|
||||
let mut r = BufReader::new(r#"
|
||||
import "./path/to/file" as foo
|
||||
def main():
|
||||
def main() -> (field):
|
||||
return foo()
|
||||
"#.as_bytes());
|
||||
let res: Result<FlatProg<FieldPrime>, CompileError<FieldPrime>> = compile(&mut r, PathBuf::from("./path/to/file"), None::<fn(&PathBuf) -> Result<BufReader<Empty>, io::Error>>, false, false);
|
||||
|
@ -147,7 +149,7 @@ mod test {
|
|||
#[test]
|
||||
fn no_resolver_without_imports() {
|
||||
let mut r = BufReader::new(r#"
|
||||
def main():
|
||||
def main() -> (field):
|
||||
return 1
|
||||
"#.as_bytes());
|
||||
let res: Result<FlatProg<FieldPrime>, CompileError<FieldPrime>> = compile(&mut r, PathBuf::from("./path/to/file"), None::<fn(&PathBuf) -> Result<BufReader<Empty>, io::Error>>, false, false);
|
||||
|
|
|
@ -738,6 +738,10 @@ impl Flattener {
|
|||
)
|
||||
);
|
||||
}
|
||||
TypedStatement::Declaration(_) => {
|
||||
// declarations have already been checked
|
||||
()
|
||||
}
|
||||
TypedStatement::Definition(ref v, ref expr) => {
|
||||
|
||||
// define n variables with n the number of primitive types for v_type
|
||||
|
|
|
@ -299,14 +299,19 @@ pub fn parse_function<T: Field, R: BufRead>(
|
|||
col: 1,
|
||||
},
|
||||
) {
|
||||
Ok((Statement::Return(list), ..)) => {
|
||||
stats.push(Statement::Return(list));
|
||||
break;
|
||||
Ok((ref statements, _, ref pos)) => {
|
||||
for stat in statements {
|
||||
stats.push(stat.clone());
|
||||
}
|
||||
Ok((statement, _, pos)) => {
|
||||
stats.push(statement);
|
||||
match statements[0] {
|
||||
Statement::Return(_) => {
|
||||
break;
|
||||
},
|
||||
_ => {
|
||||
current_line = pos.line // update the interal line counter to continue where statement ended.
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(err) => return Err(err),
|
||||
},
|
||||
None => panic!("Function {} does not return before program ends", id),
|
||||
|
|
|
@ -87,7 +87,7 @@ mod tests {
|
|||
let string = String::from("import \"./foo.code\"");
|
||||
let import: Token<FieldPrime> = Token::Import;
|
||||
assert_eq!(
|
||||
(import, "\"./foo.code\"".to_string(), pos.col(7 as isize)),
|
||||
(import, " \"./foo.code\"".to_string(), pos.col(6 as isize)),
|
||||
next_token(&string, &pos)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -18,9 +18,9 @@ pub fn parse_statement<T: Field, R: BufRead>(
|
|||
lines: &mut Lines<R>,
|
||||
input: &String,
|
||||
pos: &Position,
|
||||
) -> Result<(Statement<T>, String, Position), Error<T>> {
|
||||
) -> Result<(Vec<Statement<T>>, String, Position), Error<T>> {
|
||||
match next_token::<T>(input, pos) {
|
||||
(Token::Type(t), s1, p1) => parse_definition(t, s1, p1),
|
||||
(Token::Type(t), s1, p1) => parse_declaration_definition(t, s1, p1),
|
||||
(Token::Ide(x1), s1, p1) => parse_statement1(x1, s1, p1),
|
||||
(Token::If, ..) | (Token::Open, ..) | (Token::Num(_), ..) => match parse_expr(input, pos) {
|
||||
Ok((e2, s2, p2)) => match next_token(&s2, &p2) {
|
||||
|
@ -28,11 +28,11 @@ pub fn parse_statement<T: Field, R: BufRead>(
|
|||
Ok((e4, s4, p4)) => match next_token(&s4, &p4) {
|
||||
(Token::InlineComment(_), ref s5, _) => {
|
||||
assert_eq!(s5, "");
|
||||
Ok((Statement::Condition(e2, e4), s4, p4))
|
||||
Ok((vec![Statement::Condition(e2, e4)], s4, p4))
|
||||
}
|
||||
(Token::Unknown(ref t5), ref s5, _) if t5 == "" => {
|
||||
assert_eq!(s5, "");
|
||||
Ok((Statement::Condition(e2, e4), s4, p4))
|
||||
Ok((vec![Statement::Condition(e2, e4)], s4, p4))
|
||||
}
|
||||
(t5, _, p5) => Err(Error {
|
||||
expected: vec![Token::Unknown("".to_string())],
|
||||
|
@ -52,6 +52,8 @@ pub fn parse_statement<T: Field, R: BufRead>(
|
|||
},
|
||||
(Token::For, s1, p1) => {
|
||||
match next_token(&s1, &p1) {
|
||||
(Token::Type(t), s0, p0) => {
|
||||
match next_token(&s0, &p0) {
|
||||
(Token::Ide(x2), s2, p2) => {
|
||||
match next_token(&s2, &p2) {
|
||||
(Token::In, s3, p3) => {
|
||||
|
@ -105,17 +107,17 @@ pub fn parse_statement<T: Field, R: BufRead>(
|
|||
match next_token(&s8, &p8) {
|
||||
(Token::InlineComment(_), ref s9, _) => {
|
||||
assert_eq!(s9, "");
|
||||
return Ok((Statement::For(Variable::field_element(x2), x4, x6, statements), s8, p8))
|
||||
return Ok((vec![Statement::For(Variable::new(x2, t), x4, x6, statements)], s8, p8))
|
||||
}
|
||||
(Token::Unknown(ref t9), ref s9, _) if t9 == "" => {
|
||||
assert_eq!(s9, "");
|
||||
return Ok((Statement::For(Variable::field_element(x2), x4, x6, statements), s8, p8))
|
||||
return Ok((vec![Statement::For(Variable::new(x2, t), x4, x6, statements)], s8, p8))
|
||||
},
|
||||
(t9, _, p9) => return Err(Error { expected: vec![Token::Unknown("1432567iuhgvfc".to_string())], got: t9 , pos: p9 }),
|
||||
}
|
||||
},
|
||||
Some(Ok(ref x)) if !x.trim().starts_with("return") => match parse_statement(lines, x, &Position { line: current_line, col: 1 }) {
|
||||
Ok((statement, ..)) => statements.push(statement),
|
||||
Ok((statement, ..)) => statements.push(statement[0].clone()),
|
||||
Err(err) => return Err(err),
|
||||
},
|
||||
Some(Err(err)) => panic!("Error while reading Definitions: {}", err),
|
||||
|
@ -168,16 +170,23 @@ pub fn parse_statement<T: Field, R: BufRead>(
|
|||
pos: p2,
|
||||
}),
|
||||
}
|
||||
},
|
||||
(t0, _, p0) => Err(Error {
|
||||
expected: vec![Token::Type(Type::FieldElement)],
|
||||
got: t0,
|
||||
pos: p0,
|
||||
}),
|
||||
}
|
||||
}
|
||||
(Token::Return, s1, p1) => match parse_expression_list(s1, p1) {
|
||||
Ok((e2, s2, p2)) => match next_token(&s2, &p2) {
|
||||
(Token::InlineComment(_), ref s3, _) => {
|
||||
assert_eq!(s3, "");
|
||||
Ok((Statement::Return(e2), s2, p2))
|
||||
Ok((vec![Statement::Return(e2)], s2, p2))
|
||||
}
|
||||
(Token::Unknown(ref t3), ref s3, _) if t3 == "" => {
|
||||
assert_eq!(s3, "");
|
||||
Ok((Statement::Return(e2), s2, p2))
|
||||
Ok((vec![Statement::Return(e2)], s2, p2))
|
||||
}
|
||||
(t3, _, p3) => Err(Error {
|
||||
expected: vec![Token::Unknown("".to_string())],
|
||||
|
@ -206,23 +215,49 @@ pub fn parse_statement<T: Field, R: BufRead>(
|
|||
}
|
||||
}
|
||||
|
||||
// parse statement that starts with an identifier
|
||||
fn parse_definition<T: Field>(
|
||||
fn parse_definition1<T: Field>(
|
||||
ide: String,
|
||||
input: String,
|
||||
pos: Position,
|
||||
) -> Result<(Vec<Statement<T>>, String, Position), Error<T>> {
|
||||
match parse_expr(&input, &pos) {
|
||||
Ok((e1, s1, p1)) => match next_token(&s1, &p1) {
|
||||
(Token::InlineComment(_), ref s2, _) => {
|
||||
assert_eq!(s2, "");
|
||||
Ok((vec![Statement::Definition(ide, e1)], s1, p1))
|
||||
}
|
||||
(Token::Unknown(ref t2), ref s2, _) if t2 == "" => {
|
||||
assert_eq!(s2, "");
|
||||
Ok((vec![Statement::Definition(ide, e1)], s1, p1))
|
||||
}
|
||||
(t2, _, p2) => Err(Error {
|
||||
expected: vec![
|
||||
Token::Unknown("".to_string()),
|
||||
],
|
||||
got: t2,
|
||||
pos: p2,
|
||||
}),
|
||||
},
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_declaration_definition<T: Field>(
|
||||
t: Type,
|
||||
input: String,
|
||||
pos: Position,
|
||||
) -> Result<(Statement<T>, String, Position), Error<T>> {
|
||||
) -> Result<(Vec<Statement<T>>, String, Position), Error<T>> {
|
||||
match next_token::<T>(&input, &pos) {
|
||||
(Token::Ide(x), s0, p0) => match next_token(&s0, &p0) {
|
||||
(Token::Eq, s1, p1) => match parse_expr(&s1, &p1) {
|
||||
Ok((e2, s2, p2)) => match next_token(&s2, &p2) {
|
||||
(Token::InlineComment(_), ref s3, _) => {
|
||||
assert_eq!(s3, "");
|
||||
Ok((Statement::Definition(Variable::new(x, t), e2), s2, p2))
|
||||
Ok((vec![Statement::Declaration(Variable::new(x.clone(), t)), Statement::Definition(x, e2)], s2, p2))
|
||||
}
|
||||
(Token::Unknown(ref t3), ref s3, _) if t3 == "" => {
|
||||
assert_eq!(s3, "");
|
||||
Ok((Statement::Definition(Variable::new(x, t), e2), s2, p2))
|
||||
Ok((vec![Statement::Declaration(Variable::new(x.clone(), t)), Statement::Definition(x, e2)], s2, p2))
|
||||
}
|
||||
(t3, _, p3) => Err(Error {
|
||||
expected: vec![
|
||||
|
@ -239,8 +274,36 @@ fn parse_definition<T: Field>(
|
|||
},
|
||||
Err(err) => Err(err),
|
||||
},
|
||||
(t1, _, p1) => Err(Error {
|
||||
(Token::Comma, s1, p1) => match parse_identifier_list1(x, Some(t.clone()), s1, p1) {
|
||||
// if we find a comma, parse the rest of the destructure
|
||||
Ok((e2, d2, s2, p2)) => match next_token(&s2, &p2) {
|
||||
// then we should have an equal sign
|
||||
(Token::Eq, s3, p3) => match parse_expr(&s3, &p3) {
|
||||
Ok((e4, s4, p4)) => {
|
||||
let mut statements: Vec<Statement<T>> = d2.into_iter().map(|v| Statement::Declaration(v)).collect();
|
||||
statements.push(Statement::MultipleDefinition(e2, e4));
|
||||
Ok((statements, s4, p4)) // output a multipledefinition with the destructure and the expression
|
||||
}
|
||||
Err(err) => Err(err),
|
||||
},
|
||||
(t3, _, p3) => Err(Error {
|
||||
expected: vec![Token::Eq],
|
||||
got: t3,
|
||||
pos: p3,
|
||||
}),
|
||||
},
|
||||
Err(err) => Err(err),
|
||||
},
|
||||
(Token::InlineComment(_), ref s1, _) => {
|
||||
assert_eq!(s1, "");
|
||||
Ok((vec![Statement::Declaration(Variable::new(x.clone(), t))], s0, p0))
|
||||
},
|
||||
(Token::Unknown(ref t1), ref s1, _) if t1 == "" => {
|
||||
assert_eq!(s1, "");
|
||||
Ok((vec![Statement::Declaration(Variable::new(x.clone(), t))], s0, p0))
|
||||
},
|
||||
(t1, _, p1) => Err(Error {
|
||||
expected: vec![Token::Eq, Token::Unknown("".to_string())],
|
||||
got: t1,
|
||||
pos: p1,
|
||||
}),
|
||||
|
@ -258,15 +321,18 @@ fn parse_statement1<T: Field>(
|
|||
ide: String,
|
||||
input: String,
|
||||
pos: Position,
|
||||
) -> Result<(Statement<T>, String, Position), Error<T>> {
|
||||
) -> Result<(Vec<Statement<T>>, String, Position), Error<T>> {
|
||||
match next_token::<T>(&input, &pos) {
|
||||
(Token::Comma, s1, p1) => match parse_identifier_list1(ide, s1, p1) {
|
||||
(Token::Eq, s1, p1) => parse_definition1(ide, s1, p1),
|
||||
(Token::Comma, s1, p1) => match parse_identifier_list1(ide, None, s1, p1) {
|
||||
// if we find a comma, parse the rest of the destructure
|
||||
Ok((e2, s2, p2)) => match next_token(&s2, &p2) {
|
||||
Ok((e2, d2, s2, p2)) => match next_token(&s2, &p2) {
|
||||
// then we should have an equal sign
|
||||
(Token::Eq, s3, p3) => match parse_expr(&s3, &p3) {
|
||||
Ok((e4, s4, p4)) => {
|
||||
Ok((Statement::MultipleDefinition(e2, e4), s4, p4)) // output a multipledefinition with the destructure and the expression
|
||||
let mut statements: Vec<Statement<T>> = d2.into_iter().map(|v| Statement::Declaration(v)).collect();
|
||||
statements.push(Statement::MultipleDefinition(e2, e4));
|
||||
Ok((statements, s4, p4)) // output a multipledefinition with the destructure and the expression
|
||||
}
|
||||
Err(err) => Err(err),
|
||||
},
|
||||
|
@ -284,11 +350,11 @@ fn parse_statement1<T: Field>(
|
|||
Ok((e5, s5, p5)) => match next_token(&s5, &p5) {
|
||||
(Token::InlineComment(_), ref s6, _) => {
|
||||
assert_eq!(s6, "");
|
||||
Ok((Statement::Condition(e3, e5), s5, p5))
|
||||
Ok((vec![Statement::Condition(e3, e5)], s5, p5))
|
||||
}
|
||||
(Token::Unknown(ref t6), ref s6, _) if t6 == "" => {
|
||||
assert_eq!(s6, "");
|
||||
Ok((Statement::Condition(e3, e5), s5, p5))
|
||||
Ok((vec![Statement::Condition(e3, e5)], s5, p5))
|
||||
}
|
||||
(t6, _, p6) => Err(Error {
|
||||
expected: vec![
|
||||
|
@ -320,11 +386,11 @@ fn parse_statement1<T: Field>(
|
|||
Ok((e5, s5, p5)) => match next_token(&s5, &p5) {
|
||||
(Token::InlineComment(_), ref s6, _) => {
|
||||
assert_eq!(s6, "");
|
||||
Ok((Statement::Condition(e3, e5), s5, p5))
|
||||
Ok((vec![Statement::Condition(e3, e5)], s5, p5))
|
||||
}
|
||||
(Token::Unknown(ref t6), ref s6, _) if t6 == "" => {
|
||||
assert_eq!(s6, "");
|
||||
Ok((Statement::Condition(e3, e5), s5, p5))
|
||||
Ok((vec![Statement::Condition(e3, e5)], s5, p5))
|
||||
}
|
||||
(t6, _, p6) => Err(Error {
|
||||
expected: vec![
|
||||
|
@ -357,29 +423,57 @@ fn parse_statement1<T: Field>(
|
|||
// parse an expression list starting with an identifier
|
||||
pub fn parse_identifier_list1<T: Field>(
|
||||
head: String,
|
||||
_type: Option<Type>,
|
||||
input: String,
|
||||
pos: Position,
|
||||
) -> Result<(Vec<Variable>, String, Position), Error<T>> {
|
||||
) -> Result<(Vec<String>, Vec<Variable>, String, Position), Error<T>> {
|
||||
let mut res = Vec::new();
|
||||
res.push(Variable::field_element(head));
|
||||
parse_comma_separated_identifier_list_rec(input, pos, &mut res)
|
||||
let mut decl = Vec::new();
|
||||
res.push(head.clone());
|
||||
match _type {
|
||||
Some(t) => {
|
||||
decl.push(Variable::new(head, t));
|
||||
},
|
||||
_ => {}
|
||||
};
|
||||
parse_comma_separated_identifier_list_rec(input, pos, &mut res, &mut decl)
|
||||
}
|
||||
|
||||
fn parse_comma_separated_identifier_list_rec<T: Field>(
|
||||
input: String,
|
||||
pos: Position,
|
||||
mut acc: &mut Vec<Variable>,
|
||||
) -> Result<(Vec<Variable>, String, Position), Error<T>> {
|
||||
mut acc: &mut Vec<String>,
|
||||
mut decl: &mut Vec<Variable>,
|
||||
) -> Result<(Vec<String>, Vec<Variable>, String, Position), Error<T>> {
|
||||
match next_token(&input, &pos) {
|
||||
(Token::Type(t), s1, p1) => {
|
||||
match next_token::<T>(&s1, &p1) {
|
||||
(Token::Ide(id), s2, p2) => {
|
||||
acc.push(id.clone());
|
||||
decl.push(Variable::new(id, t));
|
||||
match next_token::<T>(&s2, &p2) {
|
||||
(Token::Comma, s3, p3) => {
|
||||
parse_comma_separated_identifier_list_rec(s3, p3, &mut acc, &mut decl)
|
||||
}
|
||||
(..) => Ok((acc.to_vec(), decl.to_vec(), s2, p2)),
|
||||
}
|
||||
}
|
||||
(t2, _, p2) => Err(Error {
|
||||
expected: vec![Token::Ide(String::from("ide"))],
|
||||
got: t2,
|
||||
pos: p2,
|
||||
}),
|
||||
}
|
||||
},
|
||||
(Token::Ide(id), s1, p1) => {
|
||||
acc.push(Variable::field_element(id));
|
||||
acc.push(id);
|
||||
match next_token::<T>(&s1, &p1) {
|
||||
(Token::Comma, s2, p2) => {
|
||||
parse_comma_separated_identifier_list_rec(s2, p2, &mut acc)
|
||||
}
|
||||
(..) => Ok((acc.to_vec(), s1, p1)),
|
||||
parse_comma_separated_identifier_list_rec(s2, p2, &mut acc, &mut decl)
|
||||
}
|
||||
(..) => Ok((acc.to_vec(), decl.to_vec(), s1, p1)),
|
||||
}
|
||||
},
|
||||
(t1, _, p1) => Err(Error {
|
||||
expected: vec![Token::Ide(String::from("ide"))],
|
||||
got: t1,
|
||||
|
@ -404,7 +498,7 @@ mod tests {
|
|||
Expression::Number(FieldPrime::from(1)),
|
||||
);
|
||||
assert_eq!(
|
||||
Ok((cond, String::from(""), pos.col(string.len() as isize))),
|
||||
Ok((vec![cond], String::from(""), pos.col(string.len() as isize))),
|
||||
parse_statement1(String::from("foo"), string, pos)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,39 @@ impl fmt::Display for Error {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct FunctionQuery {
|
||||
id: String,
|
||||
inputs: Vec<Type>,
|
||||
outputs: Vec<Option<Type>>
|
||||
}
|
||||
|
||||
impl FunctionQuery {
|
||||
fn new(id: String, inputs: &Vec<Type>, outputs: &Vec<Option<Type>>) -> FunctionQuery {
|
||||
FunctionQuery {
|
||||
id,
|
||||
inputs: inputs.clone(),
|
||||
outputs: outputs.clone()
|
||||
}
|
||||
}
|
||||
|
||||
fn match_func(&self, func: &FunctionDeclaration) -> bool {
|
||||
self.id == func.id &&
|
||||
self.inputs == func.signature.inputs &&
|
||||
self.outputs.len() == func.signature.outputs.len() &&
|
||||
self.outputs
|
||||
.iter()
|
||||
.enumerate()
|
||||
.all(|(index, t)| match t {
|
||||
Some(ref t) => t == &func.signature.outputs[index],
|
||||
_ => true
|
||||
})
|
||||
}
|
||||
|
||||
fn match_funcs(&self, funcs: Vec<FunctionDeclaration>) -> Vec<FunctionDeclaration> {
|
||||
funcs.into_iter().filter(|func| self.match_func(func)).collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub struct ScopedVariable {
|
||||
id: Variable,
|
||||
|
@ -92,24 +125,31 @@ impl Checker {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_for_var(&self, var: &Variable) -> Result<(), Error> {
|
||||
match var.get_type() {
|
||||
Type::FieldElement => Ok(()),
|
||||
t => Err(Error { message: format!("Variable in for loop cannot have type {}", t) })
|
||||
}
|
||||
}
|
||||
|
||||
fn check_function<T: Field>(&mut self, funct: &Function<T>) -> Result<TypedFunction<T>, Error> {
|
||||
assert_eq!(funct.arguments.len(), funct.signature.inputs.len());
|
||||
|
||||
match self.find_function(&funct.id, &funct.arguments.iter().map(|a| a.clone().id._type).collect()) {
|
||||
Some(_) => {
|
||||
let candidates = self.find_candidates(&funct.id, &funct.signature.inputs, &funct.signature.outputs.clone().into_iter().map(|o| Some(o)).collect());
|
||||
|
||||
match candidates.len() {
|
||||
1 => {
|
||||
return Err(Error { message: format!("Duplicate definition for function {} with {} arguments", funct.id, funct.arguments.len()) })
|
||||
},
|
||||
None => {
|
||||
0 => {
|
||||
|
||||
}
|
||||
},
|
||||
_ => panic!("dupllicate function declaration should have been caught")
|
||||
}
|
||||
self.level += 1;
|
||||
|
||||
for arg in funct.arguments.clone() {
|
||||
self.scope.insert(ScopedVariable {
|
||||
id: arg.id,
|
||||
level: self.level
|
||||
});
|
||||
self.insert_scope(arg.id);
|
||||
}
|
||||
|
||||
let mut statements_checked = vec![];
|
||||
|
@ -139,7 +179,7 @@ impl Checker {
|
|||
Statement::Return(ref list) => {
|
||||
let mut expression_list_checked = vec![];
|
||||
for e in list.expressions.clone() {
|
||||
let e_checked = self.check_expression(e)?;
|
||||
let e_checked = self.check_expression(&e)?;
|
||||
expression_list_checked.push(e_checked);
|
||||
}
|
||||
|
||||
|
@ -150,24 +190,34 @@ impl Checker {
|
|||
false => Err( Error { message: format!("Expected {:?} in return statement, found {:?}", header_return_types, return_statement_types)})
|
||||
}
|
||||
}
|
||||
Statement::Definition(var, expr) => {
|
||||
let checked_expr = self.check_expression(expr)?;
|
||||
|
||||
Statement::Declaration(var) => {
|
||||
self.insert_scope(var.clone());
|
||||
Ok(TypedStatement::Declaration(var))
|
||||
}
|
||||
Statement::Definition(variable_name, expr) => {
|
||||
// check the expression to be assigned
|
||||
let checked_expr = self.check_expression(&expr)?;
|
||||
let expression_type = checked_expr.get_type();
|
||||
|
||||
if expression_type != var._type {
|
||||
return Err( Error { message: format!("cannot assign {:?} to {:?}", expression_type, var._type) });
|
||||
// check that the variable is defined
|
||||
let var = match self.scope.iter().find(|v| v.id.id == variable_name) {
|
||||
Some(var) => {
|
||||
if expression_type != var.id.get_type() {
|
||||
return Err( Error { message: format!("cannot assign {:?} to {:?}", expression_type, var.id.get_type()) });
|
||||
}
|
||||
|
||||
self.scope.insert(ScopedVariable {
|
||||
id: var.clone(),
|
||||
level: self.level
|
||||
});
|
||||
Ok(TypedStatement::Definition(var, checked_expr))
|
||||
Ok(var)
|
||||
},
|
||||
None => {
|
||||
Err( Error { message: format!("Undeclared variable: {:?}", variable_name) })
|
||||
}
|
||||
}?;
|
||||
|
||||
Ok(TypedStatement::Definition(var.id.clone(), checked_expr))
|
||||
}
|
||||
Statement::Condition(lhs, rhs) => {
|
||||
let checked_lhs = self.check_expression(lhs)?;
|
||||
let checked_rhs = self.check_expression(rhs)?;
|
||||
let checked_lhs = self.check_expression(&lhs)?;
|
||||
let checked_rhs = self.check_expression(&rhs)?;
|
||||
|
||||
match (checked_lhs.clone(), checked_rhs.clone()) {
|
||||
(TypedExpression::FieldElement(_), TypedExpression::FieldElement(_)) => Ok(TypedStatement::Condition(checked_lhs, checked_rhs)),
|
||||
|
@ -176,11 +226,10 @@ impl Checker {
|
|||
}
|
||||
Statement::For(var, from, to, statements) => {
|
||||
self.level += 1;
|
||||
let index = ScopedVariable {
|
||||
id: var.clone(),
|
||||
level: self.level
|
||||
};
|
||||
self.scope.insert(index.clone());
|
||||
|
||||
self.check_for_var(&var)?;
|
||||
|
||||
self.insert_scope(var.clone());
|
||||
|
||||
let mut checked_statements = vec![];
|
||||
|
||||
|
@ -188,46 +237,59 @@ impl Checker {
|
|||
let checked_stat = self.check_statement(stat, header_return_types)?;
|
||||
checked_statements.push(checked_stat);
|
||||
}
|
||||
self.scope.remove(&index);
|
||||
|
||||
let current_level = self.level.clone();
|
||||
let current_scope = self.scope.clone();
|
||||
let to_remove = current_scope.iter().filter(|symbol| symbol.level == current_level);
|
||||
for symbol in to_remove {
|
||||
self.scope.remove(symbol);
|
||||
}
|
||||
self.level -= 1;
|
||||
|
||||
Ok(TypedStatement::For(var, from, to, checked_statements))
|
||||
},
|
||||
Statement::MultipleDefinition(vars, rhs) => {
|
||||
let vars_types: Vec<Type> = vars.iter().map(|var| var.clone()._type).collect();
|
||||
|
||||
// All elements of the left side have to be identifiers
|
||||
Statement::MultipleDefinition(var_names, rhs) => {
|
||||
match rhs {
|
||||
// Right side has to be a function call
|
||||
Expression::FunctionCall(ref fun_id, ref arguments) => {
|
||||
// check the arguments
|
||||
|
||||
// find lhs types
|
||||
let vars_types: Vec<Option<Type>> = var_names.iter().map(|name|
|
||||
match self.scope.clone().into_iter().find(|v| &v.id.id == name) {
|
||||
None => None,
|
||||
Some(sv) => Some(sv.id.get_type())
|
||||
}
|
||||
).collect();
|
||||
|
||||
// find arguments types
|
||||
let mut arguments_checked = vec![];
|
||||
for arg in arguments {
|
||||
let arg_checked = self.check_expression(arg.clone())?;
|
||||
let arg_checked = self.check_expression(arg)?;
|
||||
arguments_checked.push(arg_checked);
|
||||
}
|
||||
|
||||
let arguments_types = arguments_checked.iter().map(|a| a.get_type()).collect();
|
||||
|
||||
let mut arguments_types = vec![];
|
||||
for arg in arguments_checked.iter() {
|
||||
arguments_types.push(arg.get_type());
|
||||
}
|
||||
let candidates = self.find_candidates(fun_id, &arguments_types, &vars_types).clone();
|
||||
|
||||
match self.find_function(fun_id, &arguments_types) {
|
||||
match candidates.len() {
|
||||
// the function has to be defined
|
||||
Some(f) => {
|
||||
// the return count has to match the left side
|
||||
if f.signature.outputs == vars_types {
|
||||
for var in &vars {
|
||||
self.scope.insert(ScopedVariable {
|
||||
id: var.clone(),
|
||||
level: self.level
|
||||
});
|
||||
1 => {
|
||||
let f = &candidates[0];
|
||||
|
||||
let lhs = var_names.iter().enumerate().map(|(index, name)|
|
||||
Variable::new(name.to_string(), f.signature.outputs[index].clone())
|
||||
);
|
||||
|
||||
// we can infer the left hand side to be typed as the return values
|
||||
for var in lhs.clone() {
|
||||
self.insert_scope(var);
|
||||
}
|
||||
return Ok(TypedStatement::MultipleDefinition(vars, TypedExpressionList::FunctionCall(f.id, arguments_checked, f.signature.outputs)))
|
||||
}
|
||||
Err(Error { message: format!("{} returns {} values but left side is of size {}", f.id, f.signature.outputs.len(), vars.len()) })
|
||||
|
||||
Ok(TypedStatement::MultipleDefinition(lhs.collect(), TypedExpressionList::FunctionCall(f.id.clone(), arguments_checked, f.signature.outputs.clone())))
|
||||
},
|
||||
None => Err(Error { message: format!("Function definition for function {} with arguments {:?} not found.", fun_id, arguments_types) })
|
||||
0 => Err(Error { message: format!("Function definition for function {} with arguments {:?} not found.", fun_id, arguments_types) }),
|
||||
_ => Err(Error { message: format!("Function call for function {} with arguments {:?} is ambiguous.", fun_id, arguments_types) }),
|
||||
}
|
||||
},
|
||||
_ => Err(Error { message: format!("{} should be a FunctionCall", rhs) })
|
||||
|
@ -236,21 +298,21 @@ impl Checker {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_expression<T: Field>(&mut self, expr: Expression<T>) -> Result<TypedExpression<T>, Error> {
|
||||
fn check_expression<T: Field>(&mut self, expr: &Expression<T>) -> Result<TypedExpression<T>, Error> {
|
||||
match expr {
|
||||
Expression::Identifier(variable) => {
|
||||
&Expression::Identifier(ref variable) => {
|
||||
// check that `id` is defined in the scope
|
||||
match self.scope.iter().find(|v| v.id.id == variable) {
|
||||
Some(v) => match v.clone().id._type {
|
||||
Type::Boolean => Ok(BooleanExpression::Identifier(variable).into()),
|
||||
Type::FieldElement => Ok(FieldElementExpression::Identifier(variable).into()),
|
||||
match self.scope.iter().find(|v| v.id.id == variable.to_string()) {
|
||||
Some(v) => match v.clone().id.get_type() {
|
||||
Type::Boolean => Ok(BooleanExpression::Identifier(variable.to_string()).into()),
|
||||
Type::FieldElement => Ok(FieldElementExpression::Identifier(variable.to_string()).into()),
|
||||
},
|
||||
None => Err(Error { message: format!("{} is undefined", variable.to_string()) }),
|
||||
}
|
||||
},
|
||||
Expression::Add(box e1, box e2) => {
|
||||
let e1_checked = self.check_expression(e1)?;
|
||||
let e2_checked = self.check_expression(e2)?;
|
||||
&Expression::Add(ref e1, ref e2) => {
|
||||
let e1_checked = self.check_expression(&e1)?;
|
||||
let e2_checked = self.check_expression(&e2)?;
|
||||
|
||||
match (e1_checked, e2_checked) {
|
||||
(TypedExpression::FieldElement(e1), TypedExpression::FieldElement(e2)) => {
|
||||
|
@ -259,9 +321,9 @@ impl Checker {
|
|||
(t1, t2) => Err(Error { message: format!("Expected only field elements, found {:?}, {:?}", t1.get_type(), t2.get_type()) }),
|
||||
}
|
||||
},
|
||||
Expression::Sub(box e1, box e2) => {
|
||||
let e1_checked = self.check_expression(e1)?;
|
||||
let e2_checked = self.check_expression(e2)?;
|
||||
&Expression::Sub(ref e1, ref e2) => {
|
||||
let e1_checked = self.check_expression(&e1)?;
|
||||
let e2_checked = self.check_expression(&e2)?;
|
||||
|
||||
match (e1_checked, e2_checked) {
|
||||
(TypedExpression::FieldElement(e1), TypedExpression::FieldElement(e2)) => {
|
||||
|
@ -270,9 +332,9 @@ impl Checker {
|
|||
(t1, t2) => Err(Error { message: format!("Expected only field elements, found {:?}, {:?}", t1.get_type(), t2.get_type()) }),
|
||||
}
|
||||
},
|
||||
Expression::Mult(box e1, box e2) => {
|
||||
let e1_checked = self.check_expression(e1)?;
|
||||
let e2_checked = self.check_expression(e2)?;
|
||||
&Expression::Mult(ref e1, ref e2) => {
|
||||
let e1_checked = self.check_expression(&e1)?;
|
||||
let e2_checked = self.check_expression(&e2)?;
|
||||
|
||||
match (e1_checked, e2_checked) {
|
||||
(TypedExpression::FieldElement(e1), TypedExpression::FieldElement(e2)) => {
|
||||
|
@ -281,9 +343,9 @@ impl Checker {
|
|||
(t1, t2) => Err(Error { message: format!("Expected only field elements, found {:?}, {:?}", t1.get_type(), t2.get_type()) }),
|
||||
}
|
||||
},
|
||||
Expression::Div(box e1, box e2) => {
|
||||
let e1_checked = self.check_expression(e1)?;
|
||||
let e2_checked = self.check_expression(e2)?;
|
||||
&Expression::Div(ref e1, ref e2) => {
|
||||
let e1_checked = self.check_expression(&e1)?;
|
||||
let e2_checked = self.check_expression(&e2)?;
|
||||
|
||||
match (e1_checked, e2_checked) {
|
||||
(TypedExpression::FieldElement(e1), TypedExpression::FieldElement(e2)) => {
|
||||
|
@ -292,9 +354,9 @@ impl Checker {
|
|||
(t1, t2) => Err(Error { message: format!("Expected only field elements, found {:?}, {:?}", t1.get_type(), t2.get_type()) }),
|
||||
}
|
||||
},
|
||||
Expression::Pow(box e1, box e2) => {
|
||||
let e1_checked = self.check_expression(e1)?;
|
||||
let e2_checked = self.check_expression(e2)?;
|
||||
&Expression::Pow(ref e1, ref e2) => {
|
||||
let e1_checked = self.check_expression(&e1)?;
|
||||
let e2_checked = self.check_expression(&e2)?;
|
||||
|
||||
match (e1_checked, e2_checked) {
|
||||
(TypedExpression::FieldElement(e1), TypedExpression::FieldElement(e2)) => {
|
||||
|
@ -303,10 +365,10 @@ impl Checker {
|
|||
(t1, t2) => Err(Error { message: format!("Expected only field elements, found {:?}, {:?}", t1.get_type(), t2.get_type()) }),
|
||||
}
|
||||
},
|
||||
Expression::IfElse(box condition, box consequence, box alternative) => {
|
||||
&Expression::IfElse(ref condition, ref consequence, ref alternative) => {
|
||||
let condition_checked = self.check_condition(&condition)?;
|
||||
let consequence_checked = self.check_expression(consequence)?;
|
||||
let alternative_checked = self.check_expression(alternative)?;
|
||||
let consequence_checked = self.check_expression(&consequence)?;
|
||||
let alternative_checked = self.check_expression(&alternative)?;
|
||||
|
||||
match (condition_checked, consequence_checked, alternative_checked) {
|
||||
(condition, TypedExpression::FieldElement(consequence), TypedExpression::FieldElement(alternative)) => {
|
||||
|
@ -315,12 +377,12 @@ impl Checker {
|
|||
_ => panic!("id else only for bool fe fe")
|
||||
}
|
||||
},
|
||||
Expression::Number(n) => Ok(FieldElementExpression::Number(n).into()),
|
||||
Expression::FunctionCall(ref fun_id, ref arguments) => {
|
||||
&Expression::Number(ref n) => Ok(FieldElementExpression::Number(n.clone()).into()),
|
||||
&Expression::FunctionCall(ref fun_id, ref arguments) => {
|
||||
// check the arguments
|
||||
let mut arguments_checked = vec![];
|
||||
for arg in arguments {
|
||||
let arg_checked = self.check_expression(arg.clone())?;
|
||||
let arg_checked = self.check_expression(&arg.clone())?;
|
||||
arguments_checked.push(arg_checked);
|
||||
}
|
||||
|
||||
|
@ -330,19 +392,25 @@ impl Checker {
|
|||
arguments_types.push(arg.get_type());
|
||||
}
|
||||
|
||||
match self.find_function(fun_id, &arguments_types) {
|
||||
// outside of multidef, function calls must have a single return value
|
||||
// we use type inference to determine the type of the return, so we don't specify it
|
||||
let candidates = self.find_candidates(fun_id, &arguments_types, &vec![None]);
|
||||
|
||||
match candidates.len() {
|
||||
// the function has to be defined
|
||||
Some(f) => {
|
||||
1 => {
|
||||
let f = &candidates[0];
|
||||
// the return count has to be 1
|
||||
if f.signature.outputs.len() == 1 {
|
||||
match f.signature.outputs[0] {
|
||||
Type::FieldElement => return Ok(FieldElementExpression::FunctionCall(f.id, arguments_checked).into()),
|
||||
Type::FieldElement => return Ok(FieldElementExpression::FunctionCall(f.id.clone(), arguments_checked).into()),
|
||||
_ => panic!("cannot return booleans")
|
||||
}
|
||||
}
|
||||
Err(Error { message: format!("{} returns {} values but is called outside of a definition", f.id, f.signature.outputs.len()) })
|
||||
},
|
||||
None => Err(Error { message: format!("Function definition for function {} with arguments {:?} not found.", fun_id, arguments_types) })
|
||||
0 => Err(Error { message: format!("Function definition for function {} with arguments {:?} not found.", fun_id, arguments_types) }),
|
||||
_ => panic!("duplicate definition should have been caught before the call")
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -351,8 +419,8 @@ impl Checker {
|
|||
fn check_condition<T: Field>(&mut self, cond: &Condition<T>) -> Result<BooleanExpression<T>, Error> {
|
||||
match cond.clone() {
|
||||
Condition::Lt(e1, e2) => {
|
||||
let e1_checked = self.check_expression(e1)?;
|
||||
let e2_checked = self.check_expression(e2)?;
|
||||
let e1_checked = self.check_expression(&e1)?;
|
||||
let e2_checked = self.check_expression(&e2)?;
|
||||
match (e1_checked, e2_checked) {
|
||||
(TypedExpression::FieldElement(e1), TypedExpression::FieldElement(e2)) => {
|
||||
Ok(BooleanExpression::Lt(box e1, box e2))
|
||||
|
@ -361,8 +429,8 @@ impl Checker {
|
|||
}
|
||||
},
|
||||
Condition::Le(e1, e2) => {
|
||||
let e1_checked = self.check_expression(e1)?;
|
||||
let e2_checked = self.check_expression(e2)?;
|
||||
let e1_checked = self.check_expression(&e1)?;
|
||||
let e2_checked = self.check_expression(&e2)?;
|
||||
match (e1_checked, e2_checked) {
|
||||
(TypedExpression::FieldElement(e1), TypedExpression::FieldElement(e2)) => {
|
||||
Ok(BooleanExpression::Le(box e1, box e2))
|
||||
|
@ -371,8 +439,8 @@ impl Checker {
|
|||
}
|
||||
},
|
||||
Condition::Eq(e1, e2) => {
|
||||
let e1_checked = self.check_expression(e1)?;
|
||||
let e2_checked = self.check_expression(e2)?;
|
||||
let e1_checked = self.check_expression(&e1)?;
|
||||
let e2_checked = self.check_expression(&e2)?;
|
||||
match (e1_checked, e2_checked) {
|
||||
(TypedExpression::FieldElement(e1), TypedExpression::FieldElement(e2)) => {
|
||||
Ok(BooleanExpression::Eq(box e1, box e2))
|
||||
|
@ -381,8 +449,8 @@ impl Checker {
|
|||
}
|
||||
},
|
||||
Condition::Ge(e1, e2) => {
|
||||
let e1_checked = self.check_expression(e1)?;
|
||||
let e2_checked = self.check_expression(e2)?;
|
||||
let e1_checked = self.check_expression(&e1)?;
|
||||
let e2_checked = self.check_expression(&e2)?;
|
||||
match (e1_checked, e2_checked) {
|
||||
(TypedExpression::FieldElement(e1), TypedExpression::FieldElement(e2)) => {
|
||||
Ok(BooleanExpression::Ge(box e1, box e2))
|
||||
|
@ -391,8 +459,8 @@ impl Checker {
|
|||
}
|
||||
},
|
||||
Condition::Gt(e1, e2) => {
|
||||
let e1_checked = self.check_expression(e1)?;
|
||||
let e2_checked = self.check_expression(e2)?;
|
||||
let e1_checked = self.check_expression(&e1)?;
|
||||
let e2_checked = self.check_expression(&e2)?;
|
||||
match (e1_checked, e2_checked) {
|
||||
(TypedExpression::FieldElement(e1), TypedExpression::FieldElement(e2)) => {
|
||||
Ok(BooleanExpression::Gt(box e1, box e2))
|
||||
|
@ -403,11 +471,20 @@ impl Checker {
|
|||
}
|
||||
}
|
||||
|
||||
fn find_function(&mut self, id: &str, arg_types: &Vec<Type>) -> Option<FunctionDeclaration> {
|
||||
self.functions.clone().into_iter().find(|fun| {
|
||||
fun.id == id && fun.signature.inputs.len() == arg_types.len()
|
||||
fn insert_scope(&mut self, v: Variable) -> bool {
|
||||
println!("var!");
|
||||
self.scope.insert(ScopedVariable {
|
||||
id: v,
|
||||
level: self.level
|
||||
})
|
||||
}
|
||||
|
||||
fn find_candidates(&self, id: &str, arg_types: &Vec<Type>, return_types: &Vec<Option<Type>>) -> Vec<FunctionDeclaration> {
|
||||
|
||||
let query = FunctionQuery::new(String::from(id), arg_types, return_types);
|
||||
|
||||
query.match_funcs(self.functions.clone().into_iter().collect())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -429,7 +506,7 @@ mod tests {
|
|||
// a = b
|
||||
// b undefined
|
||||
let statement: Statement<FieldPrime> = Statement::Definition(
|
||||
Variable::field_element("a"),
|
||||
String::from("a"),
|
||||
Expression::Identifier(String::from("b"))
|
||||
);
|
||||
let mut checker = Checker::new();
|
||||
|
@ -441,10 +518,14 @@ mod tests {
|
|||
// a = b
|
||||
// b defined
|
||||
let statement: Statement<FieldPrime> = Statement::Definition(
|
||||
Variable::field_element("a"),
|
||||
String::from("a"),
|
||||
Expression::Identifier(String::from("b"))
|
||||
);
|
||||
let mut scope = HashSet::new();
|
||||
scope.insert(ScopedVariable {
|
||||
id: Variable::field_element("a"),
|
||||
level: 0
|
||||
});
|
||||
scope.insert(ScopedVariable {
|
||||
id: Variable::field_element("b"),
|
||||
level: 0
|
||||
|
@ -463,14 +544,17 @@ mod tests {
|
|||
#[test]
|
||||
fn declared_in_other_function() {
|
||||
// def foo():
|
||||
// a = 1
|
||||
// field a = 1
|
||||
// def bar():
|
||||
// return a
|
||||
// should fail
|
||||
let foo_args = Vec::<Parameter>::new();
|
||||
let mut foo_statements = Vec::<Statement<FieldPrime>>::new();
|
||||
foo_statements.push(Statement::Declaration(
|
||||
Variable::field_element("a")
|
||||
));
|
||||
foo_statements.push(Statement::Definition(
|
||||
Variable::field_element("a"),
|
||||
String::from("a"),
|
||||
Expression::Number(FieldPrime::from(1)))
|
||||
);
|
||||
let foo = Function {
|
||||
|
@ -525,8 +609,11 @@ mod tests {
|
|||
// should pass
|
||||
let foo_args = vec![];
|
||||
let foo_statements = vec![
|
||||
Statement::Declaration(
|
||||
Variable::field_element("a")
|
||||
),
|
||||
Statement::Definition(
|
||||
Variable::field_element("a"),
|
||||
String::from("a"),
|
||||
Expression::Number(FieldPrime::from(1)))
|
||||
];
|
||||
|
||||
|
@ -542,8 +629,11 @@ mod tests {
|
|||
|
||||
let bar_args = Vec::<Parameter>::new();
|
||||
let bar_statements = vec![
|
||||
Statement::Declaration(
|
||||
Variable::field_element("a")
|
||||
),
|
||||
Statement::Definition(
|
||||
Variable::field_element("a"),
|
||||
String::from("a"),
|
||||
Expression::Number(FieldPrime::from(2))
|
||||
),
|
||||
Statement::Return(
|
||||
|
@ -597,7 +687,7 @@ mod tests {
|
|||
#[test]
|
||||
fn for_index_after_end() {
|
||||
// def foo():
|
||||
// for i in 0..10 do
|
||||
// for field i in 0..10 do
|
||||
// endfor
|
||||
// return i
|
||||
// should fail
|
||||
|
@ -636,8 +726,11 @@ mod tests {
|
|||
// should pass
|
||||
let mut foo_statements = Vec::<Statement<FieldPrime>>::new();
|
||||
let mut for_statements = Vec::<Statement<FieldPrime>>::new();
|
||||
for_statements.push(Statement::Declaration(
|
||||
Variable::field_element("a")
|
||||
));
|
||||
for_statements.push(Statement::Definition(
|
||||
Variable::field_element("a"),
|
||||
String::from("a"),
|
||||
Expression::Identifier(String::from("i"))
|
||||
));
|
||||
foo_statements.push(Statement::For(
|
||||
|
@ -650,6 +743,10 @@ mod tests {
|
|||
let mut foo_statements_checked = Vec::<TypedStatement<FieldPrime>>::new();
|
||||
let mut for_statements_checked = Vec::<TypedStatement<FieldPrime>>::new();
|
||||
|
||||
for_statements_checked.push(TypedStatement::Declaration(
|
||||
Variable::field_element("a")
|
||||
));
|
||||
|
||||
for_statements_checked.push(TypedStatement::Definition(
|
||||
Variable::field_element("a"),
|
||||
FieldElementExpression::Identifier(String::from("i")).into()
|
||||
|
@ -692,12 +789,16 @@ mod tests {
|
|||
// def foo():
|
||||
// return 1, 2
|
||||
// def bar():
|
||||
// c = foo()
|
||||
// field c = foo()
|
||||
// should fail
|
||||
let bar_statements: Vec<Statement<FieldPrime>> = vec![Statement::MultipleDefinition(
|
||||
vec![Variable::field_element("a")],
|
||||
Expression::FunctionCall("foo".to_string(), vec![])
|
||||
)];
|
||||
let bar_statements: Vec<Statement<FieldPrime>> = vec![
|
||||
Statement::Declaration(
|
||||
Variable::field_element("a")
|
||||
),
|
||||
Statement::MultipleDefinition(
|
||||
vec![String::from("a")],
|
||||
Expression::FunctionCall("foo".to_string(), vec![]))
|
||||
];
|
||||
|
||||
let foo = FunctionDeclaration {
|
||||
id: "foo".to_string(),
|
||||
|
@ -764,12 +865,16 @@ mod tests {
|
|||
#[test]
|
||||
fn function_undefined_in_multidef() {
|
||||
// def bar():
|
||||
// c = foo()
|
||||
// field a = foo()
|
||||
// should fail
|
||||
let bar_statements: Vec<Statement<FieldPrime>> = vec![Statement::MultipleDefinition(
|
||||
vec![Variable::field_element("a")],
|
||||
Expression::FunctionCall("foo".to_string(), vec![])
|
||||
)];
|
||||
let bar_statements: Vec<Statement<FieldPrime>> = vec![
|
||||
Statement::Declaration(
|
||||
Variable::field_element("a")
|
||||
),
|
||||
Statement::MultipleDefinition(
|
||||
vec![String::from("a")],
|
||||
Expression::FunctionCall("foo".to_string(), vec![]))
|
||||
];
|
||||
|
||||
let bar = Function {
|
||||
id: "bar".to_string(),
|
||||
|
@ -814,8 +919,14 @@ mod tests {
|
|||
};
|
||||
|
||||
let main_statements: Vec<Statement<FieldPrime>> = vec![
|
||||
Statement::Declaration(
|
||||
Variable::field_element("a")
|
||||
),
|
||||
Statement::Declaration(
|
||||
Variable::field_element("b")
|
||||
),
|
||||
Statement::MultipleDefinition(
|
||||
vec![Variable::field_element("a"), Variable::field_element("b")],
|
||||
vec![String::from("a"), String::from("b")],
|
||||
Expression::FunctionCall("foo".to_string(), vec![
|
||||
Expression::Identifier("x".to_string())
|
||||
])
|
||||
|
@ -902,13 +1013,19 @@ mod tests {
|
|||
// def foo():
|
||||
// return 1, 2
|
||||
// def bar():
|
||||
// a, b = foo()
|
||||
// field a, field b = foo()
|
||||
// return a + b
|
||||
//
|
||||
// should pass
|
||||
let bar_statements: Vec<Statement<FieldPrime>> = vec![
|
||||
Statement::Declaration(
|
||||
Variable::field_element("a")
|
||||
),
|
||||
Statement::Declaration(
|
||||
Variable::field_element("b")
|
||||
),
|
||||
Statement::MultipleDefinition(
|
||||
vec![Variable::field_element("a"), Variable::field_element("b")],
|
||||
vec![String::from("a"), String::from("b")],
|
||||
Expression::FunctionCall("foo".to_string(), vec![])
|
||||
),
|
||||
Statement::Return(
|
||||
|
|
|
@ -123,6 +123,7 @@ impl<T: Field> fmt::Debug for TypedFunction<T> {
|
|||
pub enum TypedStatement<T: Field> {
|
||||
Return(Vec<TypedExpression<T>>),
|
||||
Definition(Variable, TypedExpression<T>),
|
||||
Declaration(Variable),
|
||||
Condition(TypedExpression<T>, TypedExpression<T>),
|
||||
For(Variable, T, T, Vec<TypedStatement<T>>),
|
||||
MultipleDefinition(Vec<Variable>, TypedExpressionList<T>),
|
||||
|
@ -141,6 +142,9 @@ impl<T: Field> fmt::Debug for TypedStatement<T> {
|
|||
}
|
||||
write!(f, ")")
|
||||
},
|
||||
TypedStatement::Declaration(ref var) => {
|
||||
write!(f, "Declaration({:?})", var)
|
||||
}
|
||||
TypedStatement::Definition(ref lhs, ref rhs) => {
|
||||
write!(f, "Definition({:?}, {:?})", lhs, rhs)
|
||||
}
|
||||
|
@ -173,6 +177,7 @@ impl<T: Field> fmt::Display for TypedStatement<T> {
|
|||
}
|
||||
write!(f, "")
|
||||
},
|
||||
TypedStatement::Declaration(ref var) => write!(f, "{}", var),
|
||||
TypedStatement::Definition(ref lhs, ref rhs) => write!(f, "{} = {}", lhs, rhs),
|
||||
TypedStatement::Condition(ref lhs, ref rhs) => write!(f, "{} == {}", lhs, rhs),
|
||||
TypedStatement::For(ref var, ref start, ref stop, ref list) => {
|
||||
|
|
Loading…
Reference in a new issue