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 .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ build_emscripten/
ninja/
cmake-build-*/
out/
__pycache__/

# Prerequisites
*.d
Expand Down
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,20 @@
## [Unreleased changes] - 20XX-XX-XX
### Breaking changes
- `assert` is no longer an instruction but a builtin
- when comparing values of different types using `<`, `>`, `<=`, `>=` and `=`, the result will always be `false` (it used to rely on the type index)

### Added
- added `BREAKPOINT` instruction
- breakpoints can be placed using `(breakpoint)` and `(breakpoint condition)`
- added a debugger that can be triggered on error or on breakpoint by passing `-fdebugger` to the CLI (see [the docs for the debugger](https://arkscript-lang.dev/docs/tutorials/debugging/))
- diagnostics can now be generated when using `State.doString`, using `Diagnostics::generateWithCode` (as the original code must be passed to the diagnostics generator)
- `empty?` can now take a dict, and returns `true` if it has no key/value pairs
- `len` can now work on dictionaries, counting the number of keys

### Changed
- changed the runpath of `arkscript` to look for `libArkReactor` under its (arkscript's) directory, {arkscript}/bin, {arkscript}/lib, and {arkscript}/../lib
- `and` and `or` require valid expressions, so `(or 1 (mut x 3))` is no longer valid code, as `(mut x 3)` doesn't return a value
- `(not (dict "a" 2))` now returns `false`, as `not` checks if the dict is empty

## [4.1.2] - 2026-01-09
### Added
Expand Down Expand Up @@ -876,7 +880,7 @@
- moved the VM FFI into include/Ark/VM

## [1.0.0-dev] - 2019
## Added
### Added
- beginning of the documentation
- compiler (ark code to ark bytecode)
- bytecode reader (human readable format)
Expand Down
31 changes: 2 additions & 29 deletions include/Ark/VM/Value/Value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ namespace Ark

friend ARK_API bool operator==(const Value& A, const Value& B) noexcept;
friend ARK_API_INLINE bool operator<(const Value& A, const Value& B) noexcept;
friend ARK_API_INLINE bool operator!(const Value& A) noexcept;
friend ARK_API bool operator!(const Value& A) noexcept;

friend class Ark::VM;
friend class Ark::BytecodeReader;
Expand All @@ -216,41 +216,14 @@ namespace Ark
inline bool operator<(const Value& A, const Value& B) noexcept
{
if (A.m_type != B.m_type)
return (A.typeNum() - B.typeNum()) < 0;
return false;
return A.m_value < B.m_value;
}

inline bool operator!=(const Value& A, const Value& B) noexcept
{
return !(A == B);
}

inline bool operator!(const Value& A) noexcept
{
switch (A.valueType())
{
case ValueType::List:
return A.constList().empty();

case ValueType::Number:
return A.number() == 0.0;

case ValueType::String:
return A.string().empty();

case ValueType::User:
[[fallthrough]];
case ValueType::Nil:
[[fallthrough]];
case ValueType::False:
return true;

case ValueType::True:
[[fallthrough]];
default:
return false;
}
}
}

namespace std
Expand Down
2 changes: 1 addition & 1 deletion lib/std
Submodule std updated 1 files
+9 −0 tests/dict-tests.ark
106 changes: 106 additions & 0 deletions src/arkreactor/Builtins/Builtins.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
--#
* @name toString
* @brief Convert a value to a string
* @param value anything
* =begin
* (print (toString "abc")) # "abc"
* (print (toString 1)) # "1"
* (print (toString (fun () ()))) # "Function@1"
* (print (toString print)) # "CProcedure"
* (print (toString [])) # "[]"
* (let x 1) (print (toString (fun (&x) ()))) # "(.x=1)"
* (print (toString (dict 1 2 3 4))) # "{1: 2, 3: 4}"
* (print (toString nil)) # "nil"
* (print (toString true)) # "true"
* (print (toString false)) # "false"
* =end
#--

--#
* @name type
* @brief Get the type of a given value as a string
* @param value anything
* =begin
* (print (type "abc")) # "String"
* (print (type 1)) # "Number"
* (print (type (fun () ()))) # "Function"
* (print (type print)) # "CProc"
* (print (type [])) # "List"
* (let x 1) (print (type (fun (&x) ()))) # "Closure"
* (print (type (dict 1 2 3 4))) # "Dict"
* (print (type nil)) # "Nil"
* (print (type true)) # "Bool"
* (print (type false)) # "Bool"
* =end
#--

--#
* @name nil?
* @brief Check if a value is nil
* @param value anything
* =begin
* (print (nil? "abc")) # false
* (print (nil? 1)) # false
* (print (nil? (fun () ()))) # false
* (print (nil? print)) # false
* (print (nil? [])) # false
* (print (nil? (dict 1 2 3 4))) # false
* (print (nil? nil)) # true
* (print (nil? true)) # false
* (print (nil? false)) # false
* =end
#--

--#
* @name comparison
* @brief Compare two values and return true or false
* @details Comparing two values (using `<`, `>`, `<=`, `>=` and `=`) with a different type will always return false
* @param a first value
* @param b second value
* =begin
* (print (< "abc" "def")) # true, string are compared lexicographically
* (print (< 2 1)) # false
* (print (> 3 -5.5) # true
* (print (> "Hello" ""))
* (print (<= [] [1 2])) # true, lists are compared lexicographically
* (print (<= [1 2] [1 0])) # false
* (print (<= [1 2] [10])) # true
* (print (>= 5 5)) # true
* (print (= false 5)) # false
* (print (!= false 5)) # true
* =end
#--

--#
* @name not
* @brief Convert a value to a boolean and invert it
* @param value anything
* =begin
* (print (not "")) # true
* (print (not "a")) # false
* (print (not 0)) # true
* (print (not 1)) # false
* (print (not [])) # true
* (print (not [1 2])) # false
* (print (not nil)) # true
* (print (not true)) # false
* (print (not false)) # true
* (print (not (dict))) # true
* (print (not (dict "a" 1))) # false
* =end
#--

--#
* @name hasField
* @brief Check if a closure has a given field
* @param c closure
* @param field string, field name to look for
* =begin
* (let x 1)
* (let b "hello")
* (let closure (fun (&x &b) ()))
* (print (hasField closure "x")) # true
* (print (hasField closure "b")) # true
* (print (hasField closure "B")) # false, field names are case-sensitive
* =end
#--
19 changes: 19 additions & 0 deletions src/arkreactor/Builtins/Dict.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
--#
* @name empty?
* @brief Check if a dict is empty
* @param a dict
* =begin
* (print (empty? (dict "a" 2))) # false
* (print (empty? (dict))) # true
* =end
#--

--#
* @name len
* @brief Return the length of a dictionary
* @param a dict
* =begin
* (print (len (dict)) # 0
* (print (len (dict "a" 1 "b" 2 "c" 3))) # 3
* =end
#--
79 changes: 79 additions & 0 deletions src/arkreactor/Builtins/List.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
--#
* @name len
* @brief Return the length of a list
* @param a list
* =begin
* (print (len [])) # 0
* (print (len (list)) # 0
* (print (len [1 2 3])) # 3
* =end
#--

--#
* @name empty?
* @brief Check if a list is empty
* @details `nil` is also considered empty, as it is the void value that can be returned by `head`
* @param a list
* =begin
* (print (empty? [])) # true
* (print (empty? (list)) # true
* (print (empty? nil)) # true
* (print (empty? [1 2 3])) # false
* =end
#--

--#
* @name head
* @brief Return the first element of a list, or nil if empty
* @param a list
* =begin
* (print (head [])) # nil
* (print (head (list)) # nil
* (print (head [1])) # 1
* (print (head [1 2 3])) # 1
* =end
#--

--#
* @name tail
* @brief Return the tail of a list, or empty list if it has one or less element
* @param a list
* =begin
* (print (tail [])) # []
* (print (tail (list)) # []
* (print (tail [1])) # []
* (print (tail [1 2 3])) # [2 3]
* =end
#--

--#
* @name @
* @brief Get an element in a list
* @details Raise an error if the index is out of range
* @param lst list
* @param i index (can be negative to start from the end)
* =begin
* (print (@ [1 2 3] 0)) # 1
* (print (@ [1 2 3] 1)) # 2
* (print (@ [1 2 3] 2)) # 3
* (print (@ [1 2 3] -1)) # 3
* (print (@ [1 2 3] -2)) # 2
* =end
#--

--#
* @name @@
* @brief Get an element in a list of lists, or list of strings
* @details Raise an error if an index is out of range
* @param lst list of collections (lists or strings, can be mixed)
* @param y index (can be negative to start from the end)
* @param x index (can be negative to start from the end)
* =begin
* (print (@@ [[1 2 3] [4 5 6] [7 8 9]] 0 1)) # 2
* (print (@@ [[1 2 3] [4 5 6] "ghi"] -1 1)) # h
* (print (@@ [[1 2 3] [4 5 6] [7 8 9]] 0 -1)) # 3
* (print (@@ ["abc" "def" "ghi"] 0 1)) # b
* (print (@@ ["abc" "def" "ghi"] -1 1)) # h
* (print (@@ ["abc" "def" "ghi"] 0 -1)) # c
* =end
#--
56 changes: 56 additions & 0 deletions src/arkreactor/Builtins/Math.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
--#
* @name +
* @brief Add two or more numbers together
* @param a number
* @param b... more numbers
* =begin
* (print (+ 1 2.5)) # 3.5
* (print (+ 5 -7.6 12)) # 9.4
* =end
#--

--#
* @name -
* @brief Subtract two or more numbers together
* @param a first number to subtract other numbers to
* @param b... more numbers
* =begin
* (print (- 1 2.5)) # -1.5
* (print (- 5 11 1)) # -7
* =end
#--

--#
* @name *
* @brief Multiply two or more numbers together
* @param a number
* @param b... more numbers
* =begin
* (print (* 2 2.5)) # 5
* (print (* 5 4 3)) # 60
* =end
#--

--#
* @name /
* @brief Divide two or more numbers together
* @details The result is always a floating point number. For an integer division, see **math:floordiv**
* @param a first number to divide by other numbers
* @param b... more numbers
* =begin
* (print (/ 10 3)) # 3.33333...
* (print (/ 99 5 4)) # (99 / 5) / 4 = 4.95
* =end
#--

--#
* @name mod
* @brief Compute the modulus of two numbers
* @details The result is always a floating point number
* @param a number
* @param b number
* =begin
* (print (mod 10 3)) # 1
* (print (mod 12.9 4)) # 0.9000000000000004
* =end
#--
Loading
Loading