4
Copyright (c) 2022 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,
6
https://bmstu.codes/lsx/simodo/loom
9
#include "simodo/variable/FunctionWrapper.h"
10
#include "simodo/bormental/DrBormental.h"
11
#include "simodo/inout/format/fmt.h"
15
namespace simodo::variable
17
inline const std::string INVALID_FUNCTION_STRUCTURE = "Invalid function internal structure";
19
FunctionWrapper::FunctionWrapper(const Variable & function_variable)
20
: _function_variable(function_variable.origin())
21
, _function_structure(_function_variable.value().getObject())
23
// assert(_function_variable.type() == ValueType::Function);
26
Value FunctionWrapper::invoke(VariableSetWrapper_mutable & arguments)
28
Variable calling_address = getCallingAddressVariable();
30
castArguments(arguments);
32
if (calling_address.type() == ValueType::ExtFunction) {
33
ExternalFunction func = std::get<ExternalFunction>(calling_address.value().variant());
34
Value return_value = func.f(func.m.get(), arguments);
36
// return_variable.setLocation(_dot.location);
37
// return _machine.convertVariable_overridable(return_variable, getReturnDeclarationVariable().type());
41
// if (calling_address.type() == ValueType::IntFunction) {
42
// InternalFunction_t internal_function_address = get<InternalFunction_t>(calling_address.value().variant());
44
// StWalkerState state = _machine.host().walker().walk(*internal_function_address);
46
// return (state == StWalkerState::Error) ? error_variable() : _machine.return_variable();
49
throw bormental::DrBormental("FunctionWrapper::invoke", inout::fmt(INVALID_FUNCTION_STRUCTURE));
52
void FunctionWrapper::castArguments(VariableSetWrapper_mutable & arguments) const
54
VariableSetWrapper declarations = getArgumentDeclarationVariables();
56
if (arguments.size() != declarations.size())
57
// throw SemanticException("FunctionWrapper::castArguments",
59
// "The number of given parameters does not match the number of declared arguments for function '" +
60
// convertToU8(_function_variable.name()) + "'");
61
throw bormental::DrBormental("FunctionWrapper::castArguments", inout::fmt(INVALID_FUNCTION_STRUCTURE));
63
for(size_t i=0; i < arguments.size(); ++i) {
64
if (arguments[i].origin().type() != declarations[i].type() && declarations[i].type() != ValueType::Null)
65
// arguments[i] = _machine.convertVariable_overridable(arguments[i].origin(),declarations[i].type());
66
throw bormental::DrBormental("FunctionWrapper::castArguments", inout::fmt(INVALID_FUNCTION_STRUCTURE));
67
if (arguments[i].name() != declarations[i].name())
68
arguments[i].setName(declarations[i].name());
72
const Variable & FunctionWrapper::getCallingAddressVariable() const
74
if (_function_structure->variables().size() < 2)
75
throw bormental::DrBormental("FunctionWrapper::getCallingAddressVariable", inout::fmt(INVALID_FUNCTION_STRUCTURE));
77
return _function_structure->variables()[0];
80
const Variable & FunctionWrapper::getReturnDeclarationVariable() const
82
if (_function_structure->variables().size() < 2)
83
throw bormental::DrBormental("FunctionWrapper::getReturnDeclarationVariable", inout::fmt(INVALID_FUNCTION_STRUCTURE));
85
return _function_structure->variables()[1];
88
VariableSetWrapper FunctionWrapper::getArgumentDeclarationVariables() const
90
if (_function_structure->variables().size() < 2)
91
throw bormental::DrBormental("FunctionWrapper::getArgumentDeclarationVariables", inout::fmt(INVALID_FUNCTION_STRUCTURE));
93
return VariableSetWrapper(_function_structure->variables(), 2, _function_structure->variables().size());