Title here
Summary here
lib/std
folder of ArkScript-lang/Ark
Indentation matters to us, programmers (but not to the compiler):
The general rule of thumb is that a closing parenthesis should never be to the left of its matching opening parenthesis. All new lines should be a couple of spaces to the right of the opening parenthesis of the list they’re in. Example:
# demonstration of the creation of a function
# we create a constant named fact, and put a function in it
# taking a single argument, n
(let fact (fun (n) {
(mut a 1)
(mut acc 2)
# then we use a loop (for loops doesn't exist in ArkScript)
(while (<= acc n) {
(set a (* a acc))
# thus we need to increment the accumulator ourselves
(set acc (+ 1 acc)) })
# the return value
a }))
# then we call the function we just created
(print "Factorial 6 (with loop and acc): " (fact 6))
Functions and constants (the ones in the lib and in the builtins) are named following the convention described in the naming guidelines.
begin
blockfun
keyword ((begin
or {
)Complete example:
(let foo (fun (a) {
(if (= a 2)
{
(print "a = 2")
(egg (* 2 a)) }
{
(print "a != 2")
(egg 0) })}))
(let bar (fun (b c) {
(let boop (+ b c))
boop })
Use ArkScript formatter to enforce those guidelines:
# will print the formatted script, without updating it
arkscript -f script.ark --dry-run
# returns exit code 0 if the script is correctly formatted,
# exit code 1 otherwise (needs to be formatted)
arkscript -f script.ark --check
# format the file and write the changes to the file
arkscript -f script.ark
Each function and constant defined in the standard library should be documented, using ArkDoc format.
auto
whenever possible. Using it is tolerated for complex types such as iterators{
, }
) must be on its own lineif (condition) do_this();
) do not need to be enclosed in bracesfor
, while
, if
and (...)
, around each =
sign (wherever it is, even in for-loops), between #include
and the file to includeenum class
over enum
*
and &
are part of the type:// AVOID THIS
int *i = new int(5);
int &j = k;
// PREFERRED
int* i = new int(5);
int& j = k;
// AVOID THIS
for (auto value : container)
// PREFERRED
for (const auto& value : container)
for (auto&& value : container)
// AVOID THIS
for (std::size_t i = 0; i < container.size(); ++i)
...
// PREFERRED
for (std::size_t i = 0, end = container.size(); i < end; i++)
...
#ifndef
, #define
and #endif
, the define being in MACRO_CASEnoexcept
[[nodiscard]]
this
. Prefix every member variable with m_
inline
or templated)/**
* @file Lexer.hpp
* @author Lex Plateau (lexplt.dev@gmail.com)
* @brief Tokenize ArkScript code
* @date 2020-10-27
*
* @copyright Copyright (c) 2025
*
*/
#include <bla>
code...
Snippet to recapitulate guidelines for headers:
/**
* @file Lexer.hpp
* @author Lex Plateau (lexplt.dev@gmail.com)
* @brief Tokenize ArkScript code
* @date 2020-10-27
*
* @copyright Copyright (c) 2020
*
*/
#ifndef HEADER_GUARD
#define HEADER_GUARD
#include <Ark/Compiler/Something.hpp>
#include <vector>
namespace Ark
{
/**
* @brief doxygen documentation about the class
*
*/
class Lexer
{
public:
/**
* @brief doxygen documentation here
*
*/
Lexer();
/**
* @brief doxygen documentation here
*
* @param a_parameter defines the power of the flux capacitor
*/
void aMethod(const std::string& a_parameter);
private:
int m_member; ///< This is a doxygen comment
};
}
#endif // Adding an empty line at the end of each file is strongly advised