mirror of
https://github.com/roc-lang/roc.git
synced 2025-12-23 08:48:03 +00:00
Merge pull request #8331 from roc-lang/for-loops
`for` loops in the interpreter
This commit is contained in:
commit
2b89aee96b
20 changed files with 1496 additions and 0 deletions
|
|
@ -509,6 +509,77 @@ pub const Interpreter = struct {
|
|||
.s_expr => |sx| {
|
||||
_ = try self.evalExprMinimal(sx.expr, roc_ops, null);
|
||||
},
|
||||
.s_for => |for_stmt| {
|
||||
// Evaluate the list expression
|
||||
const expr_ct_var = can.ModuleEnv.varFrom(for_stmt.expr);
|
||||
const expr_rt_var = try self.translateTypeVar(self.env, expr_ct_var);
|
||||
const list_value = try self.evalExprMinimal(for_stmt.expr, roc_ops, expr_rt_var);
|
||||
defer list_value.decref(&self.runtime_layout_store, roc_ops);
|
||||
|
||||
// Get the list layout
|
||||
if (list_value.layout.tag != .list) {
|
||||
return error.TypeMismatch;
|
||||
}
|
||||
const elem_layout_idx = list_value.layout.data.list;
|
||||
const elem_layout = self.runtime_layout_store.getLayout(elem_layout_idx);
|
||||
const elem_size: usize = @intCast(self.runtime_layout_store.layoutSize(elem_layout));
|
||||
|
||||
// Get the RocList header
|
||||
const list_header: *const RocList = @ptrCast(@alignCast(list_value.ptr.?));
|
||||
const list_len = list_header.len();
|
||||
|
||||
// Get the element type for binding
|
||||
const patt_ct_var = can.ModuleEnv.varFrom(for_stmt.patt);
|
||||
const patt_rt_var = try self.translateTypeVar(self.env, patt_ct_var);
|
||||
|
||||
// Iterate over each element
|
||||
var i: usize = 0;
|
||||
while (i < list_len) : (i += 1) {
|
||||
// Get pointer to element
|
||||
const elem_ptr = if (list_header.bytes) |buffer|
|
||||
buffer + i * elem_size
|
||||
else
|
||||
return error.TypeMismatch;
|
||||
|
||||
// Create a StackValue from the element
|
||||
var elem_value = StackValue{
|
||||
.ptr = elem_ptr,
|
||||
.layout = elem_layout,
|
||||
.is_initialized = true,
|
||||
};
|
||||
|
||||
// Increment refcount since we're creating a new reference
|
||||
elem_value.incref();
|
||||
|
||||
// Bind the pattern to the element value
|
||||
var temp_binds = try std.array_list.AlignedManaged(Binding, null).initCapacity(self.allocator, 4);
|
||||
defer {
|
||||
self.trimBindingList(&temp_binds, 0, roc_ops);
|
||||
temp_binds.deinit();
|
||||
}
|
||||
|
||||
if (!try self.patternMatchesBind(for_stmt.patt, elem_value, patt_rt_var, roc_ops, &temp_binds)) {
|
||||
elem_value.decref(&self.runtime_layout_store, roc_ops);
|
||||
return error.TypeMismatch;
|
||||
}
|
||||
|
||||
// Add bindings to the environment
|
||||
const loop_bindings_start = self.bindings.items.len;
|
||||
for (temp_binds.items) |binding| {
|
||||
try self.bindings.append(binding);
|
||||
}
|
||||
|
||||
// Evaluate the body
|
||||
const body_result = try self.evalExprMinimal(for_stmt.body, roc_ops, null);
|
||||
body_result.decref(&self.runtime_layout_store, roc_ops);
|
||||
|
||||
// Clean up bindings for this iteration
|
||||
self.trimBindingList(&self.bindings, loop_bindings_start, roc_ops);
|
||||
|
||||
// Decrement the element reference (it was incremented above)
|
||||
elem_value.decref(&self.runtime_layout_store, roc_ops);
|
||||
}
|
||||
},
|
||||
else => return error.NotImplemented,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
13
test/snapshots/repl/for_loop_complex_mutation.md
Normal file
13
test/snapshots/repl/for_loop_complex_mutation.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=For loop with complex var mutation
|
||||
type=repl
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
» countEvens = { var count_ = 0; var sum_ = 0; for n in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] { if n % 2 == 0 { count_ = count_ + 1; sum_ = sum_ + n } else { {} } }; count_ * sum_ }
|
||||
~~~
|
||||
# OUTPUT
|
||||
assigned `countEvens`
|
||||
# PROBLEMS
|
||||
NIL
|
||||
13
test/snapshots/repl/for_loop_empty_list.md
Normal file
13
test/snapshots/repl/for_loop_empty_list.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=For loop with empty list
|
||||
type=repl
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
» unchanged = { var value_ = 42; for n in [] { value_ = n }; value_ }
|
||||
~~~
|
||||
# OUTPUT
|
||||
assigned `unchanged`
|
||||
# PROBLEMS
|
||||
NIL
|
||||
13
test/snapshots/repl/for_loop_list_bool.md
Normal file
13
test/snapshots/repl/for_loop_list_bool.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=For loop iterating over List Bool
|
||||
type=repl
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
» result = { var allTrue_ = Bool.True; for b in [Bool.True, Bool.True, Bool.False] { if b == Bool.False { allTrue_ = Bool.False } else { {} } }; allTrue_ }
|
||||
~~~
|
||||
# OUTPUT
|
||||
assigned `result`
|
||||
# PROBLEMS
|
||||
NIL
|
||||
13
test/snapshots/repl/for_loop_list_str.md
Normal file
13
test/snapshots/repl/for_loop_list_str.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=For loop iterating over List Str
|
||||
type=repl
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
» count = { var counter_ = 0; for _ in ["hello", "world", "test"] { counter_ = counter_ + 1 }; counter_ }
|
||||
~~~
|
||||
# OUTPUT
|
||||
assigned `count`
|
||||
# PROBLEMS
|
||||
NIL
|
||||
13
test/snapshots/repl/for_loop_list_u64.md
Normal file
13
test/snapshots/repl/for_loop_list_u64.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=For loop iterating over List U64
|
||||
type=repl
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
» sum = { var total_ = 0; for n in [1, 2, 3, 4, 5] { total_ = total_ + n }; total_ }
|
||||
~~~
|
||||
# OUTPUT
|
||||
assigned `sum`
|
||||
# PROBLEMS
|
||||
NIL
|
||||
13
test/snapshots/repl/for_loop_nested.md
Normal file
13
test/snapshots/repl/for_loop_nested.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=Nested for loops
|
||||
type=repl
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
» product = { var result_ = 0; for i in [1, 2, 3] { for j in [10, 20] { result_ = result_ + (i * j) } }; result_ }
|
||||
~~~
|
||||
# OUTPUT
|
||||
assigned `product`
|
||||
# PROBLEMS
|
||||
NIL
|
||||
13
test/snapshots/repl/for_loop_var_conditional_persist.md
Normal file
13
test/snapshots/repl/for_loop_var_conditional_persist.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=For loop with var that persists across iterations with conditional updates
|
||||
type=repl
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
» result = { var lastEven_ = 0; var evenCount_ = 0; for n in [1, 2, 3, 4, 5, 6, 7, 8] { if n % 2 == 0 { lastEven_ = n; evenCount_ = evenCount_ + 1 } else { {} } }; lastEven_ * evenCount_ }
|
||||
~~~
|
||||
# OUTPUT
|
||||
assigned `result`
|
||||
# PROBLEMS
|
||||
NIL
|
||||
13
test/snapshots/repl/for_loop_var_every_iteration.md
Normal file
13
test/snapshots/repl/for_loop_var_every_iteration.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=For loop with var reassignment on every iteration
|
||||
type=repl
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
» result = { var prev_ = 0; var count_ = 0; for n in [10, 20, 30, 40, 50] { count_ = count_ + 1; prev_ = n }; prev_ + count_ }
|
||||
~~~
|
||||
# OUTPUT
|
||||
assigned `result`
|
||||
# PROBLEMS
|
||||
NIL
|
||||
13
test/snapshots/repl/for_loop_var_reassign_tracking.md
Normal file
13
test/snapshots/repl/for_loop_var_reassign_tracking.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=For loop with var reassignment tracking across iterations
|
||||
type=repl
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
» result = { var sum_ = 0; var max_ = 0; for n in [3, 7, 2, 9, 1] { sum_ = sum_ + n; if n > max_ { max_ = n } else { {} } }; sum_ + max_ }
|
||||
~~~
|
||||
# OUTPUT
|
||||
assigned `result`
|
||||
# PROBLEMS
|
||||
NIL
|
||||
13
test/snapshots/repl/for_loop_with_var.md
Normal file
13
test/snapshots/repl/for_loop_with_var.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=For loop with var reassignment
|
||||
type=repl
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
» result = { var prev_ = 0; var count_ = 0; for n in [10, 20, 30, 40, 50] { count_ = count_ + 1; prev_ = n }; prev_ + count_ }
|
||||
~~~
|
||||
# OUTPUT
|
||||
assigned `result`
|
||||
# PROBLEMS
|
||||
NIL
|
||||
185
test/snapshots/statement/for_loop_complex_mutation.md
Normal file
185
test/snapshots/statement/for_loop_complex_mutation.md
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=For loop with complex var mutation
|
||||
type=snippet
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
countEvens : U64
|
||||
countEvens = {
|
||||
var count_ = 0
|
||||
var sum_ = 0
|
||||
for n in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] {
|
||||
if n % 2 == 0 {
|
||||
count_ = count_ + 1
|
||||
sum_ = sum_ + n
|
||||
} else {
|
||||
{}
|
||||
}
|
||||
}
|
||||
count_ * sum_
|
||||
}
|
||||
|
||||
expect countEvens == 150
|
||||
~~~
|
||||
# EXPECTED
|
||||
NIL
|
||||
# PROBLEMS
|
||||
NIL
|
||||
# TOKENS
|
||||
~~~zig
|
||||
LowerIdent,OpColon,UpperIdent,
|
||||
LowerIdent,OpAssign,OpenCurly,
|
||||
KwVar,LowerIdent,OpAssign,Int,
|
||||
KwVar,LowerIdent,OpAssign,Int,
|
||||
KwFor,LowerIdent,KwIn,OpenSquare,Int,Comma,Int,Comma,Int,Comma,Int,Comma,Int,Comma,Int,Comma,Int,Comma,Int,Comma,Int,Comma,Int,CloseSquare,OpenCurly,
|
||||
KwIf,LowerIdent,OpPercent,Int,OpEquals,Int,OpenCurly,
|
||||
LowerIdent,OpAssign,LowerIdent,OpPlus,Int,
|
||||
LowerIdent,OpAssign,LowerIdent,OpPlus,LowerIdent,
|
||||
CloseCurly,KwElse,OpenCurly,
|
||||
OpenCurly,CloseCurly,
|
||||
CloseCurly,
|
||||
CloseCurly,
|
||||
LowerIdent,OpStar,LowerIdent,
|
||||
CloseCurly,
|
||||
KwExpect,LowerIdent,OpEquals,Int,
|
||||
EndOfFile,
|
||||
~~~
|
||||
# PARSE
|
||||
~~~clojure
|
||||
(file
|
||||
(type-module)
|
||||
(statements
|
||||
(s-type-anno (name "countEvens")
|
||||
(ty (name "U64")))
|
||||
(s-decl
|
||||
(p-ident (raw "countEvens"))
|
||||
(e-block
|
||||
(statements
|
||||
(s-var (name "count_")
|
||||
(e-int (raw "0")))
|
||||
(s-var (name "sum_")
|
||||
(e-int (raw "0")))
|
||||
(s-for
|
||||
(p-ident (raw "n"))
|
||||
(e-list
|
||||
(e-int (raw "1"))
|
||||
(e-int (raw "2"))
|
||||
(e-int (raw "3"))
|
||||
(e-int (raw "4"))
|
||||
(e-int (raw "5"))
|
||||
(e-int (raw "6"))
|
||||
(e-int (raw "7"))
|
||||
(e-int (raw "8"))
|
||||
(e-int (raw "9"))
|
||||
(e-int (raw "10")))
|
||||
(e-block
|
||||
(statements
|
||||
(e-if-then-else
|
||||
(e-binop (op "==")
|
||||
(e-binop (op "%")
|
||||
(e-ident (raw "n"))
|
||||
(e-int (raw "2")))
|
||||
(e-int (raw "0")))
|
||||
(e-block
|
||||
(statements
|
||||
(s-decl
|
||||
(p-ident (raw "count_"))
|
||||
(e-binop (op "+")
|
||||
(e-ident (raw "count_"))
|
||||
(e-int (raw "1"))))
|
||||
(s-decl
|
||||
(p-ident (raw "sum_"))
|
||||
(e-binop (op "+")
|
||||
(e-ident (raw "sum_"))
|
||||
(e-ident (raw "n"))))))
|
||||
(e-block
|
||||
(statements
|
||||
(e-record)))))))
|
||||
(e-binop (op "*")
|
||||
(e-ident (raw "count_"))
|
||||
(e-ident (raw "sum_"))))))
|
||||
(s-expect
|
||||
(e-binop (op "==")
|
||||
(e-ident (raw "countEvens"))
|
||||
(e-int (raw "150"))))))
|
||||
~~~
|
||||
# FORMATTED
|
||||
~~~roc
|
||||
NO CHANGE
|
||||
~~~
|
||||
# CANONICALIZE
|
||||
~~~clojure
|
||||
(can-ir
|
||||
(d-let
|
||||
(p-assign (ident "countEvens"))
|
||||
(e-block
|
||||
(s-var
|
||||
(p-assign (ident "count_"))
|
||||
(e-num (value "0")))
|
||||
(s-var
|
||||
(p-assign (ident "sum_"))
|
||||
(e-num (value "0")))
|
||||
(s-for
|
||||
(p-assign (ident "n"))
|
||||
(e-list
|
||||
(elems
|
||||
(e-num (value "1"))
|
||||
(e-num (value "2"))
|
||||
(e-num (value "3"))
|
||||
(e-num (value "4"))
|
||||
(e-num (value "5"))
|
||||
(e-num (value "6"))
|
||||
(e-num (value "7"))
|
||||
(e-num (value "8"))
|
||||
(e-num (value "9"))
|
||||
(e-num (value "10"))))
|
||||
(e-block
|
||||
(e-if
|
||||
(if-branches
|
||||
(if-branch
|
||||
(e-binop (op "eq")
|
||||
(e-binop (op "rem")
|
||||
(e-lookup-local
|
||||
(p-assign (ident "n")))
|
||||
(e-num (value "2")))
|
||||
(e-num (value "0")))
|
||||
(e-block
|
||||
(s-reassign
|
||||
(p-assign (ident "count_"))
|
||||
(e-binop (op "add")
|
||||
(e-lookup-local
|
||||
(p-assign (ident "count_")))
|
||||
(e-num (value "1"))))
|
||||
(s-reassign
|
||||
(p-assign (ident "sum_"))
|
||||
(e-binop (op "add")
|
||||
(e-lookup-local
|
||||
(p-assign (ident "sum_")))
|
||||
(e-lookup-local
|
||||
(p-assign (ident "n")))))
|
||||
(e-empty_record))))
|
||||
(if-else
|
||||
(e-block
|
||||
(e-empty_record))))))
|
||||
(e-binop (op "mul")
|
||||
(e-lookup-local
|
||||
(p-assign (ident "count_")))
|
||||
(e-lookup-local
|
||||
(p-assign (ident "sum_")))))
|
||||
(annotation
|
||||
(ty-lookup (name "U64") (builtin))))
|
||||
(s-expect
|
||||
(e-binop (op "eq")
|
||||
(e-lookup-local
|
||||
(p-assign (ident "countEvens")))
|
||||
(e-num (value "150")))))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(inferred-types
|
||||
(defs
|
||||
(patt (type "Num(Int(Unsigned64))")))
|
||||
(expressions
|
||||
(expr (type "Num(Int(Unsigned64))"))))
|
||||
~~~
|
||||
102
test/snapshots/statement/for_loop_empty_list.md
Normal file
102
test/snapshots/statement/for_loop_empty_list.md
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=For loop with empty list
|
||||
type=snippet
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
unchanged : U64
|
||||
unchanged = {
|
||||
var value_ = 42
|
||||
for n in [] {
|
||||
value_ = n
|
||||
}
|
||||
value_
|
||||
}
|
||||
|
||||
expect unchanged == 42
|
||||
~~~
|
||||
# EXPECTED
|
||||
NIL
|
||||
# PROBLEMS
|
||||
NIL
|
||||
# TOKENS
|
||||
~~~zig
|
||||
LowerIdent,OpColon,UpperIdent,
|
||||
LowerIdent,OpAssign,OpenCurly,
|
||||
KwVar,LowerIdent,OpAssign,Int,
|
||||
KwFor,LowerIdent,KwIn,OpenSquare,CloseSquare,OpenCurly,
|
||||
LowerIdent,OpAssign,LowerIdent,
|
||||
CloseCurly,
|
||||
LowerIdent,
|
||||
CloseCurly,
|
||||
KwExpect,LowerIdent,OpEquals,Int,
|
||||
EndOfFile,
|
||||
~~~
|
||||
# PARSE
|
||||
~~~clojure
|
||||
(file
|
||||
(type-module)
|
||||
(statements
|
||||
(s-type-anno (name "unchanged")
|
||||
(ty (name "U64")))
|
||||
(s-decl
|
||||
(p-ident (raw "unchanged"))
|
||||
(e-block
|
||||
(statements
|
||||
(s-var (name "value_")
|
||||
(e-int (raw "42")))
|
||||
(s-for
|
||||
(p-ident (raw "n"))
|
||||
(e-list)
|
||||
(e-block
|
||||
(statements
|
||||
(s-decl
|
||||
(p-ident (raw "value_"))
|
||||
(e-ident (raw "n"))))))
|
||||
(e-ident (raw "value_")))))
|
||||
(s-expect
|
||||
(e-binop (op "==")
|
||||
(e-ident (raw "unchanged"))
|
||||
(e-int (raw "42"))))))
|
||||
~~~
|
||||
# FORMATTED
|
||||
~~~roc
|
||||
NO CHANGE
|
||||
~~~
|
||||
# CANONICALIZE
|
||||
~~~clojure
|
||||
(can-ir
|
||||
(d-let
|
||||
(p-assign (ident "unchanged"))
|
||||
(e-block
|
||||
(s-var
|
||||
(p-assign (ident "value_"))
|
||||
(e-num (value "42")))
|
||||
(s-for
|
||||
(p-assign (ident "n"))
|
||||
(e-empty_list)
|
||||
(e-block
|
||||
(s-reassign
|
||||
(p-assign (ident "value_"))
|
||||
(e-lookup-local
|
||||
(p-assign (ident "n"))))
|
||||
(e-empty_record)))
|
||||
(e-lookup-local
|
||||
(p-assign (ident "value_"))))
|
||||
(annotation
|
||||
(ty-lookup (name "U64") (builtin))))
|
||||
(s-expect
|
||||
(e-binop (op "eq")
|
||||
(e-lookup-local
|
||||
(p-assign (ident "unchanged")))
|
||||
(e-num (value "42")))))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(inferred-types
|
||||
(defs
|
||||
(patt (type "Num(Int(Unsigned64))")))
|
||||
(expressions
|
||||
(expr (type "Num(Int(Unsigned64))"))))
|
||||
~~~
|
||||
150
test/snapshots/statement/for_loop_list_bool.md
Normal file
150
test/snapshots/statement/for_loop_list_bool.md
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=For loop iterating over List Bool
|
||||
type=snippet
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
result : Bool
|
||||
result = {
|
||||
var allTrue_ = Bool.True
|
||||
for b in [Bool.True, Bool.True, Bool.False] {
|
||||
if b == Bool.False {
|
||||
allTrue_ = Bool.False
|
||||
} else {
|
||||
{}
|
||||
}
|
||||
}
|
||||
allTrue_
|
||||
}
|
||||
|
||||
expect result == Bool.False
|
||||
~~~
|
||||
# EXPECTED
|
||||
NIL
|
||||
# PROBLEMS
|
||||
NIL
|
||||
# TOKENS
|
||||
~~~zig
|
||||
LowerIdent,OpColon,UpperIdent,
|
||||
LowerIdent,OpAssign,OpenCurly,
|
||||
KwVar,LowerIdent,OpAssign,UpperIdent,NoSpaceDotUpperIdent,
|
||||
KwFor,LowerIdent,KwIn,OpenSquare,UpperIdent,NoSpaceDotUpperIdent,Comma,UpperIdent,NoSpaceDotUpperIdent,Comma,UpperIdent,NoSpaceDotUpperIdent,CloseSquare,OpenCurly,
|
||||
KwIf,LowerIdent,OpEquals,UpperIdent,NoSpaceDotUpperIdent,OpenCurly,
|
||||
LowerIdent,OpAssign,UpperIdent,NoSpaceDotUpperIdent,
|
||||
CloseCurly,KwElse,OpenCurly,
|
||||
OpenCurly,CloseCurly,
|
||||
CloseCurly,
|
||||
CloseCurly,
|
||||
LowerIdent,
|
||||
CloseCurly,
|
||||
KwExpect,LowerIdent,OpEquals,UpperIdent,NoSpaceDotUpperIdent,
|
||||
EndOfFile,
|
||||
~~~
|
||||
# PARSE
|
||||
~~~clojure
|
||||
(file
|
||||
(type-module)
|
||||
(statements
|
||||
(s-type-anno (name "result")
|
||||
(ty (name "Bool")))
|
||||
(s-decl
|
||||
(p-ident (raw "result"))
|
||||
(e-block
|
||||
(statements
|
||||
(s-var (name "allTrue_")
|
||||
(e-tag (raw "Bool.True")))
|
||||
(s-for
|
||||
(p-ident (raw "b"))
|
||||
(e-list
|
||||
(e-tag (raw "Bool.True"))
|
||||
(e-tag (raw "Bool.True"))
|
||||
(e-tag (raw "Bool.False")))
|
||||
(e-block
|
||||
(statements
|
||||
(e-if-then-else
|
||||
(e-binop (op "==")
|
||||
(e-ident (raw "b"))
|
||||
(e-tag (raw "Bool.False")))
|
||||
(e-block
|
||||
(statements
|
||||
(s-decl
|
||||
(p-ident (raw "allTrue_"))
|
||||
(e-tag (raw "Bool.False")))))
|
||||
(e-block
|
||||
(statements
|
||||
(e-record)))))))
|
||||
(e-ident (raw "allTrue_")))))
|
||||
(s-expect
|
||||
(e-binop (op "==")
|
||||
(e-ident (raw "result"))
|
||||
(e-tag (raw "Bool.False"))))))
|
||||
~~~
|
||||
# FORMATTED
|
||||
~~~roc
|
||||
NO CHANGE
|
||||
~~~
|
||||
# CANONICALIZE
|
||||
~~~clojure
|
||||
(can-ir
|
||||
(d-let
|
||||
(p-assign (ident "result"))
|
||||
(e-block
|
||||
(s-var
|
||||
(p-assign (ident "allTrue_"))
|
||||
(e-nominal-external
|
||||
(external-module "Bool")
|
||||
(e-tag (name "True"))))
|
||||
(s-for
|
||||
(p-assign (ident "b"))
|
||||
(e-list
|
||||
(elems
|
||||
(e-nominal-external
|
||||
(external-module "Bool")
|
||||
(e-tag (name "True")))
|
||||
(e-nominal-external
|
||||
(external-module "Bool")
|
||||
(e-tag (name "True")))
|
||||
(e-nominal-external
|
||||
(external-module "Bool")
|
||||
(e-tag (name "False")))))
|
||||
(e-block
|
||||
(e-if
|
||||
(if-branches
|
||||
(if-branch
|
||||
(e-binop (op "eq")
|
||||
(e-lookup-local
|
||||
(p-assign (ident "b")))
|
||||
(e-nominal-external
|
||||
(external-module "Bool")
|
||||
(e-tag (name "False"))))
|
||||
(e-block
|
||||
(s-reassign
|
||||
(p-assign (ident "allTrue_"))
|
||||
(e-nominal-external
|
||||
(external-module "Bool")
|
||||
(e-tag (name "False"))))
|
||||
(e-empty_record))))
|
||||
(if-else
|
||||
(e-block
|
||||
(e-empty_record))))))
|
||||
(e-lookup-local
|
||||
(p-assign (ident "allTrue_"))))
|
||||
(annotation
|
||||
(ty-lookup (name "Bool") (external-module "Bool"))))
|
||||
(s-expect
|
||||
(e-binop (op "eq")
|
||||
(e-lookup-local
|
||||
(p-assign (ident "result")))
|
||||
(e-nominal-external
|
||||
(external-module "Bool")
|
||||
(e-tag (name "False"))))))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(inferred-types
|
||||
(defs
|
||||
(patt (type "Bool")))
|
||||
(expressions
|
||||
(expr (type "Bool"))))
|
||||
~~~
|
||||
119
test/snapshots/statement/for_loop_list_str.md
Normal file
119
test/snapshots/statement/for_loop_list_str.md
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=For loop iterating over List Str
|
||||
type=snippet
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
count : U64
|
||||
count = {
|
||||
var counter_ = 0
|
||||
for _ in ["hello", "world", "test"] {
|
||||
counter_ = counter_ + 1
|
||||
}
|
||||
counter_
|
||||
}
|
||||
|
||||
expect count == 3
|
||||
~~~
|
||||
# EXPECTED
|
||||
NIL
|
||||
# PROBLEMS
|
||||
NIL
|
||||
# TOKENS
|
||||
~~~zig
|
||||
LowerIdent,OpColon,UpperIdent,
|
||||
LowerIdent,OpAssign,OpenCurly,
|
||||
KwVar,LowerIdent,OpAssign,Int,
|
||||
KwFor,Underscore,KwIn,OpenSquare,StringStart,StringPart,StringEnd,Comma,StringStart,StringPart,StringEnd,Comma,StringStart,StringPart,StringEnd,CloseSquare,OpenCurly,
|
||||
LowerIdent,OpAssign,LowerIdent,OpPlus,Int,
|
||||
CloseCurly,
|
||||
LowerIdent,
|
||||
CloseCurly,
|
||||
KwExpect,LowerIdent,OpEquals,Int,
|
||||
EndOfFile,
|
||||
~~~
|
||||
# PARSE
|
||||
~~~clojure
|
||||
(file
|
||||
(type-module)
|
||||
(statements
|
||||
(s-type-anno (name "count")
|
||||
(ty (name "U64")))
|
||||
(s-decl
|
||||
(p-ident (raw "count"))
|
||||
(e-block
|
||||
(statements
|
||||
(s-var (name "counter_")
|
||||
(e-int (raw "0")))
|
||||
(s-for
|
||||
(p-underscore)
|
||||
(e-list
|
||||
(e-string
|
||||
(e-string-part (raw "hello")))
|
||||
(e-string
|
||||
(e-string-part (raw "world")))
|
||||
(e-string
|
||||
(e-string-part (raw "test"))))
|
||||
(e-block
|
||||
(statements
|
||||
(s-decl
|
||||
(p-ident (raw "counter_"))
|
||||
(e-binop (op "+")
|
||||
(e-ident (raw "counter_"))
|
||||
(e-int (raw "1")))))))
|
||||
(e-ident (raw "counter_")))))
|
||||
(s-expect
|
||||
(e-binop (op "==")
|
||||
(e-ident (raw "count"))
|
||||
(e-int (raw "3"))))))
|
||||
~~~
|
||||
# FORMATTED
|
||||
~~~roc
|
||||
NO CHANGE
|
||||
~~~
|
||||
# CANONICALIZE
|
||||
~~~clojure
|
||||
(can-ir
|
||||
(d-let
|
||||
(p-assign (ident "count"))
|
||||
(e-block
|
||||
(s-var
|
||||
(p-assign (ident "counter_"))
|
||||
(e-num (value "0")))
|
||||
(s-for
|
||||
(p-underscore)
|
||||
(e-list
|
||||
(elems
|
||||
(e-string
|
||||
(e-literal (string "hello")))
|
||||
(e-string
|
||||
(e-literal (string "world")))
|
||||
(e-string
|
||||
(e-literal (string "test")))))
|
||||
(e-block
|
||||
(s-reassign
|
||||
(p-assign (ident "counter_"))
|
||||
(e-binop (op "add")
|
||||
(e-lookup-local
|
||||
(p-assign (ident "counter_")))
|
||||
(e-num (value "1"))))
|
||||
(e-empty_record)))
|
||||
(e-lookup-local
|
||||
(p-assign (ident "counter_"))))
|
||||
(annotation
|
||||
(ty-lookup (name "U64") (builtin))))
|
||||
(s-expect
|
||||
(e-binop (op "eq")
|
||||
(e-lookup-local
|
||||
(p-assign (ident "count")))
|
||||
(e-num (value "3")))))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(inferred-types
|
||||
(defs
|
||||
(patt (type "Num(Int(Unsigned64))")))
|
||||
(expressions
|
||||
(expr (type "Num(Int(Unsigned64))"))))
|
||||
~~~
|
||||
118
test/snapshots/statement/for_loop_list_u64.md
Normal file
118
test/snapshots/statement/for_loop_list_u64.md
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=For loop iterating over List U64
|
||||
type=snippet
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
sum : U64
|
||||
sum = {
|
||||
var total_ = 0
|
||||
for n in [1, 2, 3, 4, 5] {
|
||||
total_ = total_ + n
|
||||
}
|
||||
total_
|
||||
}
|
||||
|
||||
expect sum == 15
|
||||
~~~
|
||||
# EXPECTED
|
||||
NIL
|
||||
# PROBLEMS
|
||||
NIL
|
||||
# TOKENS
|
||||
~~~zig
|
||||
LowerIdent,OpColon,UpperIdent,
|
||||
LowerIdent,OpAssign,OpenCurly,
|
||||
KwVar,LowerIdent,OpAssign,Int,
|
||||
KwFor,LowerIdent,KwIn,OpenSquare,Int,Comma,Int,Comma,Int,Comma,Int,Comma,Int,CloseSquare,OpenCurly,
|
||||
LowerIdent,OpAssign,LowerIdent,OpPlus,LowerIdent,
|
||||
CloseCurly,
|
||||
LowerIdent,
|
||||
CloseCurly,
|
||||
KwExpect,LowerIdent,OpEquals,Int,
|
||||
EndOfFile,
|
||||
~~~
|
||||
# PARSE
|
||||
~~~clojure
|
||||
(file
|
||||
(type-module)
|
||||
(statements
|
||||
(s-type-anno (name "sum")
|
||||
(ty (name "U64")))
|
||||
(s-decl
|
||||
(p-ident (raw "sum"))
|
||||
(e-block
|
||||
(statements
|
||||
(s-var (name "total_")
|
||||
(e-int (raw "0")))
|
||||
(s-for
|
||||
(p-ident (raw "n"))
|
||||
(e-list
|
||||
(e-int (raw "1"))
|
||||
(e-int (raw "2"))
|
||||
(e-int (raw "3"))
|
||||
(e-int (raw "4"))
|
||||
(e-int (raw "5")))
|
||||
(e-block
|
||||
(statements
|
||||
(s-decl
|
||||
(p-ident (raw "total_"))
|
||||
(e-binop (op "+")
|
||||
(e-ident (raw "total_"))
|
||||
(e-ident (raw "n")))))))
|
||||
(e-ident (raw "total_")))))
|
||||
(s-expect
|
||||
(e-binop (op "==")
|
||||
(e-ident (raw "sum"))
|
||||
(e-int (raw "15"))))))
|
||||
~~~
|
||||
# FORMATTED
|
||||
~~~roc
|
||||
NO CHANGE
|
||||
~~~
|
||||
# CANONICALIZE
|
||||
~~~clojure
|
||||
(can-ir
|
||||
(d-let
|
||||
(p-assign (ident "sum"))
|
||||
(e-block
|
||||
(s-var
|
||||
(p-assign (ident "total_"))
|
||||
(e-num (value "0")))
|
||||
(s-for
|
||||
(p-assign (ident "n"))
|
||||
(e-list
|
||||
(elems
|
||||
(e-num (value "1"))
|
||||
(e-num (value "2"))
|
||||
(e-num (value "3"))
|
||||
(e-num (value "4"))
|
||||
(e-num (value "5"))))
|
||||
(e-block
|
||||
(s-reassign
|
||||
(p-assign (ident "total_"))
|
||||
(e-binop (op "add")
|
||||
(e-lookup-local
|
||||
(p-assign (ident "total_")))
|
||||
(e-lookup-local
|
||||
(p-assign (ident "n")))))
|
||||
(e-empty_record)))
|
||||
(e-lookup-local
|
||||
(p-assign (ident "total_"))))
|
||||
(annotation
|
||||
(ty-lookup (name "U64") (builtin))))
|
||||
(s-expect
|
||||
(e-binop (op "eq")
|
||||
(e-lookup-local
|
||||
(p-assign (ident "sum")))
|
||||
(e-num (value "15")))))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(inferred-types
|
||||
(defs
|
||||
(patt (type "Num(Int(Unsigned64))")))
|
||||
(expressions
|
||||
(expr (type "Num(Int(Unsigned64))"))))
|
||||
~~~
|
||||
139
test/snapshots/statement/for_loop_nested.md
Normal file
139
test/snapshots/statement/for_loop_nested.md
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=Nested for loops
|
||||
type=snippet
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
product : U64
|
||||
product = {
|
||||
var result_ = 0
|
||||
for i in [1, 2, 3] {
|
||||
for j in [10, 20] {
|
||||
result_ = result_ + (i * j)
|
||||
}
|
||||
}
|
||||
result_
|
||||
}
|
||||
|
||||
expect product == 180
|
||||
~~~
|
||||
# EXPECTED
|
||||
NIL
|
||||
# PROBLEMS
|
||||
NIL
|
||||
# TOKENS
|
||||
~~~zig
|
||||
LowerIdent,OpColon,UpperIdent,
|
||||
LowerIdent,OpAssign,OpenCurly,
|
||||
KwVar,LowerIdent,OpAssign,Int,
|
||||
KwFor,LowerIdent,KwIn,OpenSquare,Int,Comma,Int,Comma,Int,CloseSquare,OpenCurly,
|
||||
KwFor,LowerIdent,KwIn,OpenSquare,Int,Comma,Int,CloseSquare,OpenCurly,
|
||||
LowerIdent,OpAssign,LowerIdent,OpPlus,OpenRound,LowerIdent,OpStar,LowerIdent,CloseRound,
|
||||
CloseCurly,
|
||||
CloseCurly,
|
||||
LowerIdent,
|
||||
CloseCurly,
|
||||
KwExpect,LowerIdent,OpEquals,Int,
|
||||
EndOfFile,
|
||||
~~~
|
||||
# PARSE
|
||||
~~~clojure
|
||||
(file
|
||||
(type-module)
|
||||
(statements
|
||||
(s-type-anno (name "product")
|
||||
(ty (name "U64")))
|
||||
(s-decl
|
||||
(p-ident (raw "product"))
|
||||
(e-block
|
||||
(statements
|
||||
(s-var (name "result_")
|
||||
(e-int (raw "0")))
|
||||
(s-for
|
||||
(p-ident (raw "i"))
|
||||
(e-list
|
||||
(e-int (raw "1"))
|
||||
(e-int (raw "2"))
|
||||
(e-int (raw "3")))
|
||||
(e-block
|
||||
(statements
|
||||
(s-for
|
||||
(p-ident (raw "j"))
|
||||
(e-list
|
||||
(e-int (raw "10"))
|
||||
(e-int (raw "20")))
|
||||
(e-block
|
||||
(statements
|
||||
(s-decl
|
||||
(p-ident (raw "result_"))
|
||||
(e-binop (op "+")
|
||||
(e-ident (raw "result_"))
|
||||
(e-tuple
|
||||
(e-binop (op "*")
|
||||
(e-ident (raw "i"))
|
||||
(e-ident (raw "j"))))))))))))
|
||||
(e-ident (raw "result_")))))
|
||||
(s-expect
|
||||
(e-binop (op "==")
|
||||
(e-ident (raw "product"))
|
||||
(e-int (raw "180"))))))
|
||||
~~~
|
||||
# FORMATTED
|
||||
~~~roc
|
||||
NO CHANGE
|
||||
~~~
|
||||
# CANONICALIZE
|
||||
~~~clojure
|
||||
(can-ir
|
||||
(d-let
|
||||
(p-assign (ident "product"))
|
||||
(e-block
|
||||
(s-var
|
||||
(p-assign (ident "result_"))
|
||||
(e-num (value "0")))
|
||||
(s-for
|
||||
(p-assign (ident "i"))
|
||||
(e-list
|
||||
(elems
|
||||
(e-num (value "1"))
|
||||
(e-num (value "2"))
|
||||
(e-num (value "3"))))
|
||||
(e-block
|
||||
(s-for
|
||||
(p-assign (ident "j"))
|
||||
(e-list
|
||||
(elems
|
||||
(e-num (value "10"))
|
||||
(e-num (value "20"))))
|
||||
(e-block
|
||||
(s-reassign
|
||||
(p-assign (ident "result_"))
|
||||
(e-binop (op "add")
|
||||
(e-lookup-local
|
||||
(p-assign (ident "result_")))
|
||||
(e-binop (op "mul")
|
||||
(e-lookup-local
|
||||
(p-assign (ident "i")))
|
||||
(e-lookup-local
|
||||
(p-assign (ident "j"))))))
|
||||
(e-empty_record)))
|
||||
(e-empty_record)))
|
||||
(e-lookup-local
|
||||
(p-assign (ident "result_"))))
|
||||
(annotation
|
||||
(ty-lookup (name "U64") (builtin))))
|
||||
(s-expect
|
||||
(e-binop (op "eq")
|
||||
(e-lookup-local
|
||||
(p-assign (ident "product")))
|
||||
(e-num (value "180")))))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(inferred-types
|
||||
(defs
|
||||
(patt (type "Num(Int(Unsigned64))")))
|
||||
(expressions
|
||||
(expr (type "Num(Int(Unsigned64))"))))
|
||||
~~~
|
||||
176
test/snapshots/statement/for_loop_var_conditional_persist.md
Normal file
176
test/snapshots/statement/for_loop_var_conditional_persist.md
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=For loop with var that persists across iterations with conditional updates
|
||||
type=snippet
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
result : U64
|
||||
result = {
|
||||
var lastEven_ = 0
|
||||
var evenCount_ = 0
|
||||
for n in [1, 2, 3, 4, 5, 6, 7, 8] {
|
||||
if n % 2 == 0 {
|
||||
lastEven_ = n
|
||||
evenCount_ = evenCount_ + 1
|
||||
} else {
|
||||
{}
|
||||
}
|
||||
}
|
||||
lastEven_ * evenCount_
|
||||
}
|
||||
|
||||
expect result == 32
|
||||
~~~
|
||||
# EXPECTED
|
||||
NIL
|
||||
# PROBLEMS
|
||||
NIL
|
||||
# TOKENS
|
||||
~~~zig
|
||||
LowerIdent,OpColon,UpperIdent,
|
||||
LowerIdent,OpAssign,OpenCurly,
|
||||
KwVar,LowerIdent,OpAssign,Int,
|
||||
KwVar,LowerIdent,OpAssign,Int,
|
||||
KwFor,LowerIdent,KwIn,OpenSquare,Int,Comma,Int,Comma,Int,Comma,Int,Comma,Int,Comma,Int,Comma,Int,Comma,Int,CloseSquare,OpenCurly,
|
||||
KwIf,LowerIdent,OpPercent,Int,OpEquals,Int,OpenCurly,
|
||||
LowerIdent,OpAssign,LowerIdent,
|
||||
LowerIdent,OpAssign,LowerIdent,OpPlus,Int,
|
||||
CloseCurly,KwElse,OpenCurly,
|
||||
OpenCurly,CloseCurly,
|
||||
CloseCurly,
|
||||
CloseCurly,
|
||||
LowerIdent,OpStar,LowerIdent,
|
||||
CloseCurly,
|
||||
KwExpect,LowerIdent,OpEquals,Int,
|
||||
EndOfFile,
|
||||
~~~
|
||||
# PARSE
|
||||
~~~clojure
|
||||
(file
|
||||
(type-module)
|
||||
(statements
|
||||
(s-type-anno (name "result")
|
||||
(ty (name "U64")))
|
||||
(s-decl
|
||||
(p-ident (raw "result"))
|
||||
(e-block
|
||||
(statements
|
||||
(s-var (name "lastEven_")
|
||||
(e-int (raw "0")))
|
||||
(s-var (name "evenCount_")
|
||||
(e-int (raw "0")))
|
||||
(s-for
|
||||
(p-ident (raw "n"))
|
||||
(e-list
|
||||
(e-int (raw "1"))
|
||||
(e-int (raw "2"))
|
||||
(e-int (raw "3"))
|
||||
(e-int (raw "4"))
|
||||
(e-int (raw "5"))
|
||||
(e-int (raw "6"))
|
||||
(e-int (raw "7"))
|
||||
(e-int (raw "8")))
|
||||
(e-block
|
||||
(statements
|
||||
(e-if-then-else
|
||||
(e-binop (op "==")
|
||||
(e-binop (op "%")
|
||||
(e-ident (raw "n"))
|
||||
(e-int (raw "2")))
|
||||
(e-int (raw "0")))
|
||||
(e-block
|
||||
(statements
|
||||
(s-decl
|
||||
(p-ident (raw "lastEven_"))
|
||||
(e-ident (raw "n")))
|
||||
(s-decl
|
||||
(p-ident (raw "evenCount_"))
|
||||
(e-binop (op "+")
|
||||
(e-ident (raw "evenCount_"))
|
||||
(e-int (raw "1"))))))
|
||||
(e-block
|
||||
(statements
|
||||
(e-record)))))))
|
||||
(e-binop (op "*")
|
||||
(e-ident (raw "lastEven_"))
|
||||
(e-ident (raw "evenCount_"))))))
|
||||
(s-expect
|
||||
(e-binop (op "==")
|
||||
(e-ident (raw "result"))
|
||||
(e-int (raw "32"))))))
|
||||
~~~
|
||||
# FORMATTED
|
||||
~~~roc
|
||||
NO CHANGE
|
||||
~~~
|
||||
# CANONICALIZE
|
||||
~~~clojure
|
||||
(can-ir
|
||||
(d-let
|
||||
(p-assign (ident "result"))
|
||||
(e-block
|
||||
(s-var
|
||||
(p-assign (ident "lastEven_"))
|
||||
(e-num (value "0")))
|
||||
(s-var
|
||||
(p-assign (ident "evenCount_"))
|
||||
(e-num (value "0")))
|
||||
(s-for
|
||||
(p-assign (ident "n"))
|
||||
(e-list
|
||||
(elems
|
||||
(e-num (value "1"))
|
||||
(e-num (value "2"))
|
||||
(e-num (value "3"))
|
||||
(e-num (value "4"))
|
||||
(e-num (value "5"))
|
||||
(e-num (value "6"))
|
||||
(e-num (value "7"))
|
||||
(e-num (value "8"))))
|
||||
(e-block
|
||||
(e-if
|
||||
(if-branches
|
||||
(if-branch
|
||||
(e-binop (op "eq")
|
||||
(e-binop (op "rem")
|
||||
(e-lookup-local
|
||||
(p-assign (ident "n")))
|
||||
(e-num (value "2")))
|
||||
(e-num (value "0")))
|
||||
(e-block
|
||||
(s-reassign
|
||||
(p-assign (ident "lastEven_"))
|
||||
(e-lookup-local
|
||||
(p-assign (ident "n"))))
|
||||
(s-reassign
|
||||
(p-assign (ident "evenCount_"))
|
||||
(e-binop (op "add")
|
||||
(e-lookup-local
|
||||
(p-assign (ident "evenCount_")))
|
||||
(e-num (value "1"))))
|
||||
(e-empty_record))))
|
||||
(if-else
|
||||
(e-block
|
||||
(e-empty_record))))))
|
||||
(e-binop (op "mul")
|
||||
(e-lookup-local
|
||||
(p-assign (ident "lastEven_")))
|
||||
(e-lookup-local
|
||||
(p-assign (ident "evenCount_")))))
|
||||
(annotation
|
||||
(ty-lookup (name "U64") (builtin))))
|
||||
(s-expect
|
||||
(e-binop (op "eq")
|
||||
(e-lookup-local
|
||||
(p-assign (ident "result")))
|
||||
(e-num (value "32")))))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(inferred-types
|
||||
(defs
|
||||
(patt (type "Num(Int(Unsigned64))")))
|
||||
(expressions
|
||||
(expr (type "Num(Int(Unsigned64))"))))
|
||||
~~~
|
||||
138
test/snapshots/statement/for_loop_var_every_iteration.md
Normal file
138
test/snapshots/statement/for_loop_var_every_iteration.md
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=For loop with var reassignment on every iteration
|
||||
type=snippet
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
result : U64
|
||||
result = {
|
||||
var prev_ = 0
|
||||
var count_ = 0
|
||||
for n in [10, 20, 30, 40, 50] {
|
||||
count_ = count_ + 1
|
||||
prev_ = n
|
||||
}
|
||||
prev_ + count_
|
||||
}
|
||||
|
||||
expect result == 55
|
||||
~~~
|
||||
# EXPECTED
|
||||
NIL
|
||||
# PROBLEMS
|
||||
NIL
|
||||
# TOKENS
|
||||
~~~zig
|
||||
LowerIdent,OpColon,UpperIdent,
|
||||
LowerIdent,OpAssign,OpenCurly,
|
||||
KwVar,LowerIdent,OpAssign,Int,
|
||||
KwVar,LowerIdent,OpAssign,Int,
|
||||
KwFor,LowerIdent,KwIn,OpenSquare,Int,Comma,Int,Comma,Int,Comma,Int,Comma,Int,CloseSquare,OpenCurly,
|
||||
LowerIdent,OpAssign,LowerIdent,OpPlus,Int,
|
||||
LowerIdent,OpAssign,LowerIdent,
|
||||
CloseCurly,
|
||||
LowerIdent,OpPlus,LowerIdent,
|
||||
CloseCurly,
|
||||
KwExpect,LowerIdent,OpEquals,Int,
|
||||
EndOfFile,
|
||||
~~~
|
||||
# PARSE
|
||||
~~~clojure
|
||||
(file
|
||||
(type-module)
|
||||
(statements
|
||||
(s-type-anno (name "result")
|
||||
(ty (name "U64")))
|
||||
(s-decl
|
||||
(p-ident (raw "result"))
|
||||
(e-block
|
||||
(statements
|
||||
(s-var (name "prev_")
|
||||
(e-int (raw "0")))
|
||||
(s-var (name "count_")
|
||||
(e-int (raw "0")))
|
||||
(s-for
|
||||
(p-ident (raw "n"))
|
||||
(e-list
|
||||
(e-int (raw "10"))
|
||||
(e-int (raw "20"))
|
||||
(e-int (raw "30"))
|
||||
(e-int (raw "40"))
|
||||
(e-int (raw "50")))
|
||||
(e-block
|
||||
(statements
|
||||
(s-decl
|
||||
(p-ident (raw "count_"))
|
||||
(e-binop (op "+")
|
||||
(e-ident (raw "count_"))
|
||||
(e-int (raw "1"))))
|
||||
(s-decl
|
||||
(p-ident (raw "prev_"))
|
||||
(e-ident (raw "n"))))))
|
||||
(e-binop (op "+")
|
||||
(e-ident (raw "prev_"))
|
||||
(e-ident (raw "count_"))))))
|
||||
(s-expect
|
||||
(e-binop (op "==")
|
||||
(e-ident (raw "result"))
|
||||
(e-int (raw "55"))))))
|
||||
~~~
|
||||
# FORMATTED
|
||||
~~~roc
|
||||
NO CHANGE
|
||||
~~~
|
||||
# CANONICALIZE
|
||||
~~~clojure
|
||||
(can-ir
|
||||
(d-let
|
||||
(p-assign (ident "result"))
|
||||
(e-block
|
||||
(s-var
|
||||
(p-assign (ident "prev_"))
|
||||
(e-num (value "0")))
|
||||
(s-var
|
||||
(p-assign (ident "count_"))
|
||||
(e-num (value "0")))
|
||||
(s-for
|
||||
(p-assign (ident "n"))
|
||||
(e-list
|
||||
(elems
|
||||
(e-num (value "10"))
|
||||
(e-num (value "20"))
|
||||
(e-num (value "30"))
|
||||
(e-num (value "40"))
|
||||
(e-num (value "50"))))
|
||||
(e-block
|
||||
(s-reassign
|
||||
(p-assign (ident "count_"))
|
||||
(e-binop (op "add")
|
||||
(e-lookup-local
|
||||
(p-assign (ident "count_")))
|
||||
(e-num (value "1"))))
|
||||
(s-reassign
|
||||
(p-assign (ident "prev_"))
|
||||
(e-lookup-local
|
||||
(p-assign (ident "n"))))
|
||||
(e-empty_record)))
|
||||
(e-binop (op "add")
|
||||
(e-lookup-local
|
||||
(p-assign (ident "prev_")))
|
||||
(e-lookup-local
|
||||
(p-assign (ident "count_")))))
|
||||
(annotation
|
||||
(ty-lookup (name "U64") (builtin))))
|
||||
(s-expect
|
||||
(e-binop (op "eq")
|
||||
(e-lookup-local
|
||||
(p-assign (ident "result")))
|
||||
(e-num (value "55")))))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(inferred-types
|
||||
(defs
|
||||
(patt (type "Num(Int(Unsigned64))")))
|
||||
(expressions
|
||||
(expr (type "Num(Int(Unsigned64))"))))
|
||||
~~~
|
||||
168
test/snapshots/statement/for_loop_var_reassign_tracking.md
Normal file
168
test/snapshots/statement/for_loop_var_reassign_tracking.md
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
# META
|
||||
~~~ini
|
||||
description=For loop with var reassignment tracking across iterations
|
||||
type=snippet
|
||||
~~~
|
||||
# SOURCE
|
||||
~~~roc
|
||||
result : U64
|
||||
result = {
|
||||
var sum_ = 0
|
||||
var max_ = 0
|
||||
for n in [3, 7, 2, 9, 1] {
|
||||
sum_ = sum_ + n
|
||||
if n > max_ {
|
||||
max_ = n
|
||||
} else {
|
||||
{}
|
||||
}
|
||||
}
|
||||
sum_ + max_
|
||||
}
|
||||
|
||||
expect result == 31
|
||||
~~~
|
||||
# EXPECTED
|
||||
NIL
|
||||
# PROBLEMS
|
||||
NIL
|
||||
# TOKENS
|
||||
~~~zig
|
||||
LowerIdent,OpColon,UpperIdent,
|
||||
LowerIdent,OpAssign,OpenCurly,
|
||||
KwVar,LowerIdent,OpAssign,Int,
|
||||
KwVar,LowerIdent,OpAssign,Int,
|
||||
KwFor,LowerIdent,KwIn,OpenSquare,Int,Comma,Int,Comma,Int,Comma,Int,Comma,Int,CloseSquare,OpenCurly,
|
||||
LowerIdent,OpAssign,LowerIdent,OpPlus,LowerIdent,
|
||||
KwIf,LowerIdent,OpGreaterThan,LowerIdent,OpenCurly,
|
||||
LowerIdent,OpAssign,LowerIdent,
|
||||
CloseCurly,KwElse,OpenCurly,
|
||||
OpenCurly,CloseCurly,
|
||||
CloseCurly,
|
||||
CloseCurly,
|
||||
LowerIdent,OpPlus,LowerIdent,
|
||||
CloseCurly,
|
||||
KwExpect,LowerIdent,OpEquals,Int,
|
||||
EndOfFile,
|
||||
~~~
|
||||
# PARSE
|
||||
~~~clojure
|
||||
(file
|
||||
(type-module)
|
||||
(statements
|
||||
(s-type-anno (name "result")
|
||||
(ty (name "U64")))
|
||||
(s-decl
|
||||
(p-ident (raw "result"))
|
||||
(e-block
|
||||
(statements
|
||||
(s-var (name "sum_")
|
||||
(e-int (raw "0")))
|
||||
(s-var (name "max_")
|
||||
(e-int (raw "0")))
|
||||
(s-for
|
||||
(p-ident (raw "n"))
|
||||
(e-list
|
||||
(e-int (raw "3"))
|
||||
(e-int (raw "7"))
|
||||
(e-int (raw "2"))
|
||||
(e-int (raw "9"))
|
||||
(e-int (raw "1")))
|
||||
(e-block
|
||||
(statements
|
||||
(s-decl
|
||||
(p-ident (raw "sum_"))
|
||||
(e-binop (op "+")
|
||||
(e-ident (raw "sum_"))
|
||||
(e-ident (raw "n"))))
|
||||
(e-if-then-else
|
||||
(e-binop (op ">")
|
||||
(e-ident (raw "n"))
|
||||
(e-ident (raw "max_")))
|
||||
(e-block
|
||||
(statements
|
||||
(s-decl
|
||||
(p-ident (raw "max_"))
|
||||
(e-ident (raw "n")))))
|
||||
(e-block
|
||||
(statements
|
||||
(e-record)))))))
|
||||
(e-binop (op "+")
|
||||
(e-ident (raw "sum_"))
|
||||
(e-ident (raw "max_"))))))
|
||||
(s-expect
|
||||
(e-binop (op "==")
|
||||
(e-ident (raw "result"))
|
||||
(e-int (raw "31"))))))
|
||||
~~~
|
||||
# FORMATTED
|
||||
~~~roc
|
||||
NO CHANGE
|
||||
~~~
|
||||
# CANONICALIZE
|
||||
~~~clojure
|
||||
(can-ir
|
||||
(d-let
|
||||
(p-assign (ident "result"))
|
||||
(e-block
|
||||
(s-var
|
||||
(p-assign (ident "sum_"))
|
||||
(e-num (value "0")))
|
||||
(s-var
|
||||
(p-assign (ident "max_"))
|
||||
(e-num (value "0")))
|
||||
(s-for
|
||||
(p-assign (ident "n"))
|
||||
(e-list
|
||||
(elems
|
||||
(e-num (value "3"))
|
||||
(e-num (value "7"))
|
||||
(e-num (value "2"))
|
||||
(e-num (value "9"))
|
||||
(e-num (value "1"))))
|
||||
(e-block
|
||||
(s-reassign
|
||||
(p-assign (ident "sum_"))
|
||||
(e-binop (op "add")
|
||||
(e-lookup-local
|
||||
(p-assign (ident "sum_")))
|
||||
(e-lookup-local
|
||||
(p-assign (ident "n")))))
|
||||
(e-if
|
||||
(if-branches
|
||||
(if-branch
|
||||
(e-binop (op "gt")
|
||||
(e-lookup-local
|
||||
(p-assign (ident "n")))
|
||||
(e-lookup-local
|
||||
(p-assign (ident "max_"))))
|
||||
(e-block
|
||||
(s-reassign
|
||||
(p-assign (ident "max_"))
|
||||
(e-lookup-local
|
||||
(p-assign (ident "n"))))
|
||||
(e-empty_record))))
|
||||
(if-else
|
||||
(e-block
|
||||
(e-empty_record))))))
|
||||
(e-binop (op "add")
|
||||
(e-lookup-local
|
||||
(p-assign (ident "sum_")))
|
||||
(e-lookup-local
|
||||
(p-assign (ident "max_")))))
|
||||
(annotation
|
||||
(ty-lookup (name "U64") (builtin))))
|
||||
(s-expect
|
||||
(e-binop (op "eq")
|
||||
(e-lookup-local
|
||||
(p-assign (ident "result")))
|
||||
(e-num (value "31")))))
|
||||
~~~
|
||||
# TYPES
|
||||
~~~clojure
|
||||
(inferred-types
|
||||
(defs
|
||||
(patt (type "Num(Int(Unsigned64))")))
|
||||
(expressions
|
||||
(expr (type "Num(Int(Unsigned64))"))))
|
||||
~~~
|
||||
Loading…
Add table
Add a link
Reference in a new issue