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
8 changes: 4 additions & 4 deletions .github/workflows/c-cpp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: build-depends
run: sudo apt-get -y install libgtest-dev build-essential cmake libgtest-dev libuv1-dev
run: sudo apt update && sudo apt -y install libgtest-dev build-essential cmake libgtest-dev libuv1-dev && sudo apt clean
- name: configure
run: mkdir build && cd build && cmake ../
run: mkdir build && cd build && cmake ../ -DCMAKE_BUILD_TYPE=Debug
- name: make
run: make -C build/ VERBOSE=1
run: make -j8 -C build/ VERBOSE=1
- name: make test
run: make -C build/ test VERBOSE=1
run: ctest --test-dir build/ --output-on-failure
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ add_library(
src/networkprotocoldsl/operation.hpp
src/networkprotocoldsl/operation/add.cpp
src/networkprotocoldsl/operation/add.hpp
src/networkprotocoldsl/operation/dictionaryget.cpp
src/networkprotocoldsl/operation/dictionaryinitialize.cpp
src/networkprotocoldsl/operation/dictionaryset.cpp
src/networkprotocoldsl/operation/dynamiclist.cpp
src/networkprotocoldsl/operation/dynamiclist.hpp
src/networkprotocoldsl/operation/eq.cpp
Expand Down Expand Up @@ -110,6 +113,8 @@ add_library(
src/networkprotocoldsl/operation/writeoctets.hpp
src/networkprotocoldsl/operation/writestaticoctets.cpp
src/networkprotocoldsl/operation/writestaticoctets.hpp
src/networkprotocoldsl/operation/lexicalpadasdict.cpp
src/networkprotocoldsl/operation/lexicalpadasdict.hpp
src/networkprotocoldsl/parser/grammar/identifier.hpp
src/networkprotocoldsl/parser/grammar/identifier.cpp
src/networkprotocoldsl/parser/grammar/literals.hpp
Expand Down Expand Up @@ -195,6 +200,8 @@ add_library(
src/networkprotocoldsl/operationconcepts.hpp
src/networkprotocoldsl/optree.cpp
src/networkprotocoldsl/optree.hpp
src/networkprotocoldsl/print_optreenode.cpp
src/networkprotocoldsl/print_optreenode.hpp
src/networkprotocoldsl/value.cpp
src/networkprotocoldsl/value.hpp
)
Expand Down
21 changes: 21 additions & 0 deletions src/networkprotocoldsl/executionstackframe.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
#include <networkprotocoldsl/executionstackframe.hpp>
#include <networkprotocoldsl/operationconcepts.hpp>
#include <networkprotocoldsl/print_optreenode.hpp>
#include <networkprotocoldsl/value.hpp>

#include <cassert>
#include <fstream>
#include <iostream>
#include <memory>
#include <thread>

namespace networkprotocoldsl {

Expand Down Expand Up @@ -141,8 +145,25 @@ bool ExecutionStackFrame::has_arguments_ready() {

std::shared_ptr<LexicalPad> ExecutionStackFrame::get_pad() { return pad; }

static std::string get_debug_stream_file_name() {
std::thread::id this_id = std::this_thread::get_id();
std::ostringstream ss;
ss << "/tmp/thread_";
ss << this_id;
ss << "_debug.log";
return ss.str();
}

static void do_debug(ExecutionStackFrame *frame) {
thread_local static std::ofstream debug_file(get_debug_stream_file_name(),
std::ios_base::app);
print_optreenode(frame->optreenode, debug_file, "> ", "| ");
}

OperationResult ExecutionStackFrame::execute() {
assert(has_arguments_ready());

do_debug(this);
return std::visit(
[this](auto &o) { return execute_specific_operation(this, o); },
optreenode.operation);
Expand Down
3 changes: 3 additions & 0 deletions src/networkprotocoldsl/executionstackframe.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ using OperationContextVariant =
* only happen when the right number of inputs has been provided.
*/
class ExecutionStackFrame {
public:
const OpTreeNode &optreenode;

private:
std::shared_ptr<std::vector<Value>> accumulator;
OperationContextVariant ctx;
std::shared_ptr<LexicalPad> pad;
Expand Down
8 changes: 8 additions & 0 deletions src/networkprotocoldsl/interpreterrunner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ static bool handle_read(InterpreterContext &context,
} else {
if (context.eof.load()) {
context.interpreter.handle_eof();
signals.wake_up_for_output.notify();
signals.wake_up_interpreter.notify();
signals.wake_up_for_input.notify();
signals.wake_up_for_callback.notify();
} else {
signals.wake_up_for_input.notify();
}
Expand All @@ -52,6 +56,10 @@ static bool handle_read(InterpreterContext &context,
bool handle_write(InterpreterContext &context, InterpreterSignals &signals) {
if (context.eof.load()) {
context.interpreter.handle_eof();
signals.wake_up_for_output.notify();
signals.wake_up_interpreter.notify();
signals.wake_up_for_input.notify();
signals.wake_up_for_callback.notify();
return true;
} else {
auto buffer = context.interpreter.get_write_buffer();
Expand Down
40 changes: 38 additions & 2 deletions src/networkprotocoldsl/lexer/tokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
#include <cstdlib>
#include <functional>
#include <optional>
#include <string>
#include <string_view>
#include <unordered_map>
#include <vector>

#include <lexertl/generator.hpp>
Expand All @@ -15,6 +17,40 @@
namespace networkprotocoldsl::lexer {
namespace {

// Function to unescape string literals
std::string unescape_string(const std::string &str) {
std::string result;
result.reserve(str.size());
for (size_t i = 0; i < str.size(); ++i) {
if (str[i] == '\\' && i + 1 < str.size()) {
switch (str[i + 1]) {
case 'n':
result += '\n';
break;
case 't':
result += '\t';
break;
case 'r':
result += '\r';
break;
case '\\':
result += '\\';
break;
case '\"':
result += '\"';
break;
default:
result += str[i + 1];
break;
}
++i;
} else {
result += str[i];
}
}
return result;
}

struct TokenRule {
std::string_view pattern;
std::function<void(std::vector<Token> &, const std::string_view &)> pusher;
Expand All @@ -36,10 +72,10 @@ const std::vector<TokenRule> token_rules = {
[](TP_ARGS) {
tokens.push_back(token::literal::Integer{std::atoi(str.data())});
}},
{"\\\"[^\"]*\\\"",
{"\\\"([^\"\\\\]|\\\\.)*\\\"",
[](TP_ARGS) {
tokens.push_back(token::literal::String{
std::string(str.substr(1, str.length() - 2))});
unescape_string(std::string(str.substr(1, str.length() - 2)))});
}},
{">",
[](TP_ARGS) {
Expand Down
5 changes: 5 additions & 0 deletions src/networkprotocoldsl/lexicalpad.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,9 @@ void LexicalPad::initialize_global(const std::string &name, Value v) {
}
}

Value LexicalPad::as_dict() const {
return value::Dictionary{
std::make_shared<std::unordered_map<std::string, Value>>(pad)};
}

} // namespace networkprotocoldsl
1 change: 1 addition & 0 deletions src/networkprotocoldsl/lexicalpad.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class LexicalPad {
Value set(const std::string &name, Value v);
void initialize(const std::string &name, Value v);
void initialize_global(const std::string &name, Value v);
Value as_dict() const;
};

} // namespace networkprotocoldsl
Expand Down
8 changes: 7 additions & 1 deletion src/networkprotocoldsl/operation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
#define NETWORKPROTOCOLDSL_OPERATION_HPP

#include <networkprotocoldsl/operation/add.hpp>
#include <networkprotocoldsl/operation/dictionaryget.hpp>
#include <networkprotocoldsl/operation/dictionaryinitialize.hpp>
#include <networkprotocoldsl/operation/dictionaryset.hpp>
#include <networkprotocoldsl/operation/dynamiclist.hpp>
#include <networkprotocoldsl/operation/eq.hpp>
#include <networkprotocoldsl/operation/functioncall.hpp>
Expand All @@ -11,6 +14,7 @@
#include <networkprotocoldsl/operation/int32literal.hpp>
#include <networkprotocoldsl/operation/inttoascii.hpp>
#include <networkprotocoldsl/operation/lesserequal.hpp>
#include <networkprotocoldsl/operation/lexicalpadasdict.hpp>
#include <networkprotocoldsl/operation/lexicalpadget.hpp>
#include <networkprotocoldsl/operation/lexicalpadinitialize.hpp>
#include <networkprotocoldsl/operation/lexicalpadinitializeglobal.hpp>
Expand Down Expand Up @@ -52,7 +56,9 @@ using Operation = std::variant<
operation::StaticCallable, operation::Subtract,
operation::TerminateListIfReadAhead, operation::UnaryCallback,
operation::WriteInt32Native, operation::WriteOctets,
operation::WriteStaticOctets>;
operation::WriteStaticOctets, operation::DictionaryInitialize,
operation::DictionarySet, operation::DictionaryGet,
operation::LexicalPadAsDict>;

} // namespace networkprotocoldsl

Expand Down
29 changes: 7 additions & 22 deletions src/networkprotocoldsl/operation/add.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,21 @@ namespace networkprotocoldsl::operation {

static Value _add(int32_t lhs, int32_t rhs) { return rhs + lhs; }

static Value _add(int32_t lhs, auto rhs) {
return value::RuntimeError::TypeError;
}

static Value _add(int32_t lhs, value::RuntimeError rhs) { return rhs; }

static Value _add(int32_t lhs, value::ControlFlowInstruction rhs) {
return rhs;
}

static Value _add(int32_t lhs, Value rhs) {
return std::visit([&lhs](auto rhs_v) -> Value { return _add(lhs, rhs_v); },
rhs);
}

static Value _add(value::Callable lhs, auto rhs) {
return value::RuntimeError::TypeError;
}
static Value _add(auto &, auto &) { return value::RuntimeError::TypeError; }

static Value _add(value::RuntimeError lhs, auto rhs) { return lhs; }

static Value _add(value::ControlFlowInstruction lhs, auto rhs) { return lhs; }

template <typename LHS, typename RHS> static Value _add(LHS lhs, RHS rhs) {
return value::RuntimeError::TypeError;
static Value _add(int32_t lhs, value::RuntimeError rhs) { return rhs; }

static Value _add(int32_t lhs, value::ControlFlowInstruction rhs) {
return rhs;
}

Value Add::operator()(Arguments a) const {
return std::visit([&a](auto lhs) { return _add(lhs, std::get<1>(a)); },
std::get<0>(a));
return std::visit([](auto lhs, auto rhs) { return _add(lhs, rhs); },
std::get<0>(a), std::get<1>(a));
}

} // namespace networkprotocoldsl::operation
1 change: 1 addition & 0 deletions src/networkprotocoldsl/operation/add.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class Add {
public:
using Arguments = std::tuple<Value, Value>;
Value operator()(Arguments a) const;
std::string stringify() const { return "Add{}"; }
};
static_assert(InterpretedOperationConcept<Add>);

Expand Down
1 change: 1 addition & 0 deletions src/networkprotocoldsl/operation/dictionaryget.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include <networkprotocoldsl/operation/dictionaryget.hpp>
44 changes: 44 additions & 0 deletions src/networkprotocoldsl/operation/dictionaryget.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#ifndef NETWORKPROTOCOLDSL_OPERATION_DICTIONARYGET_HPP
#define NETWORKPROTOCOLDSL_OPERATION_DICTIONARYGET_HPP

#include <networkprotocoldsl/operationconcepts.hpp>
#include <networkprotocoldsl/value.hpp>

namespace networkprotocoldsl::operation {

struct DictionaryGet {
private:
Value get(const value::Dictionary &dict) const {
auto it = dict.members->find(key);
if (it != dict.members->end()) {
return it->second;
}
return value::RuntimeError::NameError;
}

Value get(auto &) const { return value::RuntimeError::TypeError; }

Value get(value::RuntimeError &err) const { return err; }

public:
std::string key;
DictionaryGet(const std::string &key) : key(key) {}

using Arguments = std::tuple<Value>;

Value operator()(const Arguments &args) const {
return std::visit([&](auto &&dict) -> Value { return get(dict); },
std::get<0>(args));
}

std::string stringify() const {
return "DictionaryGet{key: \"" + key + "\"}";
}
};

static_assert(InterpretedOperationConcept<DictionaryGet>,
"DictionaryGet must conform to InterpretedOperationConcept");

} // namespace networkprotocoldsl::operation

#endif // NETWORKPROTOCOLDSL_OPERATION_DICTIONARYGET_HPP
1 change: 1 addition & 0 deletions src/networkprotocoldsl/operation/dictionaryinitialize.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include <networkprotocoldsl/operation/dictionaryinitialize.hpp>
28 changes: 28 additions & 0 deletions src/networkprotocoldsl/operation/dictionaryinitialize.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#ifndef NETWORKPROTOCOLDSL_OPERATION_DICTIONARYINITIALIZE_HPP
#define NETWORKPROTOCOLDSL_OPERATION_DICTIONARYINITIALIZE_HPP

#include <networkprotocoldsl/operationconcepts.hpp>
#include <networkprotocoldsl/value.hpp>

namespace networkprotocoldsl::operation {

struct DictionaryInitialize {
DictionaryInitialize() {}

using Arguments = std::tuple<>;

Value operator()(const Arguments &args) const {
return value::Dictionary{
std::make_shared<std::unordered_map<std::string, Value>>()};
}

std::string stringify() const { return "DictionaryInitialize{}"; }
};

static_assert(
InterpretedOperationConcept<DictionaryInitialize>,
"DictionaryInitialize must conform to InterpretedOperationConcept");

} // namespace networkprotocoldsl::operation

#endif // NETWORKPROTOCOLDSL_OPERATION_DICTIONARYINITIALIZE_HPP
1 change: 1 addition & 0 deletions src/networkprotocoldsl/operation/dictionaryset.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include <networkprotocoldsl/operation/dictionaryset.hpp>
Loading