ArkScript
A small, lisp-inspired, functional scripting language
ScopeView.cpp
Go to the documentation of this file.
2
3#include <Ark/Constants.hpp>
4
5#include <cassert>
6
7namespace Ark::internal
8{
9 ScopeView::ScopeView(pair_t* storage, const std::size_t start) noexcept :
10 m_storage(storage), m_start(start), m_size(0), m_min_id(MaxValue16Bits), m_max_id(0)
11 {}
12
13 void ScopeView::pushBack(uint16_t id, Value&& val) noexcept
14 {
15 if (id < m_min_id)
16 m_min_id = id;
17 if (id > m_max_id)
18 m_max_id = id;
19
20 m_storage[m_start + m_size] = std::make_pair(id, std::move(val));
21 ++m_size;
22 }
23
24 void ScopeView::pushBack(uint16_t id, const Value& val) noexcept
25 {
26 if (id < m_min_id)
27 m_min_id = id;
28 if (id > m_max_id)
29 m_max_id = id;
30
31 m_storage[m_start + m_size] = std::make_pair(id, val);
32 ++m_size;
33 }
34
35 void ScopeView::insertFront(const std::vector<pair_t>& values) noexcept
36 {
37 const std::size_t offset_by = values.size();
38 // If there is one day a bug with bad references, this can be caused by this code,
39 // called when inserting plugins variables in a scope (because we invalidate said
40 // references by moving them to another slot inside m_storage).
41 for (std::size_t i = 0; i < m_size; ++i)
42 {
43 // This is a weak attempt to prevent / notice the bug before it goes in production,
44 // if you hit this assertion read the comments carefully!
45 assert(m_storage[m_start + m_size - i - 1].second.valueType() != ValueType::Reference && "References can not be moved around!");
46 m_storage[m_start + m_size - i + offset_by - 1] = m_storage[m_start + m_size - i - 1];
47 }
48
49 std::size_t i = 0;
50 for (const pair_t& pair : values)
51 {
52 const uint16_t id = pair.first;
53 if (id < m_min_id)
54 m_min_id = id;
55 if (id > m_max_id)
56 m_max_id = id;
57
58 m_storage[m_start + i] = pair;
59 ++i;
60 }
61
62 m_size += offset_by;
63 }
64
65 bool ScopeView::maybeHas(const uint16_t id) const noexcept
66 {
67 return m_min_id <= id && id <= m_max_id;
68 }
69
70 Value* ScopeView::operator[](const uint16_t id_to_look_for) noexcept
71 {
72 if (!maybeHas(id_to_look_for))
73 return nullptr;
74
75 for (std::size_t i = m_start; i < m_start + m_size; ++i)
76 {
77 auto& [id, value] = m_storage[i];
78 if (id == id_to_look_for)
79 return &value;
80 }
81 return nullptr;
82 }
83
84 const Value* ScopeView::operator[](const uint16_t id_to_look_for) const noexcept
85 {
86 if (!maybeHas(id_to_look_for))
87 return nullptr;
88
89 for (std::size_t i = m_start; i < m_start + m_size; ++i)
90 {
91 auto& [id, value] = m_storage[i];
92 if (id == id_to_look_for)
93 return &value;
94 }
95 return nullptr;
96 }
97
98 uint16_t ScopeView::idFromValue(const Value& val) const noexcept
99 {
100 for (std::size_t i = m_start; i < m_start + m_size; ++i)
101 {
102 const auto& [id, value] = m_storage[i];
103 if (value == val)
104 return id;
105 }
106 return MaxValue16Bits;
107 }
108
109 void ScopeView::reset() noexcept
110 {
111 m_size = 0;
113 m_max_id = 0;
114 }
115
116 bool operator==(const ScopeView& A, const ScopeView& B) noexcept
117 {
118 // if we have two scopes with the same number of elements and starting at the same position,
119 // they must be identical, as we have a single storage for all scopes
120 return A.m_size == B.m_size && A.m_start == B.m_start;
121 }
122}
Constants used by ArkScript.
A class to handle the VM scope more efficiently.
Definition ScopeView.hpp:27
ScopeView()=delete
Deleted constructor to avoid creating ScopeViews pointing to nothing. Helps catch bugs at compile tim...
bool maybeHas(uint16_t id) const noexcept
Check if the scope maybe holds a specific symbol in memory.
Definition ScopeView.cpp:65
void insertFront(const std::vector< pair_t > &values) noexcept
Insert one or more pairs at the beginning of the scope.
Definition ScopeView.cpp:35
uint16_t m_max_id
Maximum stored ID, used for a basic bloom filter.
std::pair< uint16_t, Value > pair_t
Definition ScopeView.hpp:29
Value * operator[](uint16_t id_to_look_for) noexcept
Get a value from its symbol id.
Definition ScopeView.cpp:70
void pushBack(uint16_t id, Value &&val) noexcept
Put a value in the scope.
Definition ScopeView.cpp:13
void reset() noexcept
Reset size, min and max id for the scope, to signify it's empty.
uint16_t m_min_id
Minimum stored ID, used for a basic bloom filter.
uint16_t idFromValue(const Value &val) const noexcept
Get the id of a variable based on its value ; used for debug only.
Definition ScopeView.cpp:98
bool operator==(const Namespace &A, const Namespace &B)
Definition Namespace.hpp:21
constexpr uint16_t MaxValue16Bits
Definition Constants.hpp:70