From b33e35df9f36adfea610d2e30ab2a16cda016608 Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 30 Mar 2025 12:42:37 +0200 Subject: [PATCH 1/5] Working implementation of assert_lrc --- src/rt/core/builtin.cc | 46 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/rt/core/builtin.cc b/src/rt/core/builtin.cc index fb28da2..c8f1150 100644 --- a/src/rt/core/builtin.cc +++ b/src/rt/core/builtin.cc @@ -390,11 +390,57 @@ namespace rt::core }); } + void test_builtins() + { + // Onus is on caller to provide a string object representing an actual integer + // Fixme: + // Refactor once integers are implemented + add_builtin("assert_lrc", [](auto frame, auto args) { + if (args != 2) + { + ui::error("assert_lrc() expected 2 arguments"); + } + + auto count_str = frame->stack_pop("count_str"); + auto bridge = frame->stack_pop("bridge"); + // Make sure we're comparing the correct LRC value + rt::remove_reference(frame->object(), bridge); + if (count_str->get_prototype() != stringPrototypeObject()) + { + ui::error("given count is not a string", count_str); + } + if (bridge->get_prototype() != objects::regionPrototypeObject()) + { + ui::error("given object is not a bridge", bridge); + } + // Remove string object whitespace + auto s = count_str->get_name(); + if (s[0] == '\"') + { + s.erase(0, 1); + s.erase(s.size() - 1); + } + auto count = std::stoi(s); + auto actual = rt::objects::get_region(bridge)->local_reference_count; + if (actual != count) + { + std::stringstream ss; + ss << "count: " << count << "did not match LRC: " << actual; + auto msg = ss.str(); + ui::error(msg, bridge); + } + + rt::remove_reference(frame->object(), count_str); + return std::nullopt; + }); + } + void init_builtins(ui::UI* ui) { mermaid_builtins(ui); ctor_builtins(); action_builtins(); pragma_builtins(); + test_builtins(); } } From 2d8bc97b1eb88ff51b572d7c7b5e26ce46d8bac3 Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 30 Mar 2025 12:46:42 +0200 Subject: [PATCH 2/5] Forgot test --- tests/builtin_test/assert_lrc_1.frank | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 tests/builtin_test/assert_lrc_1.frank diff --git a/tests/builtin_test/assert_lrc_1.frank b/tests/builtin_test/assert_lrc_1.frank new file mode 100644 index 0000000..97b45f8 --- /dev/null +++ b/tests/builtin_test/assert_lrc_1.frank @@ -0,0 +1,11 @@ +# Feels incorrect to utilize frank-tests for builtins +# that are meant to be utilized for frank-tests... +r1 = Region() +# Give r1 a LRC of 2 +a = {} +r1.a = a +# Using string object +expected = "2" +assert_lrc(r1, expected) +# Using string directly +assert_lrc(r1, "2") \ No newline at end of file From 81df7d91f786700a73dac89766da8f7d589c898c Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 30 Mar 2025 14:36:08 +0200 Subject: [PATCH 3/5] tests --- CMakeLists.txt | 3 +++ src/rt/core/builtin.cc | 9 ++++++--- tests/builtin_test/assert_lrc_bad_1.frank | 3 +++ tests/builtin_test/assert_lrc_bad_2.frank | 3 +++ tests/builtin_test/assert_lrc_bad_3.frank | 4 ++++ 5 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 tests/builtin_test/assert_lrc_bad_1.frank create mode 100644 tests/builtin_test/assert_lrc_bad_2.frank create mode 100644 tests/builtin_test/assert_lrc_bad_3.frank diff --git a/CMakeLists.txt b/CMakeLists.txt index 34a8a27..14c5c57 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,3 +91,6 @@ set_property(TEST unresolved_field.frank PROPERTY WILL_FAIL true) set_property(TEST unresolved_global.frank PROPERTY WILL_FAIL true) set_property(TEST unresolved_name.frank PROPERTY WILL_FAIL true) set_property(TEST func_no_return.frank PROPERTY WILL_FAIL true) +set_property(TEST assert_lrc_bad_1.frank PROPERTY WILL_FAIL true) +set_property(TEST assert_lrc_bad_2.frank PROPERTY WILL_FAIL true) +set_property(TEST assert_lrc_bad_3.frank PROPERTY WILL_FAIL true) diff --git a/src/rt/core/builtin.cc b/src/rt/core/builtin.cc index c8f1150..098d8be 100644 --- a/src/rt/core/builtin.cc +++ b/src/rt/core/builtin.cc @@ -409,9 +409,12 @@ namespace rt::core { ui::error("given count is not a string", count_str); } - if (bridge->get_prototype() != objects::regionPrototypeObject()) + auto region = objects::get_region(bridge); + if (region->bridge != bridge) { - ui::error("given object is not a bridge", bridge); + std::stringstream ss; + ss << bridge << " is not the bridge object of the region"; + ui::error(ss.str(), bridge); } // Remove string object whitespace auto s = count_str->get_name(); @@ -425,7 +428,7 @@ namespace rt::core if (actual != count) { std::stringstream ss; - ss << "count: " << count << "did not match LRC: " << actual; + ss << "count: " << count << " did not match LRC: " << actual; auto msg = ss.str(); ui::error(msg, bridge); } diff --git a/tests/builtin_test/assert_lrc_bad_1.frank b/tests/builtin_test/assert_lrc_bad_1.frank new file mode 100644 index 0000000..a822e81 --- /dev/null +++ b/tests/builtin_test/assert_lrc_bad_1.frank @@ -0,0 +1,3 @@ +# Not a bridge +a = {} +assert_lrc(a, "2") \ No newline at end of file diff --git a/tests/builtin_test/assert_lrc_bad_2.frank b/tests/builtin_test/assert_lrc_bad_2.frank new file mode 100644 index 0000000..fa163a4 --- /dev/null +++ b/tests/builtin_test/assert_lrc_bad_2.frank @@ -0,0 +1,3 @@ +# Not a string +a = {} +assert_lrc(a, a) \ No newline at end of file diff --git a/tests/builtin_test/assert_lrc_bad_3.frank b/tests/builtin_test/assert_lrc_bad_3.frank new file mode 100644 index 0000000..0ec49f2 --- /dev/null +++ b/tests/builtin_test/assert_lrc_bad_3.frank @@ -0,0 +1,4 @@ +r1 = Region() +expected = "2" +# LRC is only 1 +assert_lrc(r1, expected) \ No newline at end of file From 69b43cf572f13216822c026bea74aa02cfb5696f Mon Sep 17 00:00:00 2001 From: Max Date: Fri, 18 Apr 2025 14:51:31 +0200 Subject: [PATCH 4/5] added sbrc option --- src/rt/core/builtin.cc | 107 ++++++++++++++++++++++++++--------------- 1 file changed, 69 insertions(+), 38 deletions(-) diff --git a/src/rt/core/builtin.cc b/src/rt/core/builtin.cc index 098d8be..fc7fb7f 100644 --- a/src/rt/core/builtin.cc +++ b/src/rt/core/builtin.cc @@ -390,50 +390,81 @@ namespace rt::core }); } + void assert_rc__function_impl( + verona::interpreter::FrameObj* frame, size_t args, bool assert_lrc) + { + std::string option; + if (assert_lrc) + { + option = "lrc"; + } + else + { + option = "sbrc"; + } + + + if (args != 2) + { + std::stringstream ss; + ss << "assert_" << option << " expected 2 arguments"; + ui::error(ss.str()); + } + + auto count_str = frame->stack_pop("count_str"); + auto bridge = frame->stack_pop("bridge"); + // Make sure we're comparing the correct LRC value + rt::remove_reference(frame->object(), bridge); + if (count_str->get_prototype() != stringPrototypeObject()) + { + ui::error("given count is not a string", count_str); + } + auto region = objects::get_region(bridge); + if (region->bridge != bridge) + { + std::stringstream ss; + ss << bridge << " is not the bridge object of the region"; + ui::error(ss.str(), bridge); + } + // Remove string object whitespace + auto s = count_str->get_name(); + if (s[0] == '\"') + { + s.erase(0, 1); + s.erase(s.size() - 1); + } + auto count = std::stoi(s); + size_t actual; + if (assert_lrc) + { + actual = rt::objects::get_region(bridge)->local_reference_count; + } + else + { + actual = rt::objects::get_region(bridge)->sub_region_reference_count; + } + if (actual != count) + { + std::stringstream ss; + ss << "count: " << count << " did not match " << option << ": " << actual; + auto msg = ss.str(); + ui::error(msg, bridge); + } + + rt::remove_reference(frame->object(), count_str); + }; + void test_builtins() { // Onus is on caller to provide a string object representing an actual integer // Fixme: // Refactor once integers are implemented add_builtin("assert_lrc", [](auto frame, auto args) { - if (args != 2) - { - ui::error("assert_lrc() expected 2 arguments"); - } - - auto count_str = frame->stack_pop("count_str"); - auto bridge = frame->stack_pop("bridge"); - // Make sure we're comparing the correct LRC value - rt::remove_reference(frame->object(), bridge); - if (count_str->get_prototype() != stringPrototypeObject()) - { - ui::error("given count is not a string", count_str); - } - auto region = objects::get_region(bridge); - if (region->bridge != bridge) - { - std::stringstream ss; - ss << bridge << " is not the bridge object of the region"; - ui::error(ss.str(), bridge); - } - // Remove string object whitespace - auto s = count_str->get_name(); - if (s[0] == '\"') - { - s.erase(0, 1); - s.erase(s.size() - 1); - } - auto count = std::stoi(s); - auto actual = rt::objects::get_region(bridge)->local_reference_count; - if (actual != count) - { - std::stringstream ss; - ss << "count: " << count << " did not match LRC: " << actual; - auto msg = ss.str(); - ui::error(msg, bridge); - } - - rt::remove_reference(frame->object(), count_str); + assert_rc__function_impl(frame, args, true); + return std::nullopt; + }); + add_builtin("assert_sbrc", [](auto frame, auto args) { + assert_rc__function_impl(frame, args, false); return std::nullopt; }); } From ded1d02691afae1ce0c87a8f5d309f95be3d206e Mon Sep 17 00:00:00 2001 From: Maxlytrius Date: Wed, 23 Apr 2025 11:05:54 +0200 Subject: [PATCH 5/5] Edge case for merge --- tests/regions/merge5.frank | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 tests/regions/merge5.frank diff --git a/tests/regions/merge5.frank b/tests/regions/merge5.frank new file mode 100644 index 0000000..d6c29de --- /dev/null +++ b/tests/regions/merge5.frank @@ -0,0 +1,15 @@ + +r1 = Region() +r2 = Region() +r1.r2 = r2 + +assert_sbrc(r1, "1") +r2 = None +assert_sbrc(r1, "0") +assert_lrc(r1.r2, "0") + +# Edge case where r2 does not contribute to sbrc of r1 +# Assure that lrc is unchanged +assert_lrc(r1, "1") +merge(r1.r2, r1) +assert_lrc(r1, "1") \ No newline at end of file