Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

### Changed
- instruction counter in the bytecode reader are displayed in hex, and count each instruction instead of each byte
- `let` / `mut` / `set` push a copy of their value when used as expression (instead of an internal reference)

### Removed
- removed a nearly never emitted `GET_CURRENT_PAGE_ADDR` instruction, since it's now always optimised with `CALL` into a `CALL_CURRENT_PAGE` instruction
Expand Down
2 changes: 1 addition & 1 deletion include/Ark/VM/VM.inl
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ inline void VM::call(internal::ExecutionContext& context, const uint16_t argc, V
ErrorKind::Type,
fmt::format(
"{} is not a Function but a {}",
maybe_value_ptr->toString(*this), std::to_string(call_type)));
maybe_value_ptr->toString(*this, /* show_as_code= */ true), std::to_string(call_type)));
}
}

Expand Down
9 changes: 2 additions & 7 deletions src/arkreactor/Compiler/Lowerer/ASTLowerer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -597,17 +597,12 @@ namespace Ark::internal
{
page(p).emplace_back(STORE, i);
m_locals_locator.addLocal(name);

if (!is_result_unused)
page(p).emplace_back(LOAD_FAST_BY_INDEX, 0);
}
else
{
page(p).emplace_back(SET_VAL, i);

if (!is_result_unused)
page(p).emplace_back(LOAD_FAST, i);
}
if (!is_result_unused)
page(p).emplace_back(LOAD_SYMBOL, i);

if (is_function)
m_opened_vars.pop();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ page_2
STORE 5
LOAD_FAST_BY_INDEX 0
SET_VAL 2
LOAD_FAST 2
LOAD_SYMBOL 2
RET 0
HALT 0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ page_1
page_2
STORE 5
SET_VAL_FROM_INDEX 0, 2
LOAD_FAST 2
LOAD_SYMBOL 2
RET 0
HALT 0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ page_1
STORE 2
MUL_SET_VAL 0, 2056
MUL_SET_VAL 0, 2056
LOAD_FAST 0
LOAD_SYMBOL 0
RET 0
HALT 0
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
(mut output ((let T "hello") (mut T print)))
(print output)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
TypeError: "hello" is not a Function but a String

In file tests/unittests/resources/DiagnosticsSuite/runtime/call_let_mut_not_a_function.ark:1
1 | (mut output ((let T "hello") (mut T print)))
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 | (print output)
3 |
45 changes: 38 additions & 7 deletions tests/unittests/resources/LangSuite/weird-tests.ark
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,54 @@
# just putting any and all weird code samples golfers come up with here,
# to ensure what's fixed stay fixed

(let f1 (fun (e) (append! output e)))
(let f2 (fun (x y) (append! output x y)))
(let f4 (fun (a b c d) (append! output a b c d)))

(test:suite weird {
(test:case "list:fill with let" {
(test:eq (list:fill (let x 2) x) [2 2]) })
(test:eq (list:fill (let x 2) x) [2 2])
(test:eq (builtin__list:fill (let y 3) y) [3 3 3]) })

(test:case "list:map with let" {
(mut output [])
(let f (fun (e) (append! output e)))
(list:map (let a [0 1]) f)
(list:map (let a [0 1]) f1)
(test:eq output [0 1]) })

(test:case "declare var inside call" {
(test:case "(Q ((let Q f1) 0))" {
# those append 0 to output first, due to the inner call,
# then they append [0] since 'append!' returns the modified list
(mut output [])
(Q ((let Q (fun (x) (append! output x))) 0))
(let f1 (fun (x) (append! output x)))
(Q ((let Q f1) 0))
(test:eq output [0 [0]])

(set output [])
((let P (fun (x) (append! output x))) (P 0))
(test:eq output [0 [0]]) }) })
((let P f1) (P 0))
(test:eq output [0 [0]]) })

(test:case "((let m list:map) (list:iota 0 5) f)" {
(mut output [])
((let m list:map) (list:iota 0 5) f1)
(test:eq output [0 1 2 3 4])

(set output [])
(m (list:iota 0 5) f1)
(test:eq output [0 1 2 3 4]) })

(test:case "(R 6 [(let R f2) 2])" {
(mut output [])
(R 6 [(let R f2) 2])
(test:eq output [6 [f2 2]]) })

(test:case "((@ [(let S f1) 2] 0) S)" {
(mut output [])
((@ [(let S f1) 2] 0) S)
(test:eq output [f1]) })

# this is another insanity due to how pushing variables works: we use LOAD_FAST for `n`, which pushes a ref,
# and just after, (set n 2) modifies it
(test:case "(f4 (mut n 1) (+ 0 n) n (set n 2))" {
(mut output [])
(f4 (mut n 1) (+ 0 n) n (set n 2))
(test:eq output [1 1 2 2]) }) })
Loading