loom

Форк
0
/
Value.cpp 
149 строк · 5.2 Кб
1
/*
2
MIT License
3

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

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

9
#include "simodo/variable/Variable.h"
10

11
#include "simodo/bormental/DrBormental.h"
12
#include "simodo/inout/format/fmt.h"
13

14
#include <cassert>
15

16
namespace simodo::variable
17
{
18
    std::shared_ptr<Object> Value::getInternalParent() const
19
    {
20
        if (type() != ValueType::Function)
21
            return {};
22

23
        std::shared_ptr<Object> obj = getObject();
24

25
        assert(!obj->variables().empty());
26

27
        variable::Variable & function_core = obj->getVariableByIndex_mutable(0);
28

29
        assert(function_core.type() == variable::ValueType::IntFunction);
30

31
        return function_core.value().getIntFunctionParent();
32
    }
33

34
    Value Value::copy() const
35
    {
36
        switch(_type)
37
        {
38
        case ValueType::Array:
39
            if (std::holds_alternative<std::shared_ptr<Array>>(_variant))
40
                return std::make_shared<Array>(getArray()->copy());
41
            return _type;
42
        case ValueType::Function:
43
            /// \todo При копировании функции ломается передача замыканий (нужно проверить)
44
            // return *this;
45
        case ValueType::Object:
46
            if (std::holds_alternative<std::shared_ptr<Object>>(_variant)) {
47
                Value ret { _type, std::make_shared<Object>(getObject()->copy()) };
48
                ret.checkInternalParents();
49
                return ret;
50
            }
51
            return _type;
52
        case ValueType::Ref:
53
            assert(getRef().origin().type() != ValueType::Ref);
54
            return getRef().origin().value().copy();
55
        default:
56
            return *this;
57
        }
58
    }
59

60
    void Value::checkInternalParents()
61
    {
62
        if (type() == ValueType::Object) {
63
            std::shared_ptr<Object> object = getObject();
64
                
65
            object->resetInternalParents(object);
66
        }
67
    }
68

69
    void Value::setInternalParent(std::shared_ptr<Object> parent)
70
    {
71
        assert(type() == ValueType::Function);
72

73
        std::shared_ptr<Object> function_object = getFunction();
74

75
        assert(!function_object->variables().empty());
76

77
        Variable & function_core = function_object->getVariableByIndex_mutable(0);
78
        
79
        assert(function_core.type() != ValueType::Null);
80

81
        if (function_core.type() == ValueType::IntFunction)
82
            function_core.value().getIntFunctionParent() = parent;
83
    }
84

85
    void Value::setValueRecursively(const Value & value)
86
    {
87
        if (isNull()) {
88
            setValue(value.copy());
89
            return;
90
        }
91

92
        assert(!isRef());
93
        assert(_type == value.type());
94

95
        switch(_type)
96
        {
97
        case ValueType::Array:
98
            if (std::holds_alternative<std::shared_ptr<Array>>(_variant)) {
99
                std::shared_ptr<Array> target_array = getArray();
100
                std::shared_ptr<Array> source_array = value.getArray();
101
                size_t                 i            = 0;
102

103
                for(; i < source_array->values().size() && i < target_array->values().size(); ++i) {
104
                    Value &       target_element = target_array->values_mutable()[i];
105
                    const Value & source_element = source_array->values_mutable()[i];
106

107
                    if (target_element.type() == source_element.type())
108
                        target_element.setValueRecursively(source_element);
109
                    else 
110
                        throw bormental::DrBormental("Value::setValueRecursively", 
111
                                                    inout::fmt("The types of array elements do not match"));
112
                }
113

114
                for(; i < source_array->values().size(); ++i)
115
                    target_array->add(source_array->values());
116
                break;
117
            }
118
            setValue(value.copy());
119
            break;
120
        case ValueType::Object:
121
            if (std::holds_alternative<std::shared_ptr<Object>>(_variant)) {
122
                std::shared_ptr<Object>       target = getObject();
123
                const std::shared_ptr<Object> source = value.getObject();
124

125
                for(const Variable & source_element : source->variables()) {
126
                    Variable & target_element = target->getVariableByName_mutable(source_element.name());
127
                    
128
                    if (target_element.name().empty())
129
                        target->add(source_element.copyVariable());
130
                    else if (target_element.value().isNull())
131
                        target_element.setValue(source_element.value().copy());
132
                    else if (target_element.type() == source_element.type())
133
                        target_element.value().setValueRecursively(source_element.value());
134
                    else
135
                        throw bormental::DrBormental("Value::setValueRecursively", 
136
                                                    inout::fmt("The types of the variable '%1' of the object do not match")
137
                                                    .arg(source_element.name()));
138
                }
139
                break;
140
            }
141
            setValue(value.copy());
142
            break;
143
        default:
144
            setValue(value.copy());
145
            break;
146
        }
147
    }
148

149
}

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

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

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

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