-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBuiltinManager.cpp
161 lines (133 loc) · 5.29 KB
/
BuiltinManager.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include "BuiltinManager.h"
#include <ctime>
#include "Object.h"
namespace
{
extern "C" COMPUTE_DUCK_API bool BUILTIN_FN(print)(Value* args, uint8_t argCount, Value& result)
{
if (argCount > 0)
{
for (size_t i = 0; i < argCount; ++i)
{
std::cout << args[i].Stringify();
if (i < argCount - 1)
std::cout << ",";
}
}
return false;
}
extern "C" COMPUTE_DUCK_API bool BUILTIN_FN(println)(Value* args, uint8_t argCount, Value& result)
{
if (argCount > 0)
{
for (size_t i = 0; i < argCount; ++i)
{
std::cout << args[i].Stringify();
if (i < argCount - 1)
std::cout << ",";
}
std::cout << std::endl;
}
return false;
}
extern "C" COMPUTE_DUCK_API bool BUILTIN_FN(sizeof)(Value* args, uint8_t argCount, Value& result)
{
if (argCount == 0 || argCount > 1)
ASSERT("[Native function 'sizeof']:Expect a argument.");
if (IS_ARRAY_VALUE(args[0]))
result = TO_ARRAY_VALUE(args[0])->len;
else if (IS_STR_VALUE(args[0]))
result = TO_STR_VALUE(args[0])->len;
else
ASSERT("[Native function 'sizeof']:Expect a array or string argument.");
return true;
}
extern "C" COMPUTE_DUCK_API bool BUILTIN_FN(insert)(Value* args, uint8_t argCount, Value& result)
{
if (argCount == 0 || argCount != 3)
ASSERT("[Native function 'insert']:Expect 3 arguments,the arg0 must be array or string object.The arg1 is the index object.The arg2 is the value object.");
if (IS_ARRAY_VALUE(args[0]))
{
ArrayObject* array = TO_ARRAY_VALUE(args[0]);
if (!IS_NUM_VALUE(args[1]))
ASSERT("[Native function 'insert']:Arg1 must be integer type while insert to a array");
uint32_t iIndex = (uint32_t)TO_NUM_VALUE(args[1]);
if (iIndex < 0 || iIndex >= array->len)
ASSERT("[Native function 'insert']:Index out of array's range");
ArrayInsert(array, iIndex, args[2]);
}
else if (IS_STR_VALUE(args[0]))
{
if (!IS_NUM_VALUE(args[1]))
ASSERT("[Native function 'insert']:Arg1 must be integer type while insert to a string");
uint32_t iIndex = (uint32_t)TO_NUM_VALUE(args[1]);
if (iIndex < 0 || iIndex > TO_STR_VALUE(args[0])->len)
ASSERT("[Native function 'insert']:Index out of array's range");
StrInsert(TO_STR_VALUE(args[0]), iIndex, TO_STR_VALUE(args[2]));
}
else
ASSERT("[Native function 'insert']:Expect a array or string argument.");
return false;
}
extern "C" COMPUTE_DUCK_API bool BUILTIN_FN(erase)(Value* args, uint8_t argCount, Value& result)
{
if (argCount == 0 || argCount != 2)
ASSERT("[Native function 'erase']:Expect 2 arguments,the arg0 must be array or string object.The arg1 is the corresponding index object.");
if (IS_ARRAY_VALUE(args[0]))
{
ArrayObject* array = TO_ARRAY_VALUE(args[0]);
if (!IS_NUM_VALUE(args[1]))
ASSERT("[Native function 'erase']:Arg1 must be integer type while deleting array element");
size_t iIndex = (size_t)TO_NUM_VALUE(args[1]);
if (iIndex < 0 || iIndex >= array->len)
ASSERT("[Native function 'erase']:Index out of array's range");
ArrayErase(array, iIndex);
}
else if (IS_STR_VALUE(args[0]))
{
if (!IS_NUM_VALUE(args[1]))
ASSERT("[Native function 'erase']:Arg1 must be integer type while deleting string element");
size_t iIndex = (size_t)TO_NUM_VALUE(args[1]);
if (iIndex < 0 || iIndex >= TO_STR_VALUE(args[0])->len)
ASSERT("[Native function 'erase']:Index out of array's range");
StrErase(TO_STR_VALUE(args[0]), iIndex);
}
else
ASSERT("[Native function 'erase']:Expect a array or string argument.");
return false;
}
extern "C" COMPUTE_DUCK_API bool BUILTIN_FN(clock)(Value* args, uint8_t argCount, Value& result)
{
result = clock() / CLOCKS_PER_SEC;
return true;
}
}
BuiltinManager* BuiltinManager::GetInstance()
{
static BuiltinManager instance;
return &instance;
}
BuiltinManager::BuiltinManager()
{
Register<BuiltinFn>("print", BUILTIN_FN(print));
Register<BuiltinFn>("println", BUILTIN_FN(println));
Register<BuiltinFn>("sizeof", BUILTIN_FN(sizeof));
Register<BuiltinFn>("insert", BUILTIN_FN(insert));
Register<BuiltinFn>("erase", BUILTIN_FN(erase));
Register<BuiltinFn>("clock", BUILTIN_FN(clock));
}
BuiltinManager::~BuiltinManager()
{
std::unordered_map<std::string_view, BuiltinObject*>().swap(m_BuiltinObjects);
}
BuiltinObject* BuiltinManager::FindBuiltinObject(std::string_view name)
{
auto iter = m_BuiltinObjects.find(name);
if (iter == m_BuiltinObjects.end())
ASSERT("No builtin object:%s", name.data());
return iter->second;
}
const std::unordered_map<std::string_view, BuiltinObject*> BuiltinManager::GetBuiltinObjectList() const
{
return m_BuiltinObjects;
}