Skip to content

Commit 113bc62

Browse files
authored
Merge branch 'WerWolv:master' into new_lexer
2 parents 4802c74 + c2e4a67 commit 113bc62

File tree

5 files changed

+105
-33
lines changed

5 files changed

+105
-33
lines changed

lib/include/pl/core/evaluator.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ namespace pl::core {
159159
void pushSectionId(u64 id);
160160
void popSectionId();
161161
[[nodiscard]] u64 getSectionId() const;
162+
[[nodiscard]] u64 getUserSectionId() const;
162163
[[nodiscard]] u64 createSection(const std::string &name);
163164
void removeSection(u64 id);
164165
[[nodiscard]] std::vector<u8>& getSection(u64 id);

lib/include/pl/pattern_language.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,19 @@ namespace pl {
116116
* @brief Adds a virtual source file under the path
117117
* @param code the code of the source
118118
* @param source the source of the code
119+
* @param mainSource whether this is the main source (the one that gets executed first)
119120
* @return the source that was added or that already existed
120121
*/
121122
[[nodiscard]] api::Source* addVirtualSource(const std::string& code, const std::string& source, bool mainSource = false) const;
122123

124+
/**
125+
* @brief Runs a minimal lexer and preprocess step on the code and returns key-value pairs of all pragmas that were set
126+
* @param code the code of the source
127+
* @param source the source of the code
128+
* @return Key-value pairs of all pragmas that were set
129+
*/
130+
[[nodiscard]] std::map<std::string, std::string> getPragmaValues(const std::string &code, const std::string &source = api::Source::DefaultSource) const;
131+
123132
/**
124133
* @brief Aborts the currently running execution asynchronously
125134
*/

lib/source/pl/core/evaluator.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -947,6 +947,19 @@ namespace pl::core {
947947
return this->m_sectionIdStack.back();
948948
}
949949

950+
u64 Evaluator::getUserSectionId() const {
951+
if (this->m_sectionIdStack.empty())
952+
return 0;
953+
954+
for (auto it = this->m_sectionIdStack.rbegin(); it != this->m_sectionIdStack.rend(); ++it) {
955+
if (*it != ptrn::Pattern::MainSectionId && *it != ptrn::Pattern::HeapSectionId && *it != ptrn::Pattern::PatternLocalSectionId && *it != ptrn::Pattern::InstantiationSectionId)
956+
return *it;
957+
}
958+
959+
return 0;
960+
}
961+
962+
950963
u64 Evaluator::createSection(const std::string &name) {
951964
auto id = this->m_sectionId;
952965
this->m_sectionId++;

lib/source/pl/lib/std/mem.cpp

Lines changed: 49 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
namespace pl::lib::libstd::mem {
1414

15-
static std::optional<i128> findSequence(::pl::core::Evaluator *ctx, u64 occurrenceIndex, u64 offsetFrom, u64 offsetTo, const std::vector<u8> &sequence) {
15+
static std::optional<i128> findSequence(::pl::core::Evaluator *ctx, u64 occurrenceIndex, u64 offsetFrom, u64 offsetTo, u64 section, const std::vector<u8> &sequence) {
1616
u32 occurrences = 0;
1717
const u64 bufferSize = ctx->getDataSize();
1818

@@ -25,7 +25,7 @@ namespace pl::lib::libstd::mem {
2525
std::vector<u8> bytes(std::max(sequence.size(), size_t(4 * 1024)) + sequence.size(), 0x00);
2626
for (u64 offset = offsetFrom; offset < offsetTo; offset += bytes.size() - sequence.size()) {
2727
const auto bytesToRead = std::min<std::size_t>(bytes.size(), offsetTo - offset);
28-
ctx->readData(offset, bytes.data(), bytesToRead, ptrn::Pattern::MainSectionId);
28+
ctx->readData(offset, bytes.data(), bytesToRead, section);
2929
ctx->handleAbort();
3030

3131
for (u64 i = 0; i < bytes.size() - sequence.size(); i += 1) {
@@ -59,24 +59,31 @@ namespace pl::lib::libstd::mem {
5959
{
6060

6161
/* base_address() */
62-
runtime.addFunction(nsStdMem, "base_address", FunctionParameterCount::none(), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
63-
wolv::util::unused(params);
62+
runtime.addFunction(nsStdMem, "base_address", FunctionParameterCount::between(0, 1), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
63+
auto section = params.size() == 1 ? params[0].toUnsigned() : ptrn::Pattern::MainSectionId;
64+
if (section == 0xFFFF'FFFF'FFFF'FFFF)
65+
section = ctx->getUserSectionId();
66+
67+
if (section != ptrn::Pattern::MainSectionId)
68+
return 0;
6469

6570
return u128(ctx->getDataBaseAddress());
6671
});
6772

6873
/* size() */
69-
runtime.addFunction(nsStdMem, "size", FunctionParameterCount::none(), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
70-
wolv::util::unused(params);
74+
runtime.addFunction(nsStdMem, "size", FunctionParameterCount::between(0, 1), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
75+
auto section = params.size() == 1 ? params[0].toUnsigned() : ptrn::Pattern::MainSectionId;
76+
if (section == 0xFFFF'FFFF'FFFF'FFFF)
77+
section = ctx->getUserSectionId();
7178

72-
return u128(ctx->getDataSize());
79+
return u128(ctx->getSectionSize(section));
7380
});
7481

7582
/* find_sequence_in_range(occurrence_index, start_offset, end_offset, bytes...) */
7683
runtime.addFunction(nsStdMem, "find_sequence_in_range", FunctionParameterCount::moreThan(3), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
77-
auto occurrenceIndex = u64(params[0].toUnsigned());
78-
auto offsetFrom = u64(params[1].toUnsigned());
79-
auto offsetTo = u64(params[2].toUnsigned());
84+
const u64 occurrenceIndex = params[0].toUnsigned();
85+
const u64 offsetFrom = params[1].toUnsigned();
86+
const u64 offsetTo = params[2].toUnsigned();
8087

8188
std::vector<u8> sequence;
8289
for (u32 i = 3; i < params.size(); i++) {
@@ -88,59 +95,68 @@ namespace pl::lib::libstd::mem {
8895
sequence.push_back(u8(byte));
8996
}
9097

91-
return findSequence(ctx, occurrenceIndex, offsetFrom, offsetTo, sequence).value_or(-1);
98+
return findSequence(ctx, occurrenceIndex, offsetFrom, offsetTo, ctx->getUserSectionId(), sequence).value_or(-1);
9299
});
93100

94101
/* find_string_in_range(occurrence_index, start_offset, end_offset, string) */
95102
runtime.addFunction(nsStdMem, "find_string_in_range", FunctionParameterCount::exactly(4), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
96-
auto occurrenceIndex = u64(params[0].toUnsigned());
97-
auto offsetFrom = u64(params[1].toUnsigned());
98-
auto offsetTo = u64(params[2].toUnsigned());
99-
auto string = params[3].toString(false);
103+
const u64 occurrenceIndex = params[0].toUnsigned();
104+
const u64 offsetFrom = params[1].toUnsigned();
105+
const u64 offsetTo = params[2].toUnsigned();
106+
const auto string = params[3].toString(false);
100107

101-
return findSequence(ctx, occurrenceIndex, offsetFrom, offsetTo, std::vector<u8>(string.data(), string.data() + string.size())).value_or(-1);
108+
return findSequence(ctx, occurrenceIndex, offsetFrom, offsetTo, ctx->getUserSectionId(), std::vector<u8>(string.data(), string.data() + string.size())).value_or(-1);
102109
});
103110

104-
/* read_unsigned(address, size, endian) */
105-
runtime.addFunction(nsStdMem, "read_unsigned", FunctionParameterCount::exactly(3), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
106-
auto address = u64(params[0].toUnsigned());
107-
auto size = size_t(params[1].toSigned());
108-
types::Endian endian = params[2].toUnsigned();
111+
/* read_unsigned(address, size, endian, section) */
112+
runtime.addFunction(nsStdMem, "read_unsigned", FunctionParameterCount::between(3, 4), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
113+
const u64 address = params[0].toUnsigned();
114+
const size_t size = params[1].toSigned();
115+
const types::Endian endian = params[2].toUnsigned();
116+
u64 section = params.size() == 4 ? params[3].toUnsigned() : ptrn::Pattern::MainSectionId;
117+
if (section == 0xFFFF'FFFF'FFFF'FFFF)
118+
section = ctx->getUserSectionId();
109119

110120
if (size < 1 || size > 16)
111121
err::E0012.throwError(fmt::format("Read size {} is out of range.", size), "Try a value between 1 and 16.");
112122

113123
u128 result = 0;
114-
ctx->readData(address, &result, size, ptrn::Pattern::MainSectionId);
124+
ctx->readData(address, &result, size, section);
115125
result = hlp::changeEndianess(result, size, endian);
116126

117127
return result;
118128
});
119129

120-
/* read_signed(address, size, endian) */
121-
runtime.addFunction(nsStdMem, "read_signed", FunctionParameterCount::exactly(3), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
122-
auto address = u64(params[0].toUnsigned());
123-
auto size = size_t(params[1].toSigned());
124-
types::Endian endian = params[2].toUnsigned();
130+
/* read_signed(address, size, endian, section) */
131+
runtime.addFunction(nsStdMem, "read_signed", FunctionParameterCount::between(3, 4), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
132+
const u64 address = params[0].toUnsigned();
133+
const size_t size = params[1].toSigned();
134+
const types::Endian endian = params[2].toUnsigned();
135+
u64 section = params.size() == 4 ? params[3].toUnsigned() : ptrn::Pattern::MainSectionId;
136+
if (section == 0xFFFF'FFFF'FFFF'FFFF)
137+
section = ctx->getUserSectionId();
125138

126139
if (size < 1 || size > 16)
127140
err::E0012.throwError(fmt::format("Read size {} is out of range.", size), "Try a value between 1 and 16.");
128141

129142

130143
i128 value = 0;
131-
ctx->readData(address, &value, size, ptrn::Pattern::MainSectionId);
144+
ctx->readData(address, &value, size, section);
132145
value = hlp::changeEndianess(value, size, endian);
133146

134147
return hlp::signExtend(size * 8, value);
135148
});
136149

137-
/* read_string(address, size, endian) */
138-
runtime.addFunction(nsStdMem, "read_string", FunctionParameterCount::exactly(2), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
139-
auto address = u64(params[0].toUnsigned());
140-
auto size = size_t(params[1].toUnsigned());
150+
/* read_string(address, size, endian, section) */
151+
runtime.addFunction(nsStdMem, "read_string", FunctionParameterCount::between(2, 3), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
152+
const u64 address = params[0].toUnsigned();
153+
const size_t size = params[1].toSigned();
154+
u64 section = params.size() == 3 ? params[2].toUnsigned() : ptrn::Pattern::MainSectionId;
155+
if (section == 0xFFFF'FFFF'FFFF'FFFF)
156+
section = ctx->getUserSectionId();
141157

142158
std::string result(size, '\x00');
143-
ctx->readData(address, result.data(), size, ptrn::Pattern::MainSectionId);
159+
ctx->readData(address, result.data(), size, section);
144160

145161
return result;
146162
});

lib/source/pl/pattern_language.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,39 @@ namespace pl {
338338
return this->m_fileResolver.addVirtualFile(code, source, mainSource);
339339
}
340340

341+
std::map<std::string, std::string> PatternLanguage::getPragmaValues(const std::string &code, const std::string &source) const {
342+
std::map<std::string, std::string> pragmaValues;
343+
344+
const api::Source plSource(code, source);
345+
const auto result = m_internals.lexer->lex(&plSource);
346+
if (result.isOk()) {
347+
const auto tokens = result.unwrap();
348+
for (auto it = tokens.begin(); it != tokens.end(); ++it) {
349+
if (it->type == core::Token::Type::Directive && std::get<core::Token::Directive>(it->value) == core::Token::Directive::Pragma) {
350+
++it;
351+
if (it != tokens.end() && it->type == core::Token::Type::String) {
352+
auto literal = std::get<core::Token::Literal>(it->value);
353+
auto string = std::get_if<std::string>(&literal);
354+
if (string != nullptr) {
355+
auto pragmaKey = *string;
356+
++it;
357+
if (it != tokens.end() && it->type == core::Token::Type::String) {
358+
literal = std::get<core::Token::Literal>(it->value);
359+
string = std::get_if<std::string>(&literal);
360+
if (string != nullptr) {
361+
pragmaValues.emplace(pragmaKey, *string);
362+
}
363+
}
364+
}
365+
}
366+
}
367+
}
368+
}
369+
370+
return pragmaValues;
371+
}
372+
373+
341374
void PatternLanguage::abort() {
342375
this->m_internals.evaluator->abort();
343376
this->m_aborted = true;

0 commit comments

Comments
 (0)