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 src/operators/d_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ namespace sqf
return std::string(m_value.name());
}
sqf::runtime::type type() const override { return data_type(); }
virtual std::size_t hash() const override { return std::hash<size_t>()(m_value.container_id()); }
sqf::runtime::config value() const { return m_value; }
void value(sqf::runtime::config conf) { m_value = conf; }

Expand Down
1 change: 1 addition & 0 deletions src/operators/d_group.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ namespace sqf
std::string to_string() const override { return to_string_sqf(); }

sqf::runtime::type type() const override { return data_type(); }
virtual std::size_t hash() const override { return 0; }

bool is_null() const { return m_value.expired(); }

Expand Down
1 change: 1 addition & 0 deletions src/operators/d_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ namespace sqf
std::string to_string() const override { return to_string_sqf(); }

sqf::runtime::type type() const override { return data_type(); }
virtual std::size_t hash() const override { return 0; }

bool is_null() const { return m_value.expired(); }

Expand Down
1 change: 1 addition & 0 deletions src/operators/d_side.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ namespace sqf
std::string to_string() const override { return to_string_sqf(); }

sqf::runtime::type type() const override { return data_type(); }
virtual std::size_t hash() const override { return std::hash<size_t>()(static_cast<size_t>(m_value)); }

side value() const { return m_value; }
void value(side flag) { m_value = flag; }
Expand Down
2 changes: 2 additions & 0 deletions src/operators/ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "ops_dummy_unary.h"
#include "ops_dummy_binary.h"
#include "ops_osspecific.h"
#include "ops_hashmap.h"

namespace sqf
{
Expand Down Expand Up @@ -41,6 +42,7 @@ namespace sqf
sqf::operators::ops_dummy_unary(runtime);
sqf::operators::ops_dummy_binary(runtime);
sqf::operators::ops_osspecific(runtime);
sqf::operators::ops_hashmap(runtime);
}
}
}
1 change: 0 additions & 1 deletion src/operators/ops_dummy_binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,6 @@ void sqf::operators::ops_dummy_binary(sqf::runtime::runtime& runtime)
runtime.register_sqfop(binary(4, "menuvalue", t_any(), t_any(), "", [](sqf::runtime::runtime& runtime, value::cref l, value::cref r) -> value { runtime.__logmsg(logmessage::runtime::ErrorMessage(runtime.context_active().current_frame().diag_info_from_position(), "NOT IMPLEMENTED", "menuvalue")); return {}; }));
runtime.register_sqfop(binary(4, "settaskresult", t_any(), t_any(), "", [](sqf::runtime::runtime& runtime, value::cref l, value::cref r) -> value { runtime.__logmsg(logmessage::runtime::ErrorMessage(runtime.context_active().current_frame().diag_info_from_position(), "NOT IMPLEMENTED", "settaskresult")); return {}; }));
runtime.register_sqfop(binary(4, "setlightuseflare", t_any(), t_any(), "", [](sqf::runtime::runtime& runtime, value::cref l, value::cref r) -> value { runtime.__logmsg(logmessage::runtime::ErrorMessage(runtime.context_active().current_frame().diag_info_from_position(), "NOT IMPLEMENTED", "setlightuseflare")); return {}; }));
runtime.register_sqfop(binary(4, "breakout", t_any(), t_any(), "", [](sqf::runtime::runtime& runtime, value::cref l, value::cref r) -> value { runtime.__logmsg(logmessage::runtime::ErrorMessage(runtime.context_active().current_frame().diag_info_from_position(), "NOT IMPLEMENTED", "breakout")); return {}; }));
runtime.register_sqfop(binary(4, "isequaltypeany", t_any(), t_any(), "", [](sqf::runtime::runtime& runtime, value::cref l, value::cref r) -> value { runtime.__logmsg(logmessage::runtime::ErrorMessage(runtime.context_active().current_frame().diag_info_from_position(), "NOT IMPLEMENTED", "isequaltypeany")); return {}; }));
runtime.register_sqfop(binary(4, "drawtriangle", t_any(), t_any(), "", [](sqf::runtime::runtime& runtime, value::cref l, value::cref r) -> value { runtime.__logmsg(logmessage::runtime::ErrorMessage(runtime.context_active().current_frame().diag_info_from_position(), "NOT IMPLEMENTED", "drawtriangle")); return {}; }));
runtime.register_sqfop(binary(4, "lbsetselectcolor", t_any(), t_any(), "", [](sqf::runtime::runtime& runtime, value::cref l, value::cref r) -> value { runtime.__logmsg(logmessage::runtime::ErrorMessage(runtime.context_active().current_frame().diag_info_from_position(), "NOT IMPLEMENTED", "lbsetselectcolor")); return {}; }));
Expand Down
1 change: 0 additions & 1 deletion src/operators/ops_dummy_unary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,6 @@ void sqf::operators::ops_dummy_unary(sqf::runtime::runtime& runtime)
runtime.register_sqfop(unary("menuvalue", t_any(), "", [](sqf::runtime::runtime& runtime, value::cref r) -> value { runtime.__logmsg(logmessage::runtime::ErrorMessage(runtime.context_active().current_frame().diag_info_from_position(), "NOT IMPLEMENTED", "menuvalue")); return {}; })); /* ARRAY */
runtime.register_sqfop(unary("deleteidentity", t_any(), "", [](sqf::runtime::runtime& runtime, value::cref r) -> value { runtime.__logmsg(logmessage::runtime::ErrorMessage(runtime.context_active().current_frame().diag_info_from_position(), "NOT IMPLEMENTED", "deleteidentity")); return {}; })); /* STRING */
runtime.register_sqfop(unary("getaimingcoef", t_any(), "", [](sqf::runtime::runtime& runtime, value::cref r) -> value { runtime.__logmsg(logmessage::runtime::ErrorMessage(runtime.context_active().current_frame().diag_info_from_position(), "NOT IMPLEMENTED", "getaimingcoef")); return {}; })); /* OBJECT */
runtime.register_sqfop(unary("breakout", t_any(), "", [](sqf::runtime::runtime& runtime, value::cref r) -> value { runtime.__logmsg(logmessage::runtime::ErrorMessage(runtime.context_active().current_frame().diag_info_from_position(), "NOT IMPLEMENTED", "breakout")); return {}; })); /* STRING */
runtime.register_sqfop(unary("ropeattachedobjects", t_any(), "", [](sqf::runtime::runtime& runtime, value::cref r) -> value { runtime.__logmsg(logmessage::runtime::ErrorMessage(runtime.context_active().current_frame().diag_info_from_position(), "NOT IMPLEMENTED", "ropeattachedobjects")); return {}; })); /* OBJECT */
runtime.register_sqfop(unary("lbsetselectcolor", t_any(), "", [](sqf::runtime::runtime& runtime, value::cref r) -> value { runtime.__logmsg(logmessage::runtime::ErrorMessage(runtime.context_active().current_frame().diag_info_from_position(), "NOT IMPLEMENTED", "lbsetselectcolor")); return {}; })); /* ARRAY */
runtime.register_sqfop(unary("mineactive", t_any(), "", [](sqf::runtime::runtime& runtime, value::cref r) -> value { runtime.__logmsg(logmessage::runtime::ErrorMessage(runtime.context_active().current_frame().diag_info_from_position(), "NOT IMPLEMENTED", "mineactive")); return {}; })); /* OBJECT */
Expand Down
25 changes: 25 additions & 0 deletions src/operators/ops_generic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2041,6 +2041,29 @@ namespace
{
return execvm_any_string(runtime, {}, right);
}
value breakout_any_string(runtime& runtime, value::cref left, value::cref right)
{
auto target_scope = right.data<d_string>()->value();
auto& context = runtime.context_active();
size_t pop_frame_count = 0;
for (auto it = context.frames_rbegin(); it != context.frames_rend(); ++it, ++pop_frame_count)
{
if (it->scope_name() == target_scope)
{
for (; pop_frame_count != 0; --pop_frame_count)
{
context.pop_frame();
}
return left;
}
}
runtime.__logmsg(err::ScopeNameNotFound(runtime.context_active().current_frame().diag_info_from_position(), target_scope));
return {};
}
value breakout_string(runtime& runtime, value::cref right)
{
return breakout_any_string(runtime, {}, right);
}
}
void sqf::operators::ops_generic(sqf::runtime::runtime& runtime)
{
Expand Down Expand Up @@ -2137,6 +2160,8 @@ void sqf::operators::ops_generic(sqf::runtime::runtime& runtime)
runtime.register_sqfop(unary("preprocessFile", t_string(), "Reads and processes the content of the specified file. Preprocessor is C-like, supports comments using // or /* and */ and PreProcessor Commands.", preprocessfile_string));
runtime.register_sqfop(unary("scopeName", t_string(), "Defines name of current scope. Name is visible in debugger, and name is also used as reference in some commands like breakOut and breakTo. Scope name should be defined only once per scope. Trying to set a different name on the scope that has already defined scope name will result in error.", scopename_string));
runtime.register_sqfop(unary("scriptName", t_string(), "Assign a user friendly name to the runtime script this command is executed from. Once name is assigned, it cannot be changed.", scriptname_string));
runtime.register_sqfop(unary("breakOut", t_string(), "Breaks the code execution out of the scope with the name as provided and previously set using `scopeName`.", breakout_string));
runtime.register_sqfop(binary(4, "breakOut", t_any(), t_string(), "Breaks the code execution out of the scope with the name as provided and previously set using `scopeName`.", breakout_any_string));
runtime.register_sqfop(binary(4, "in", t_any(), t_array(), "Checks whether value is in array. String values will be compared casesensitive.", in_any_array));
runtime.register_sqfop(binary(4, "in", t_string(), t_string(), "Checks whether string is in string. Values will be compared casesensitive.", in_string_string));
runtime.register_sqfop(unary("throw", t_any(), "Throws an exception. The exception is processed by first catch block. This command will terminate further execution of the code.", throw_any));
Expand Down
11 changes: 11 additions & 0 deletions src/operators/ops_generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ namespace sqf
}

sqf::runtime::type type() const override { return data_type(); }
virtual std::size_t hash() const override { return 0; }

std::shared_ptr<sqf::runtime::context> value() const { return m_context.lock(); }
void value(std::weak_ptr<sqf::runtime::context> weak) { m_context = weak; }
Expand Down Expand Up @@ -113,6 +114,7 @@ namespace sqf
}

sqf::runtime::type type() const override { return data_type(); }
virtual std::size_t hash() const override { return std::hash<sqf::runtime::value>()(m_value); }

sqf::runtime::instruction_set target_code() const { return m_target_code; }
void target_code(sqf::runtime::instruction_set set) { m_target_code = set; }
Expand Down Expand Up @@ -164,6 +166,15 @@ namespace sqf
}

sqf::runtime::type type() const override { return data_type(); }
virtual std::size_t hash() const override
{
size_t hash = 0x9e3779b9;
hash ^= std::hash<std::string>()(m_variable) + 0x9e3779b9 + (hash << 6) + (hash >> 2);
hash ^= std::hash<float>()(m_from) + 0x9e3779b9 + (hash << 6) + (hash >> 2);
hash ^= std::hash<float>()(m_to) + 0x9e3779b9 + (hash << 6) + (hash >> 2);
hash ^= std::hash<float>()(m_step) + 0x9e3779b9 + (hash << 6) + (hash >> 2);
return hash;
}

std::string variable() const { return m_variable; }
void variable(std::string value) { m_variable = value; }
Expand Down
153 changes: 153 additions & 0 deletions src/operators/ops_hashmap.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
#include "ops_hashmap.h"
#include "../runtime/value.h"
#include "../runtime/logging.h"
#include "../runtime/runtime.h"
#include "../runtime/sqfop.h"
#include "../runtime/util.h"

#include "../runtime/d_string.h"
#include "../runtime/d_scalar.h"
#include "../runtime/d_boolean.h"
#include "../runtime/d_array.h"

#include <array>



namespace err = logmessage::runtime;
using namespace sqf::runtime;
using namespace sqf::types;

namespace
{
value createhashmap_(runtime& runtime)
{
return std::make_shared<d_hashmap>();
}
value createhashmapfromarray_array(runtime& runtime, value::cref right)
{
std::unordered_map<sqf::runtime::value, sqf::runtime::value> hashmap;
auto arr = right.data<d_array>();
for (size_t i = 0; i < arr->size(); i++)
{
auto& it = arr->at(i);
if (it.is<t_array>())
{
auto subArr = it.data<d_array>();
if (subArr->size() == 2)
{
auto& key = subArr->at(0);
auto& value = subArr->at(1);
// ToDo: Check key-type matches
hashmap[key] = value;
}
else
{
runtime.__logmsg(err::ExpectedArraySizeMissmatch(
runtime.context_active().current_frame().diag_info_from_position(),
2,
2,
subArr->size()));
}
}
else
{
runtime.__logmsg(err::ExpectedArrayTypeMissmatch(
runtime.context_active().current_frame().diag_info_from_position(),
i,
t_array(),
it.type()));
}
}
return std::make_shared<d_hashmap>(hashmap);
}
value set_hashmap_array(runtime& runtime, value::cref left, value::cref right)
{
auto data = left.data<d_hashmap>();
auto arr = right.data<d_array>();
if (arr->size() == 2)
{
auto& key = arr->at(0);
auto& value = arr->at(1);
// ToDo: Check key-type matches
data->map()[key] = value;
}
else
{
runtime.__logmsg(err::ExpectedArraySizeMissmatch(
runtime.context_active().current_frame().diag_info_from_position(),
2,
2,
arr->size()));
}
return {};
}
value get_hashmap_any(runtime& runtime, value::cref left, value::cref right)
{
auto data = left.data<d_hashmap>();
auto res = data->map().find(right);
if (res != data->map().end())
{
return res->second;
}
else
{
// ToDo: Log warning about key not found
}
return {};
}
value deleteat_hashmap_any(runtime& runtime, value::cref left, value::cref right)
{
auto data = left.data<d_hashmap>();
auto res = data->map().find(right);
if (res != data->map().end())
{
auto val = *res;
data->map().erase(right);
return val.second;
}
else
{
// ToDo: Log warning about key not found
}
return {};
}
value in_any_hashmap(runtime& runtime, value::cref left, value::cref right)
{
auto data = right.data<d_hashmap>();
return data->map().find(left) != data->map().end();
}
value count_hashmap(runtime& runtime, value::cref right)
{
return right.data<d_hashmap>()->map().size();
}
value keys_hashmap(runtime& runtime, value::cref right)
{
std::vector<value> keys;
auto data = right.data<d_hashmap>();
for (auto& it : data->map())
{
keys.push_back(it.first);
}
return std::make_shared<d_array>(keys);
}
value plus_hashmap(runtime& runtime, value::cref right)
{
std::unordered_map<sqf::runtime::value, sqf::runtime::value> hashmap = right.data<d_hashmap>()->map();
return std::make_shared<d_hashmap>(hashmap);
}
}

void sqf::operators::ops_hashmap(::sqf::runtime::runtime& runtime)
{
using namespace sqf::runtime::sqfop;
runtime.register_sqfop(nular("createHashMap", "Creates a hashmap.", createhashmap_));
runtime.register_sqfop(unary("createHashMapFromArray", t_array(), "Creates a hashmap from an key-value pair array ([[key, value], ...]).", createhashmapfromarray_array));
runtime.register_sqfop(binary(4, "set", t_hashmap(), t_array(), "Assigns a value to a hashmap.", set_hashmap_array));
runtime.register_sqfop(binary(4, "get", t_hashmap(), t_any(), "Receives a value from a hashmap.", get_hashmap_any));
runtime.register_sqfop(binary(4, "deleteAt", t_hashmap(), t_any(), "Removes a key-value pair from a hashmap.", deleteat_hashmap_any));
runtime.register_sqfop(binary(4, "in", t_any(), t_hashmap(), "Checks if a given key is inside a value.", in_any_hashmap));
runtime.register_sqfop(unary("count", t_hashmap(), "Returns the number of elements inside a hashmap.", count_hashmap));
runtime.register_sqfop(unary("keys", t_hashmap(), "Returns the keys of a hashmap.", keys_hashmap));
runtime.register_sqfop(unary("+", t_hashmap(), "Returns a copy of the hashmap.", plus_hashmap));
}
91 changes: 91 additions & 0 deletions src/operators/ops_hashmap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#pragma once
#include "../runtime/data.h"
#include "../runtime/type.h"
#include "../runtime/value.h"

#include <string>
#include <memory>
#include <unordered_map>
#include <functional>
#include <sstream>


namespace sqf
{
namespace runtime
{
struct t_hashmap : public type::extend<t_hashmap> { t_hashmap() : extend() {} static const std::string name() { return "HASHMAP"; } };
class runtime;
}
namespace types
{
class d_hashmap : public sqf::runtime::data
{
private:
std::unordered_map<sqf::runtime::value, sqf::runtime::value> m_map;
public:
using data_type = sqf::runtime::t_hashmap;
protected:
virtual bool do_equals(std::shared_ptr<data> other, bool invariant) const
{
auto& other_map = std::static_pointer_cast<d_hashmap>(other)->map();
auto& self_map = m_map;

return other_map == self_map;
}
public:
d_hashmap() = default;
d_hashmap(std::unordered_map<sqf::runtime::value, sqf::runtime::value> map) : m_map(map) {}

sqf::runtime::type type() const override { return data_type(); }
virtual std::size_t hash() const override
{
size_t hash = 0x9e3779b9;
for (auto& it : m_map)
{
hash ^= std::hash<sqf::runtime::value>()(it.first) + 0x9e3779b9 + (hash << 6) + (hash >> 2);
hash ^= std::hash<sqf::runtime::value>()(it.second) + 0x9e3779b9 + (hash << 6) + (hash >> 2);
}
return hash;
}

std::string to_string_sqf() const override
{
std::stringstream sstream;
sstream << "[";
if (m_map.size() > 0)
{
for (auto it : m_map)
{
sstream << "[" << it.first.to_string_sqf() << "," << it.second.to_string_sqf() << "]" << ",";
}
sstream.seekp(-1, std::ios_base::end);
}
sstream << "]";
return sstream.str();
}
std::string to_string() const override
{
std::stringstream sstream;
sstream << "[";
if (m_map.size() > 0)
{
for (auto it : m_map)
{
sstream << it.first.to_string() << ": " << it.second.to_string() << ",";
}
sstream.seekp(-1, std::ios_base::end);
}
sstream << "}";
return sstream.str();
}

std::unordered_map<sqf::runtime::value, sqf::runtime::value>& map() { return m_map; }
};
}

namespace operators
{
void ops_hashmap(::sqf::runtime::runtime& runtime);
}
}
1 change: 1 addition & 0 deletions src/operators/ops_namespace.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ namespace sqf

virtual std::string to_string() const override { return to_string_sqf(); }
sqf::runtime::type type() const override { return data_type(); }
virtual std::size_t hash() const override { return 0; }

std::shared_ptr<sqf::runtime::value_scope> value() { return m_scope.lock(); }
operator std::shared_ptr<sqf::runtime::value_scope>() { return m_scope.lock(); }
Expand Down
Loading