ArkScript
A small, lisp-inspired, functional scripting language
Closure.hpp
Go to the documentation of this file.
1/**
2 * @file Closure.hpp
3 * @author Lex Plateau (lexplt.dev@gmail.com)
4 * @brief Subtype of the value type, handling closures
5 * @date 2024-04-21
6 *
7 * @copyright Copyright (c) 2020-2025
8 *
9 */
10
11#ifndef VM_VALUE_CLOSURE_HPP
12#define VM_VALUE_CLOSURE_HPP
13
14#include <memory>
15#include <string>
16
18
19namespace Ark
20{
21 class VM;
22}
23
24namespace Ark::internal
25{
26 using PageAddr_t = uint16_t;
27
28 class ClosureScope;
29
30 /**
31 * @brief Closure management
32 *
33 */
34 class Closure
35 {
36 public:
37 /**
38 * @brief Construct a new Closure object
39 *
40 * @param scope the scope of the function turned into a closure
41 * @param pa the current page address of the function turned into a closure
42 */
43 Closure(const ClosureScope& scope, PageAddr_t pa) noexcept;
44
45 /**
46 * @brief Construct a new Closure object
47 * @param scope_ptr a shared pointer to the scope of the function turned into a closure
48 * @param pa the current page address of the function turned into a closure
49 */
50 Closure(const std::shared_ptr<ClosureScope>& scope_ptr, PageAddr_t pa) noexcept;
51
52 [[nodiscard]] const ClosureScope& scope() const noexcept { return *m_scope; }
53 [[nodiscard]] ClosureScope& refScope() const noexcept { return *m_scope; }
54 [[nodiscard]] const std::shared_ptr<ClosureScope>& scopePtr() const { return m_scope; }
55
56 /**
57 *
58 * @return PageAddr_t the bytecode page address this closure refers to
59 */
60 [[nodiscard]] PageAddr_t pageAddr() const { return m_page_addr; }
61
62 /**
63 * @brief Used when generating error messages in the VM, to see if a symbol might have been wrongly fully qualified
64 *
65 * @param end
66 * @param vm
67 * @return true if the closure has a field which is the end of 'end'
68 */
69 [[nodiscard]] bool hasFieldEndingWith(const std::string& end, const VM& vm) const;
70
71 /**
72 * @brief Print the closure to a string
73 *
74 * @param vm
75 */
76 std::string toString(VM& vm) const noexcept;
77
78 friend ARK_API bool operator==(const Closure& A, const Closure& B) noexcept;
79 friend ARK_API_INLINE bool operator<(const Closure& A, const Closure& B) noexcept;
80 friend struct std::hash<Ark::internal::Closure>;
81
82 private:
83 std::shared_ptr<ClosureScope> m_scope;
84 // keep track of the code page number, in case we need it later
86 };
87
88 inline bool operator<(const Closure& A, const Closure& B) noexcept
89 {
90 return A.m_page_addr < B.m_page_addr;
91 }
92}
93
94template <>
95struct std::hash<Ark::internal::Closure>
96{
97 [[nodiscard]] std::size_t operator()(const Ark::internal::Closure& s) const noexcept
98 {
99 return std::hash<Ark::internal::ClosureScope*> {}(s.m_scope.get());
100 }
101};
102
103#endif
#define ARK_API
Definition Module.hpp:22
ArkScript configuration macros.
#define ARK_API_INLINE
Definition Platform.hpp:50
The ArkScript virtual machine, executing ArkScript bytecode.
Definition VM.hpp:46
A class to store fields captured by a closure.
Closure management.
Definition Closure.hpp:35
std::string toString(VM &vm) const noexcept
Print the closure to a string.
Definition Closure.cpp:27
PageAddr_t pageAddr() const
Definition Closure.hpp:60
PageAddr_t m_page_addr
Definition Closure.hpp:85
friend ARK_API_INLINE bool operator<(const Closure &A, const Closure &B) noexcept
Definition Closure.hpp:88
const ClosureScope & scope() const noexcept
Definition Closure.hpp:52
ClosureScope & refScope() const noexcept
Definition Closure.hpp:53
bool hasFieldEndingWith(const std::string &end, const VM &vm) const
Used when generating error messages in the VM, to see if a symbol might have been wrongly fully quali...
Definition Closure.cpp:20
friend ARK_API bool operator==(const Closure &A, const Closure &B) noexcept
Definition Closure.cpp:41
const std::shared_ptr< ClosureScope > & scopePtr() const
Definition Closure.hpp:54
std::shared_ptr< ClosureScope > m_scope
Definition Closure.hpp:83
uint16_t PageAddr_t
Definition Closure.hpp:26