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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
- add support for raw strings: `r"string..."`, backslashes do not have to be escaped in them
- stdlib:
- new draft module `re`, using `google/re2` as the regex engine
- cli:
- new flag `--stats` when compiling code, outputting a JSON of compilation stats

### Changed
- `@` can be used with dictionaries: `(@ dict key)` will behave the same as `(dict:get dict key)`
Expand Down
37 changes: 22 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,22 +204,27 @@ DESCRIPTION
ArkScript programming language

SYNOPSIS
arkscript -h
arkscript -v
arkscript --dev-info
arkscript -e <expression>
arkscript -h
arkscript -v
arkscript --dev-info
arkscript -e <expression>
arkscript [-d] [-L <lib_dir>] [-f(importsolver|no-importsolver)]
[-f(macroprocessor|no-macroprocessor)] [-f(optimizer|no-optimizer)]
[-f(iroptimizer|no-iroptimizer)] [-fdebugger] [-fdump-ir] [-fno-cache] ((-c
<file>) | <file>)
[-f(irinliner|no-irinliner)] [-f(iroptimizer|no-iroptimizer)] [-fdebugger]
[-fdump-ir] [-fno-cache] -c <file> [--stats]

arkscript -f <file> [--(dry-run|check)]
arkscript [-d] [-L <lib_dir>] --ast <file>
arkscript -bcr <file> -on
arkscript -bcr <file> -a [-s <start> <end>]
arkscript -bcr <file> -st [-s <start> <end>]
arkscript -bcr <file> -vt [-s <start> <end>]
arkscript -bcr <file> [-cs] [-p <page>] [-s <start> <end>]
arkscript [-d] [-L <lib_dir>] [-f(importsolver|no-importsolver)]
[-f(macroprocessor|no-macroprocessor)] [-f(optimizer|no-optimizer)]
[-f(irinliner|no-irinliner)] [-f(iroptimizer|no-iroptimizer)] [-fdebugger]
[-fdump-ir] [-fno-cache] <file>

arkscript -f <file> [--(dry-run|check)]
arkscript [-d] [-L <lib_dir>] --ast <file>
arkscript -bcr <file> -on
arkscript -bcr <file> -a [-s <start> <end>]
arkscript -bcr <file> -st [-s <start> <end>]
arkscript -bcr <file> -vt [-s <start> <end>]
arkscript -bcr <file> [-cs] [-p <page>] [-s <start> <end>]

OPTIONS
-h, --help Display this message
Expand All @@ -238,6 +243,7 @@ OPTIONS
Toggle on and off the macro processor pass

-f(optimizer|no-optimizer) Toggle on and off the optimizer pass
-f(irinliner|no-irinliner) Toggle on and off the IR inliner pass
-f(iroptimizer|no-iroptimizer)
Toggle on and off the IR optimizer pass

Expand All @@ -246,6 +252,7 @@ OPTIONS
-fno-cache Disable the bytecode cache creation
-c, --compile Compile the given program to bytecode, but do not run
<file> If file is -, it reads code from stdin
--stats Gather stats about each compiler pass and print them to stdout
-f, --format Format the given source file in place
--dry-run Do not modify the file, only print out the changes
--check Check if a file formating is correctly, without modifying it.
Expand All @@ -270,10 +277,10 @@ OPTIONS
-s, --slice Select a slice of instructions in the bytecode

VERSION
4.2.0-94e546d6
4.7.2-28c5a9e6

BUILD DATE
2026-02-21T20:42:38Z
2026-09-04T18:22:01Z

LICENSE
Mozilla Public License 2.0
Expand Down
1 change: 1 addition & 0 deletions cppcheck-suppressions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ unusedFunction
unusedStructMember
checkersReport
*:include/Ark/Compiler/Instructions.x
*:include/Ark/Compiler/Statistics.x
3 changes: 2 additions & 1 deletion include/Ark/Compiler/AST/Optimizer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ namespace Ark::internal
* @brief Construct a new Optimizer
*
* @param debug level of debug
* @param stats_collector optional statistics collector
*/
explicit Optimizer(unsigned debug) noexcept;
explicit Optimizer(unsigned debug, Statistics* stats_collector = nullptr) noexcept;

/**
* @brief Send the AST to the optimizer, then run the different optimization strategies on it
Expand Down
2 changes: 2 additions & 0 deletions include/Ark/Compiler/AST/Parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,15 @@ namespace Ark::internal
public:
/**
* @brief Constructs a new Parser object
*
* @param debug debug level
* @param mode how the parser should behave regarding certain nodes and errors
*/
explicit Parser(unsigned debug, ParserMode mode = ParserMode::Interpret);

/**
* @brief Parse the given code
*
* @param filename can be left empty, used for error generation
* @param code content of the file
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ namespace Ark::internal
* @brief Create a new IRCompiler
*
* @param debug debug level
* @param stats_collector optional statistics collector
*/
explicit IRCompiler(unsigned debug);
explicit IRCompiler(unsigned debug, Statistics* stats_collector = nullptr);

/**
* @brief Turn a given IR into bytecode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@ namespace Ark::internal
* @brief Create a new IRInliner
*
* @param debug debug level
* @param stats_collector optional statistics collector
*/
explicit IRInliner(unsigned debug);
explicit IRInliner(unsigned debug, Statistics* stats_collector = nullptr);

/**
* @brief Attempt to inline IR blocks to avoid function calls when possible
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ namespace Ark::internal
* @brief Create a new IROptimizer
*
* @param debug debug level
* @param stats_collector optional statistics collector
*/
explicit IROptimizer(unsigned debug);
explicit IROptimizer(unsigned debug, Statistics* stats_collector = nullptr);

/**
* @brief Turn a given IR into bytecode
Expand Down
3 changes: 2 additions & 1 deletion include/Ark/Compiler/Lowerer/ASTLowerer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ namespace Ark::internal
* @brief Construct a new ASTLowerer object
*
* @param debug the debug level
* @param stats_collector optional statistics collector
*/
explicit ASTLowerer(unsigned debug);
explicit ASTLowerer(unsigned debug, Statistics* stats_collector = nullptr);

/**
* @brief Pre-fill tables (used by the debugger)
Expand Down
3 changes: 2 additions & 1 deletion include/Ark/Compiler/Macros/Processor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ namespace Ark::internal
* @brief Construct a new Macro Processor object
*
* @param debug the debug level
* @param stats_collector optional statistics collector
*/
explicit MacroProcessor(unsigned debug) noexcept;
explicit MacroProcessor(unsigned debug, Statistics* stats_collector = nullptr) noexcept;

/**
* @brief Send the complete AST and work on it
Expand Down
7 changes: 6 additions & 1 deletion include/Ark/Compiler/NameResolution/NameResolutionPass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,22 @@ namespace Ark::internal
public:
/**
* @brief Create a NameResolutionPass
*
* @param debug debug level
* @param stats_collector optional statistics collector
*/
explicit NameResolutionPass(unsigned debug);
explicit NameResolutionPass(unsigned debug, Statistics* stats_collector = nullptr);

/**
* @brief Start visiting the given AST, checking for mutability violation and unbound variables
*
* @param ast AST to analyze
*/
void process(const Node& ast);

/**
* @brief Unused overload that return the input AST (untouched as this pass only generates errors)
*
* @return const Node& ast
*/
[[nodiscard]] const Node& ast() const noexcept;
Expand All @@ -61,6 +65,7 @@ namespace Ark::internal

/**
* @brief Recursively visit nodes
*
* @param node node to visit
* @param register_declarations whether or not the visit should register declarations
*/
Expand Down
5 changes: 4 additions & 1 deletion include/Ark/Compiler/Package/ImportSolver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,16 @@ namespace Ark::internal
public:
/**
* @brief Create a new ImportSolver
*
* @param debug debug level
* @param libenv list of paths to the standard library
* @param stats_collector optional statistics collector
*/
ImportSolver(unsigned debug, const std::vector<std::filesystem::path>& libenv);
ImportSolver(unsigned debug, const std::vector<std::filesystem::path>& libenv, Statistics* stats_collector = nullptr);

/**
* @brief Configure the ImportSolver
*
* @param root path to the root file that imports all others
* @param origin_imports the first imports to go through
* @return ImportSolver& *this
Expand Down
33 changes: 30 additions & 3 deletions include/Ark/Compiler/Pass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@

#include <Ark/Utils/Platform.hpp>
#include <Ark/Utils/Logger.hpp>

#include <ostream>
#include <Ark/Compiler/Statistics.hpp>

namespace Ark::internal
{
Expand All @@ -28,8 +27,9 @@ namespace Ark::internal
*
* @param name the pass name, used for logging
* @param debug_level debug level
* @param stats_collector optional statistics collector
*/
Pass(std::string name, unsigned debug_level);
Pass(std::string name, unsigned debug_level, Statistics* stats_collector = nullptr);

virtual ~Pass() = default;

Expand All @@ -42,6 +42,33 @@ namespace Ark::internal

protected:
Logger m_logger;

/**
* @brief Register an event with the number of times it happened
*
* @param name
* @param quantity
*/
void addStat(Stats name, long quantity) const;

/**
* @brief Increase the number of times an event happened by `delta`
*
* @param name
* @param delta default: 1
*/
void statIncrementCount(Stats name, long delta = 1) const;

/**
* @brief Register an event with the time it took
*
* @param name
* @param quantity
*/
void addStat(const std::string& name, std::chrono::nanoseconds quantity) const;

private:
Statistics* m_stats { nullptr };
};
}

Expand Down
65 changes: 65 additions & 0 deletions include/Ark/Compiler/Statistics.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#ifndef ARK_COMPILER_STATISTICS_HPP
#define ARK_COMPILER_STATISTICS_HPP

#include <string>
#include <chrono>
#include <vector>

#include <Ark/Utils/Platform.hpp>

namespace Ark::internal
{
enum class Stats : unsigned
{
#define X(name) name,
#include "Statistics.x"

#undef X
Count
};

constexpr std::array StatNames = {
#define X(name) #name,
#include "Statistics.x"

#undef X
};

class ARK_API Statistics
{
public:
Statistics() = default;

/**
* @brief Register an event with the number of times it happened
*
* @param name
* @param quantity
*/
void count(Stats name, long quantity);

[[nodiscard]] long getCount(Stats name) const;

/**
* @brief Register an event with the time it took
*
* @param name
* @param quantity
*/
void time(const std::string& name, std::chrono::nanoseconds quantity);

[[nodiscard]] std::string asJson() const noexcept;

private:
struct Measure
{
std::string name;
std::chrono::nanoseconds duration;
};

std::vector<Measure> m_measures;
std::array<long, static_cast<std::size_t>(Stats::Count)> m_counts { 0 };
};
}

#endif // ARK_COMPILER_STATISTICS_HPP
7 changes: 7 additions & 0 deletions include/Ark/Compiler/Statistics.x
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
X(ASTOptimizerPrunedNodes)
X(Deprecations)
X(InlinedCalls)
X(OptimisedInstructions)
X(ExpressionsCompiled)
X(FullyQualifiedNames)
X(ProcessedImports)
4 changes: 4 additions & 0 deletions include/Ark/Compiler/Welder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <filesystem>

#include <Ark/Compiler/Common.hpp>
#include <Ark/Compiler/Statistics.hpp>
#include <Ark/Compiler/AST/Node.hpp>
#include <Ark/Compiler/AST/Parser.hpp>
#include <Ark/Compiler/Lowerer/ASTLowerer.hpp>
Expand Down Expand Up @@ -111,6 +112,8 @@ namespace Ark
[[nodiscard]] std::string textualIR() const noexcept;
[[nodiscard]] const bytecode_t& bytecode() const noexcept;

friend class Ark::State;

private:
std::vector<std::filesystem::path> m_lib_env;
uint16_t m_features;
Expand All @@ -120,6 +123,7 @@ namespace Ark
std::vector<internal::IR::Block> m_ir;
bytecode_t m_bytecode;
internal::Node m_computed_ast;
internal::Statistics m_stats;

internal::Parser m_parser;
internal::ImportSolver m_import_solver;
Expand Down
8 changes: 8 additions & 0 deletions include/Ark/State.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,13 @@ namespace Ark
*/
void setLibDirs(const std::vector<std::filesystem::path>& libenv) noexcept;

/**
* @brief Toggle compiler statistics gathering
*
* @param toggle
*/
void gatherStats(bool toggle) noexcept;

/**
* @brief Reset State (all member variables related to execution)
*
Expand Down Expand Up @@ -161,6 +168,7 @@ namespace Ark

unsigned m_debug_level;
uint16_t m_features;
bool m_gather_stats;

bytecode_t m_bytecode;
std::vector<std::filesystem::path> m_libenv;
Expand Down
Loading
Loading