diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 3118a88da..9504a3e32 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -12,3 +12,4 @@ Closes # (issue)
- [ ] I have updated the documentation if needed (on https://github.com/ArkScript-lang/website, content/docs/)
- [ ] I have added tests that prove my fix/feature is working
- [ ] New and existing tests pass locally with my changes
+- [ ] AI wasn't involved in order to develop this feature
diff --git a/.gitignore b/.gitignore
index 3c202a89d..f97660afb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,7 +13,6 @@ __arkscript__/
*.arkm
/*.ark
*.ark.ir
-!tests/unittests/resources/BytecodeReaderSuite/*.arkc
tools/*_hash.py
# Generated files
diff --git a/.run/a.ark.run.xml b/.run/a.ark.run.xml
new file mode 100644
index 000000000..2b60e9a3b
--- /dev/null
+++ b/.run/a.ark.run.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/.run/ast a.ark.run.xml b/.run/ast a.ark.run.xml
new file mode 100644
index 000000000..959a15b35
--- /dev/null
+++ b/.run/ast a.ark.run.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/.run/bcr a.ark.run.xml b/.run/bcr a.ark.run.xml
new file mode 100644
index 000000000..69548eab8
--- /dev/null
+++ b/.run/bcr a.ark.run.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.run/benchmarks.run.xml b/.run/benchmarks.run.xml
new file mode 100644
index 000000000..6cf632758
--- /dev/null
+++ b/.run/benchmarks.run.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/.run/build arkscript.run.xml b/.run/build arkscript.run.xml
new file mode 100644
index 000000000..96e5de93b
--- /dev/null
+++ b/.run/build arkscript.run.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/.run/cpp unittests.run.xml b/.run/cpp unittests.run.xml
new file mode 100644
index 000000000..900a033d4
--- /dev/null
+++ b/.run/cpp unittests.run.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.run/dbg a.ark.run.xml b/.run/dbg a.ark.run.xml
new file mode 100644
index 000000000..c2967a0da
--- /dev/null
+++ b/.run/dbg a.ark.run.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/.run/format a.ark.run.xml b/.run/format a.ark.run.xml
new file mode 100644
index 000000000..707dfa329
--- /dev/null
+++ b/.run/format a.ark.run.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/.run/format b.ark.run.xml b/.run/format b.ark.run.xml
new file mode 100644
index 000000000..b66bed6cd
--- /dev/null
+++ b/.run/format b.ark.run.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/.run/repl.run.xml b/.run/repl.run.xml
new file mode 100644
index 000000000..0b0c6772a
--- /dev/null
+++ b/.run/repl.run.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.run/update expected tests.run.xml b/.run/update expected tests.run.xml
new file mode 100644
index 000000000..4f3baa4d8
--- /dev/null
+++ b/.run/update expected tests.run.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 147f1ad5d..c6e8d7d12 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,7 +7,8 @@
### Added
- added new macro `$gensym`, to generate a unique symbol identifier to use in macros
-- `append`, `concat`, and `pop` can be use as values
+- `append`, `concat`, and `pop` can be used as values
+- new `ptr` command for the debugger, printing the VM pointers (ip, pp, sp)
### Changed
- all paths inside `if` should return a value, when used as an expression. If an `else` branch is missing, `nil` will be returned
diff --git a/README.md b/README.md
index 82e162463..48cc77493 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,23 @@
- # ArkScript 
+# ArkScript 
+
+


@@ -173,22 +192,22 @@ DESCRIPTION
ArkScript programming language
SYNOPSIS
- arkscript -h
- arkscript -v
- arkscript --dev-info
- arkscript -e
+ arkscript -h
+ arkscript -v
+ arkscript --dev-info
+ arkscript -e
arkscript [-d] [-L ] [-f(importsolver|no-importsolver)]
[-f(macroprocessor|no-macroprocessor)] [-f(optimizer|no-optimizer)]
[-f(iroptimizer|no-iroptimizer)] [-fdebugger] [-fdump-ir] [-fno-cache] ((-c
- ) | )
-
- arkscript -f [--(dry-run|check)]
- arkscript [-d] [-L ] --ast
- arkscript -bcr -on
- arkscript -bcr -a [-s ]
- arkscript -bcr -st [-s ]
- arkscript -bcr -vt [-s ]
- arkscript -bcr [-cs] [-p ] [-s ]
+ ) | )
+
+ arkscript -f [--(dry-run|check)]
+ arkscript [-d] [-L ] --ast
+ arkscript -bcr -on
+ arkscript -bcr -a [-s ]
+ arkscript -bcr -st [-s ]
+ arkscript -bcr -vt [-s ]
+ arkscript -bcr [-cs] [-p ] [-s ]
OPTIONS
-h, --help Display this message
diff --git a/include/Ark/VM/Debugger.hpp b/include/Ark/VM/Debugger.hpp
index eb5d76f3e..6f1b2189c 100644
--- a/include/Ark/VM/Debugger.hpp
+++ b/include/Ark/VM/Debugger.hpp
@@ -11,10 +11,12 @@
#ifndef ARK_VM_DEBUGGER_HPP
#define ARK_VM_DEBUGGER_HPP
+#include
#include
#include
#include
#include
+#include
#include
#include
@@ -103,6 +105,41 @@ namespace Ark::internal
}
private:
+ struct CommandArgs
+ {
+ VM* vm_ptr;
+ ExecutionContext* ctx_ptr;
+ std::size_t ip, pp;
+ };
+
+ struct StartsWith_t
+ {
+ } StartsWith;
+
+ struct Command
+ {
+ using Action_t = std::function;
+
+ bool is_exact;
+ std::vector names;
+ std::string description;
+ Action_t action;
+
+ Command(std::string name, std::string desc, Action_t&& do_this) :
+ is_exact(true), names({ std::move(name) }), description(std::move(desc)), action(do_this)
+ {}
+
+ Command(const std::initializer_list list_of_names, std::string desc, Action_t&& do_this) :
+ is_exact(true), names(list_of_names), description(std::move(desc)), action(do_this)
+ {}
+
+ Command(StartsWith_t, std::string start, std::string desc, Action_t&& do_this) :
+ is_exact(false), names({ std::move(start) }), description(std::move(desc)), action(std::move(do_this))
+ {}
+ };
+
+ std::vector m_commands;
+
std::vector> m_states;
std::vector m_libenv;
std::vector m_symbols;
@@ -116,6 +153,9 @@ namespace Ark::internal
std::string m_code; ///< Code added while inside the debugger
std::size_t m_line_count { 0 };
+ void initCommands();
+ std::optional matchCommand(const std::string& line) const;
+
void showContext(const VM& vm, const ExecutionContext& context) const;
void showStack(VM& vm, const ExecutionContext& context, std::size_t count) const;
void showLocals(VM& vm, ExecutionContext& context, std::size_t count) const;
diff --git a/src/arkreactor/Builtins/String.cpp b/src/arkreactor/Builtins/String.cpp
index 16a880bd0..352b2ac3a 100644
--- a/src/arkreactor/Builtins/String.cpp
+++ b/src/arkreactor/Builtins/String.cpp
@@ -226,16 +226,7 @@ namespace Ark::internal::Builtins::String
else if (it->valueType() == ValueType::False)
store.push_back("false");
else if (it->valueType() == ValueType::List)
- {
- // std::vector r;
- // std::ranges::transform(
- // it->list(),
- // std::back_inserter(r),
- // [&vm](const Value& val) -> value_wrapper {
- // return value_wrapper { val, vm };
- // });
store.push_back(value_wrapper { *it, vm });
- }
else
store.push_back(it->toString(*vm));
}
diff --git a/src/arkreactor/VM/Debugger.cpp b/src/arkreactor/VM/Debugger.cpp
index 5b1194179..d97eb41ec 100644
--- a/src/arkreactor/VM/Debugger.cpp
+++ b/src/arkreactor/VM/Debugger.cpp
@@ -23,6 +23,7 @@ namespace Ark::internal
m_os(std::cout),
m_colorize(true)
{
+ initCommands();
saveState(context);
}
@@ -33,7 +34,9 @@ namespace Ark::internal
m_os(os),
m_colorize(false),
m_prompt_stream(std::make_unique(path_to_prompt_file))
- {}
+ {
+ initCommands();
+ }
void Debugger::saveState(const ExecutionContext& context)
{
@@ -128,6 +131,93 @@ namespace Ark::internal
m_running = false;
}
+ void Debugger::initCommands()
+ {
+ m_commands = {
+ Command(
+ "help",
+ "display this message",
+ [this](const std::string&, const CommandArgs&) {
+ fmt::println(m_os, "Available commands:");
+ for (const Command& cmd : m_commands)
+ {
+ if (cmd.is_exact)
+ fmt::println(m_os, " {} -- {}", fmt::join(cmd.names, ", "), cmd.description);
+ else
+ // todo: make arguments description configurable
+ fmt::println(m_os, " {} -- {}", fmt::join(cmd.names, ", "), cmd.description);
+ }
+ return false;
+ }),
+ Command(
+ { "c", "continue" },
+ "resume execution",
+ [this](const std::string&, const CommandArgs&) {
+ fmt::println(m_os, "dbg: continue");
+ return true;
+ }),
+ Command(
+ { "q", "quit" },
+ "quit the debugger, stopping the script execution",
+ [this](const std::string&, const CommandArgs&) {
+ fmt::println(m_os, "dbg: stop");
+ m_quit_vm = true;
+ return true;
+ }),
+ Command(
+ StartsWith,
+ "stack",
+ "show the last n values on the stack",
+ [this](const std::string& line, const CommandArgs& args) {
+ if (const auto arg = getArgAndParseOrError("stack", line, /* default_value= */ 5))
+ showStack(*args.vm_ptr, *args.ctx_ptr, arg.value());
+ return false;
+ }),
+ Command(
+ StartsWith,
+ "locals",
+ "show the last n values on the locals' stack",
+ [this](const std::string& line, const CommandArgs& args) {
+ if (const auto arg = getArgAndParseOrError("locals", line, /* default_value= */ 5))
+ showLocals(*args.vm_ptr, *args.ctx_ptr, arg.value());
+ return false;
+ }),
+ Command(
+ "ptr",
+ "show the values of the VM pointers",
+ [this](const std::string&, const CommandArgs& args) {
+ fmt::println(
+ m_os,
+ "IP: {} - PP: {} - SP: {}",
+ fmt::styled(args.ip / 4, m_colorize ? fmt::fg(fmt::color::cyan) : fmt::text_style()),
+ fmt::styled(args.pp, m_colorize ? fmt::fg(fmt::color::green) : fmt::text_style()),
+ fmt::styled(args.ctx_ptr->sp, m_colorize ? fmt::fg(fmt::color::yellow) : fmt::text_style()));
+ return false;
+ }),
+ };
+ }
+
+ std::optional Debugger::matchCommand(const std::string& line) const
+ {
+ for (const Command& c : m_commands)
+ {
+ if (c.is_exact)
+ {
+ if (std::ranges::find(c.names, line) != c.names.end())
+ return c;
+ }
+ else
+ {
+ if (std::ranges::find_if(c.names, [&line](const std::string& name) -> bool {
+ return line.starts_with(name);
+ }) != c.names.end())
+ return c;
+ }
+ }
+
+ return std::nullopt;
+ }
+
void Debugger::showContext(const VM& vm, const ExecutionContext& context) const
{
// show the line where the breakpoint hit
@@ -276,43 +366,20 @@ namespace Ark::internal
Utils::trimWhitespace(line);
- if (line == "c" || line == "continue" || line.empty())
+ if (line.empty() && !unfinished_block)
{
fmt::println(m_os, "dbg: continue");
return std::nullopt;
}
- else if (line == "q" || line == "quit")
- {
- fmt::println(m_os, "dbg: stop");
- m_quit_vm = true;
- return std::nullopt;
- }
- else if (line.starts_with("stack"))
- {
- if (auto arg = getArgAndParseOrError("stack", line, /* default_value= */ 5))
- showStack(vm, context, arg.value());
- else
- return std::nullopt;
- }
- else if (line.starts_with("locals"))
+
+ if (const auto& maybe_cmd = matchCommand(line))
{
- if (auto arg = getArgAndParseOrError("locals", line, /* default_value= */ 5))
- showLocals(vm, context, arg.value());
- else
+ if (maybe_cmd->action(line, CommandArgs { .vm_ptr = &vm, .ctx_ptr = &context, .ip = ip, .pp = pp }))
return std::nullopt;
}
- else if (line == "help")
- {
- fmt::println(m_os, "Available commands:");
- fmt::println(m_os, " help -- display this message");
- fmt::println(m_os, " c, continue -- resume execution");
- fmt::println(m_os, " q, quit -- quit the debugger, stopping the script execution");
- fmt::println(m_os, " stack -- show the last n values on the stack");
- fmt::println(m_os, " locals -- show the last n values on the locals' stack");
- }
else
{
- code += line;
+ code += line + "\n";
open_parens += Utils::countOpenEnclosures(line, '(', ')');
open_braces += Utils::countOpenEnclosures(line, '{', '}');
diff --git a/src/arkreactor/VM/VM.cpp b/src/arkreactor/VM/VM.cpp
index 27765f2dc..aa03026cf 100644
--- a/src/arkreactor/VM/VM.cpp
+++ b/src/arkreactor/VM/VM.cpp
@@ -106,7 +106,7 @@ namespace Ark
}
}
- Value VM::createList(const std::size_t count, internal::ExecutionContext& context)
+ Value VM::createList(const std::size_t count, ExecutionContext& context)
{
Value l(ValueType::List);
if (count != 0)
diff --git a/tests/unittests/TestsHelper.cpp b/tests/unittests/TestsHelper.cpp
index 826f482ac..89c01a17b 100644
--- a/tests/unittests/TestsHelper.cpp
+++ b/tests/unittests/TestsHelper.cpp
@@ -94,9 +94,14 @@ std::string sanitizeOutput(const std::string& output)
// remove the directory prefix so that we are environment agnostic
while (diag.find(ARK_TESTS_ROOT) != std::string::npos)
diag.erase(diag.find(ARK_TESTS_ROOT), std::size(ARK_TESTS_ROOT) - 1);
- Ark::Utils::ltrim(Ark::Utils::rtrim(diag));
+
+ auto lines = Ark::Utils::splitString(diag, '\n');
+ diag = "";
+ for (std::string& line : lines)
+ diag += Ark::Utils::rtrim(line) + "\n";
+
// we most likely have a blank line at the end now
- Ark::Utils::rtrim(diag);
+ Ark::Utils::ltrim(Ark::Utils::rtrim(diag));
return diag;
}
diff --git a/tests/unittests/resources/DebuggerSuite/basic.expected b/tests/unittests/resources/DebuggerSuite/basic.expected
index cc189307c..0f01725f8 100644
--- a/tests/unittests/resources/DebuggerSuite/basic.expected
+++ b/tests/unittests/resources/DebuggerSuite/basic.expected
@@ -6,10 +6,14 @@ In file tests/unittests/resources/DebuggerSuite/basic.ark:3
4 | (prn (format "ark: after first breakpoint, a={}, b={}" a b))
5 |
-dbg[pp:0,ip:3]:000> (let c (+ a b))
-dbg[pp:0,ip:3]:001> (prn c)
+dbg[pp:0,ip:3]:000> (let c
+dbg[pp:0,ip:3]:001: (+
+dbg[pp:0,ip:3]:002: a
+dbg[pp:0,ip:3]:003:
+dbg[pp:0,ip:3]:004: b))
+dbg[pp:0,ip:3]:005> (prn c)
11
-dbg[pp:0,ip:3]:002> c
+dbg[pp:0,ip:3]:006> c
dbg: continue
ark: after first breakpoint, a=5, b=6
@@ -31,6 +35,7 @@ Available commands:
q, quit -- quit the debugger, stopping the script execution
stack -- show the last n values on the stack
locals -- show the last n values on the locals' stack
+ ptr -- show the values of the VM pointers
dbg[pp:1,ip:5]:001> continue
dbg: continue
ark: in (foo x y z), after second breakpoint
diff --git a/tests/unittests/resources/DebuggerSuite/basic.prompt b/tests/unittests/resources/DebuggerSuite/basic.prompt
index 0f5648781..42369549e 100644
--- a/tests/unittests/resources/DebuggerSuite/basic.prompt
+++ b/tests/unittests/resources/DebuggerSuite/basic.prompt
@@ -1,4 +1,8 @@
-(let c (+ a b))
+(let c
+(+
+a
+
+b))
(prn c)
c
(prn x y z)
diff --git a/tests/unittests/resources/DebuggerSuite/stack_and_locals.expected b/tests/unittests/resources/DebuggerSuite/stack_and_locals.expected
index 7638509e4..deb72821a 100644
--- a/tests/unittests/resources/DebuggerSuite/stack_and_locals.expected
+++ b/tests/unittests/resources/DebuggerSuite/stack_and_locals.expected
@@ -7,6 +7,8 @@ In file tests/unittests/resources/DebuggerSuite/stack_and_locals.ark:8
9 | (prn (f 1 2))
10 |
+dbg[pp:0,ip:2]:000> ptr
+IP: 2 - PP: 0 - SP: 0
dbg[pp:0,ip:2]:000> stack
Stack is empty
diff --git a/tests/unittests/resources/DebuggerSuite/stack_and_locals.prompt b/tests/unittests/resources/DebuggerSuite/stack_and_locals.prompt
index c25e5fe48..8f6fe06c4 100644
--- a/tests/unittests/resources/DebuggerSuite/stack_and_locals.prompt
+++ b/tests/unittests/resources/DebuggerSuite/stack_and_locals.prompt
@@ -1,3 +1,4 @@
+ptr
stack
locals
c