Example #1
0
def test_func_args():
    scope = TEST_SCOPE
    code = """\
struct T:
    member s : felt
    member t : felt
end
func f(x, y : T, z : T*):
    x = 1; ap++
    y.s = 2; ap++
    z.t = y.t; ap++
    ret
end
"""
    program = preprocess_str(code=code, prime=PRIME, main_scope=scope)
    reference_x = program.instructions[-1].flow_tracking_data.resolve_reference(
        reference_manager=program.reference_manager, name=scope + 'f.x')
    assert reference_x.value.format() == 'cast([fp + (-6)], felt)'
    reference_y = program.instructions[-1].flow_tracking_data.resolve_reference(
        reference_manager=program.reference_manager, name=scope + 'f.y')
    assert reference_y.value.format() == f'cast([fp + (-5)], {scope}.T)'
    reference_z = program.instructions[-1].flow_tracking_data.resolve_reference(
        reference_manager=program.reference_manager, name=scope + 'f.z')
    assert reference_z.value.format() == f'cast([fp + (-3)], {scope}.T*)'
    assert program.format() == """\
Example #2
0
def test_references():
    program = preprocess_str(code="""
call label1
label1:
ret

let x = ap + 1
label2:
[x] = 1; ap++
[x + 3] = 2; ap++
[x - 2] = 3; ap++
[x - 2] = 3; ap++
jmp label1 if [x] != 0; ap++
jmp label3 if [x] != 0
[x - 2] = 4
[x - 4] = 5
[x - 6] = 6; ap++
[ap] = [ap]; ap++
ap += 4
[x] = 7

call label3
label3:
ret

let y = ap
[y] = 0; ap++
[y] = 0; ap++
""", prime=PRIME)
    assert program.format() == """\
Example #3
0
def test_reference_type_deduction():
    scope = TEST_SCOPE
    program = preprocess_str(code="""
struct T:
    member t : felt
end

func foo():
    let a = cast(0, T***)
    tempvar b = [a]
    tempvar c : felt* = [a]
    let d = [b]
    let e : felt* = [b]
    return ()
end
""", prime=PRIME, main_scope=scope)

    def get_reference_type(name):
        identifier_definition = program.identifiers.get_by_full_name(scope + name)
        assert isinstance(identifier_definition, ReferenceDefinition)
        assert len(identifier_definition.references) == 1
        _, expr_type = simplify_type_system(identifier_definition.references[0].value)
        return expr_type

    assert get_reference_type('foo.a').format() == f'{scope}.T***'
    assert get_reference_type('foo.b').format() == f'{scope}.T**'
    assert get_reference_type('foo.c').format() == 'felt*'
    assert get_reference_type('foo.d').format() == f'{scope}.T*'
    assert get_reference_type('foo.e').format() == 'felt*'
Example #4
0
def test_hints_unindent():
    before = """\
  %{
      hint1
      hint2
%}
[fp] = [fp]
func f():
  %{
       if a:
           b
%}
[fp] = [fp]
ret
end
"""
    after = """\
%{
    hint1
    hint2
%}
[fp] = [fp]
%{
    if a:
        b
%}
[fp] = [fp]
ret
"""
    program = preprocess_str(code=before, prime=PRIME)
    assert program.format() == after
def test_compound_expressions_args():
    code = """\
func foo(a, b, c, d) -> (x, y):
  return (a + b, c * c + d)
end

tempvar x = 5
foo(x + x, x + x * x, x, 3 * x + x * x)
"""
    program = preprocess_str(code=code, prime=PRIME)
    expected_result = """\
[ap] = [fp + (-4)] * [fp + (-4)]; ap++     # Compute c * c.
[ap] = [fp + (-6)] + [fp + (-5)]; ap++     # Push a + b.
[ap] = [ap + (-2)] + [fp + (-3)]; ap++     # Push c * c + d.
ret

[ap] = 5; ap++

[ap] = [ap + (-1)] * [ap + (-1)]; ap++     # Compute x * x.
[ap] = 3; ap++
[ap] = [ap + (-1)] * [ap + (-3)]; ap++     # Compute 3 * x.
[ap] = [ap + (-4)] * [ap + (-4)]; ap++     # Compute x * x.
[ap] = [ap + (-5)] + [ap + (-5)]; ap++     # Push x + x.
[ap] = [ap + (-6)] + [ap + (-5)]; ap++     # Push x + x * x.
[ap] = [ap + (-7)]; ap++                   # Push x.
[ap] = [ap + (-5)] + [ap + (-4)]; ap++     # Push 3 * x + x * x.
call rel -15
"""
    assert program.format() == re.sub(r'\s*#.*\n', '\n',
                                      expected_result).replace('\n\n', '\n')
def test_local_variable():
    code = """\
struct MyStruct:
    member a : felt
    member b : felt
end

func main():
    ap += 5 + SIZEOF_LOCALS
    local x
    local y : MyStruct
    local z = x * y.a
    x = y.a
    y.b = z
    local w : MyStruct* = cast(17, MyStruct*)
    # Check implicit cast from MyStruct* to felt*.
    local w_as_felt_ptr : felt* = w
    z = w.b
    ret
end

func no_locals():
    ap += SIZEOF_LOCALS
    ret
end
"""
    program = preprocess_str(code=code, prime=PRIME)
    assert program.format() == """\
def test_unique_label_creator():
    program = preprocess_str(code="""
namespace B:
    func foo(x, y) -> (res):
        if x == 0:
            if y == 0:
                return (res=0)
            else:
                return (res=1)
            end
        else:
            if y == 0:
                return (res=2)
            else:
                return (res=3)
            end
        end
    end
end
func main():
    B.foo(1, 2)
    ret
end
""",
                             prime=PRIME)
    assert program.format() == """\
Example #8
0
def test_static_assert():
    code = """\
static_assert 3 + fp + 10 == 0 + fp + 13
let x = ap
ap += 3
static_assert x + 7 == ap + 4
"""
    program = preprocess_str(code=code, prime=PRIME)
    assert program.format() == """\
Example #9
0
def test_process_file_scope():
    # Verify the good scenario.
    valid_scope = ScopedName.from_string('some.valid.scope')
    program = preprocess_str('const x = 4', prime=PRIME, main_scope=valid_scope)

    module = CairoModule(cairo_file=program, module_name=valid_scope)
    assert program.identifiers.as_dict() == {
        valid_scope + 'x': ConstDefinition(4)
    }
def test_n_locals_used_in_static_assert():
    code = """\
func main():
    static_assert 3 == SIZEOF_LOCALS + 2
    local x
    ret
end
"""
    program = preprocess_str(code=code, prime=PRIME)
    assert program.format() == """\
Example #11
0
def test_assign_future_label():
    code = """\
[ap] = future_label2 - future_label1; ap++
[ap] = future_label1; ap++
future_label1:
[ap] = future_label2; ap++
future_label2:
[ap] = 8; ap++
"""
    program = preprocess_str(code=code, prime=PRIME)
    assert program.format() == """\
Example #12
0
def test_directives():
    program = preprocess_str(code="""\
# This is a comment.


%builtins ab cd ef

[fp] = [fp]
""", prime=PRIME)
    assert program.builtins == ['ab', 'cd', 'ef']
    assert program.format() == """\
Example #13
0
def test_reference_flow_converge():
    program = preprocess_str("""
if [ap] != 0:
    tempvar a = 1
else:
    tempvar a = 2
end

assert a = a
""", prime=PRIME)
    assert program.format() == """\
Example #14
0
def test_hints():
    code = """\
%{ hint0 %}
[fp] = [fp]
%{
    hint1
    hint2
%}
[fp] = [fp]
"""
    program = preprocess_str(code=code, prime=PRIME)
    assert program.format() == code
Example #15
0
def test_tail_call():
    code = """\
func f(a) -> (a):
    return f(a)
end
func g(a, b) -> (a):
    return f(a)
end
"""
    program = preprocess_str(
        code=code, prime=PRIME, main_scope=ScopedName.from_string('test_scope'))
    assert program.format() == """\
Example #16
0
def test_func_by_value_return():
    code = """\
struct T:
    member s : felt
    member t : felt
end
func f(s : T) -> (x : T, y : T):
    let t : T = cast([ap - 100], T)
    return(x=s, y=t)
end
"""
    program = preprocess_str(code=code, prime=PRIME)
    assert program.format() == """\
def test_compound_expressions_tempvars():
    code = """\
tempvar x = [ap - 1] * [ap - 1] + [ap - 1] * [ap - 2]
tempvar y = x + x
"""
    program = preprocess_str(code=code, prime=PRIME)
    assert program.format() == """\
[ap] = [ap + (-1)] * [ap + (-1)]; ap++
[ap] = [ap + (-2)] * [ap + (-3)]; ap++
[ap] = [ap + (-2)] + [ap + (-1)]; ap++

[ap] = [ap + (-1)] + [ap + (-1)]; ap++
""".replace('\n\n', '\n')
Example #18
0
def test_implcit_argument_bindings():
    code = """\
func f{x, y}():
    ret
end

func g{x, y, z}():
    f{y=z}()
    return ()
end
"""
    program = preprocess_str(code=code, prime=PRIME)
    assert program.format() == """\
def test_local_rebinding():
    code = """\
func main():
    alloc_locals
    local x = 5
    local x = x * x
    local x = x + x
    local x = x * x
    ret
end
"""
    program = preprocess_str(code=code, prime=PRIME)
    assert program.format() == """\
Example #20
0
def test_function_call_by_value_args():
    code = """\
struct T:
    member s : felt
    member t : felt
end
func f(x, y : T, z : T):
    let t : T = cast([ap], T)
    let res = f(x=2, y=z, z=t)
    return()
end
"""
    program = preprocess_str(code=code, prime=PRIME)
    assert program.format() == """\
Example #21
0
def test_reference_flow_revokes(valid, has0, has1, has2):
    def0 = 'let ref = [fp]' if has0 else ''
    def1 = 'let ref = [fp + 1]' if has1 else ''
    def2 = 'let ref = [fp + 2]' if has2 else ''
    code = f"""
{def0}
jmp b if [ap] != 0
a:
{def1}
jmp c
b:
{def2}
c:
[ref] = [fp + 3]
"""
    if valid:
        preprocess_str(code, prime=PRIME)
    else:
        verify_exception(code, """
file:?:?: Reference 'ref' was revoked.
[ref] = [fp + 3]
 ^*^
""")
Example #22
0
def test_with_statement():
    code = """
let x = 1000
[ap] = 0
with x:
    [ap] = 1
    [ap] = 2
    [ap] = x
    let x = 1001
end
[ap] = x
"""
    program = preprocess_str(code=code, prime=PRIME)
    assert program.format() == """\
Example #23
0
def test_temporary_variable():
    code = """\
struct T:
    member pad0 : felt
    member t : felt
end
tempvar x = [ap - 1] + [fp - 3]
ap += 3
tempvar y : T* = cast(x, T*)
ap += 4
[fp] = y.t
"""
    program = preprocess_str(code=code, prime=PRIME)
    assert program.format() == """\
def test_compound_expressions():
    code = """\
assert [ap] = [ap + 1] * [ap + 2]
assert 5 = [[ap - 1]]
assert [[ap - 1]] = 5
assert [ap - 2] = [[ap - 1] - 5]
assert [ap - 2] = [[ap - 1] + 999999]
assert [[ap + 5 + 5]] = [ap - 1]
assert [ap - 1] = [[[ap + 5 + 5]]]
assert [[ap - 1]] = [[ap - 2]]

tempvar __fp__ = 100
assert [fp] = fp + [fp + [fp]]

let __fp__ = [ap - 1] + [ap - 1]
assert [fp] = fp + fp
"""
    program = preprocess_str(code=code, prime=PRIME)
    assert program.format() == """\
[ap] = [ap + 1] * [ap + 2]

[ap] = [[ap + (-1)]]; ap++
5 = [ap + (-1)]

[ap] = 5; ap++
[[ap + (-2)]] = [ap + (-1)]

[ap + (-2)] = [[ap + (-1)] + (-5)]

[ap] = [ap + (-1)] + 999999; ap++
[ap + (-3)] = [[ap + (-1)]]

[[ap + 10]] = [ap + (-1)]

[ap] = [[ap + 10]]; ap++
[ap + (-2)] = [[ap + (-1)]]

[ap] = [[ap + (-2)]]; ap++
[[ap + (-2)]] = [ap + (-1)]

[ap] = 100; ap++
[ap] = [ap + (-1)] + [fp]; ap++
[ap] = [[ap + (-1)]]; ap++
[fp] = [ap + (-3)] + [ap + (-1)]

[ap] = [ap + (-1)] + [ap + (-1)]; ap++
[ap] = [ap + (-2)] + [ap + (-2)]; ap++
[fp] = [ap + (-2)] + [ap + (-1)]
""".replace('\n\n', '\n')
Example #25
0
def test_scope_const():
    code = """\
const x = 5
[ap] = x; ap++
func f():
    const x = 1234
    [ap + 1] = x; ap++
    [ap + 2] = f.x; ap++
    ret
end
[ap + 3] = x; ap++
[ap + 4] = f.x; ap++
"""
    program = preprocess_str(code=code, prime=PRIME)
    assert program.format() == """\
Example #26
0
def test_func_args_scope():
    code = """\
const x = 1234
[ap] = x; ap++
func f(x, y, z):
    x = 1; ap++
    y = 2; ap++
    z = 3; ap++
    ret
end
[ap + 4] = x; ap++
[ap + 5] = f.Args.z; ap++
"""
    program = preprocess_str(code=code, prime=PRIME)
    assert program.format() == """\
Example #27
0
def test_func_named_args():
    code = """\
func f(x, y, z):
    ret
end

let f_args = cast(ap, f.Args*)
f_args.z = 2; ap++
f_args.x = 0; ap++
f_args.y = 1; ap++
static_assert f_args + f.Args.SIZE == ap
call f
"""
    program = preprocess_str(code=code, prime=PRIME)
    assert program.format() == """\
Example #28
0
def test_rebind_reference():
    program = preprocess_str(code="""
struct T:
    member pad0 : felt
    member pad1 : felt
    member t : felt
end

let x : T* = cast(ap + 1, T*)
let y = &x.t
[cast(x, felt)] = x.t
let x : T* = cast(fp - 3, T*)
[cast(x, felt)] = x.t
[y] = [y]
""", prime=PRIME)
    assert program.format() == """\
Example #29
0
def test_function_call():
    code = """\
func foo(a, b) -> (c):
    bar(a=a)
    return (1)
end
func bar(a):
    return ()
end
foo(2, 3)
foo(2, b=3)
let res = foo(a=2, b=3)
res.c = 1
"""
    program = preprocess_str(code=code, prime=PRIME)
    assert program.format() == """\
Example #30
0
def test_func_args_and_rets_scope():
    code = """\
const x = 1234
[ap] = x; ap++
func f(x, y, z) -> (a, b, x):
    x = 1; ap++
    y = 2; ap++
    [ap] = Return.b; ap++
    ret
end
[ap + 4] = x; ap++
[ap + 5] = f.Args.x; ap++
[ap + 6] = f.Return.x; ap++
"""
    program = preprocess_str(code=code, prime=PRIME)
    assert program.format() == """\