loom

Форк
0
/
FunctionWrapper.cpp 
96 строк · 4.1 Кб
1
/*
2
MIT License
3

4
Copyright (c) 2022 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,
5

6
https://bmstu.codes/lsx/simodo/loom
7
*/
8

9
#include "simodo/variable/FunctionWrapper.h"
10
#include "simodo/bormental/DrBormental.h"
11
#include "simodo/inout/format/fmt.h"
12

13
#include <cassert>
14

15
namespace simodo::variable
16
{
17
    inline const std::string INVALID_FUNCTION_STRUCTURE = "Invalid function internal structure";
18

19
    FunctionWrapper::FunctionWrapper(const Variable & function_variable)
20
        : _function_variable(function_variable.origin())
21
        , _function_structure(_function_variable.value().getObject())
22
    {
23
        // assert(_function_variable.type() == ValueType::Function);
24
    }
25

26
    Value FunctionWrapper::invoke(VariableSetWrapper_mutable & arguments)
27
    {
28
        Variable calling_address = getCallingAddressVariable();
29

30
        castArguments(arguments);
31

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);
35

36
            // return_variable.setLocation(_dot.location);
37
            // return _machine.convertVariable_overridable(return_variable, getReturnDeclarationVariable().type());
38
            return return_value;
39
        }
40

41
        // if (calling_address.type() == ValueType::IntFunction) {
42
        //     InternalFunction_t internal_function_address = get<InternalFunction_t>(calling_address.value().variant());
43

44
        //     StWalkerState state = _machine.host().walker().walk(*internal_function_address);
45

46
        //     return (state == StWalkerState::Error) ? error_variable() : _machine.return_variable();
47
        // }
48

49
        throw bormental::DrBormental("FunctionWrapper::invoke", inout::fmt(INVALID_FUNCTION_STRUCTURE));
50
    }
51

52
    void FunctionWrapper::castArguments(VariableSetWrapper_mutable & arguments) const 
53
    {
54
        VariableSetWrapper declarations = getArgumentDeclarationVariables();
55

56
        if (arguments.size() != declarations.size())
57
            // throw SemanticException("FunctionWrapper::castArguments", 
58
            //                         _dot.location,
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));
62

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());
69
        }
70
    }
71

72
    const Variable & FunctionWrapper::getCallingAddressVariable() const
73
    {
74
        if (_function_structure->variables().size() < 2)
75
            throw bormental::DrBormental("FunctionWrapper::getCallingAddressVariable", inout::fmt(INVALID_FUNCTION_STRUCTURE));
76

77
        return _function_structure->variables()[0];
78
    }
79

80
    const Variable & FunctionWrapper::getReturnDeclarationVariable() const
81
    {
82
        if (_function_structure->variables().size() < 2)
83
            throw bormental::DrBormental("FunctionWrapper::getReturnDeclarationVariable", inout::fmt(INVALID_FUNCTION_STRUCTURE));
84

85
        return _function_structure->variables()[1];
86
    }
87

88
    VariableSetWrapper FunctionWrapper::getArgumentDeclarationVariables() const
89
    {
90
        if (_function_structure->variables().size() < 2)
91
            throw bormental::DrBormental("FunctionWrapper::getArgumentDeclarationVariables", inout::fmt(INVALID_FUNCTION_STRUCTURE));
92

93
        return VariableSetWrapper(_function_structure->variables(), 2, _function_structure->variables().size());
94
    }
95

96
}

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.