SayoriOS 0.3.3

eBatRuntime.c
1 #include "kernel.h"
2 #include "eBat.h"
3 #include "eBatRuntime.h"
4
5 BAT_GoTo_T* bat_runtime_find_goto(BAT_T* bat, char* key){
6 bat_debug("[Find GoTo] Size: %d\n", bat->Size_GT);
7 for (int i = 0; i < bat->Size_GT; i++){
8 BAT_GoTo_T* gt = (BAT_GoTo_T*) bat->GoTo[i];
9 bat_debug(" |--- '%s' == '%s'\n", gt->Identifier, key);
10 if (strcmp(gt->Identifier, key) == 0){
11 bat_debug(" |--- TRUE\n");
12 return gt;
13 }
14 }
15 bat_debug(" |--- NULL RETURN\n");
16 return NULL;
17 }
18
19 void bat_runtime_echo(BAT_T* bat,BAT_GROUP_T* group){
20 if (bat->Echo == 1 && group->Size > 0){
21 printf("%s ", EBAT_CONFIG_HELLO_LINE);
22 for (int i = 0; i < group->Size; i++){
23 BAT_TOKEN_T *Line = (BAT_TOKEN_T *) group->Tokens[i];
24 if (Line->type == BAT_TOKEN_TYPE_VARIABLE) {
25 printf("%c%s%c ", '%', Line->value,'%');
26 } else if (Line->type == BAT_TOKEN_TYPE_STRING) {
27 printf("\"%s\" ", Line->value);
28 } else {
29 printf("%s ", Line->value);
30 }
31
32 }
33 printf("\n");
34 }
35 #ifdef DEBUG
36 if (bat->Debug == 1){
37 for (int y = 0; y < group->Size; y++){
38 BAT_TOKEN_T* xtok = (BAT_TOKEN_T*) group->Tokens[y];
39 bat_debug(" |--- [%d | %d] Tok: [%d] %s | Val: %s \n", y+1, group->Size, xtok->type, bat_debug_type(xtok->type), xtok->value);
40 }
41 }
42 #endif
43 }
44
45 int bat_runtime_equal_var_and_string(int Line, BAT_TOKEN_T* Data1, BAT_TOKEN_T* Eq, BAT_TOKEN_T* Data2) {
46 if (Data1->type != BAT_TOKEN_TYPE_VARIABLE){
47 bat_fatalerror(Line, "The first value must be a variable.");
48 return 0;
49 }
50 if (Data2->type != BAT_TOKEN_TYPE_STRING){
51 bat_fatalerror(Line, "The second value must be a string.");
52 return 0;
53 }
54 eBatCheckModule(Line, EBAT_CONFIG_SYSTEM_SET, "System.Set");
55 eBatCheckVariable(Line, Data1->value, D1);
56
57 qemu_ok("D1: '%s' && D3 '%s'", D1, Data2->value);
58
59 int ret = 0;
60 if (Eq->type == BAT_TOKEN_TYPE_EQUAL){
61 ret = (strcmp(D1, Data2->value) == 0?1:0);
62 } else {
63 ret = (strcmp(D1, Data2->value) != 0?1:0);
64 }
65
66
67 free(D1);
68 return ret;
69 }
70
71 int bat_runtime_equal(int Line, BAT_TOKEN_T* Data1, BAT_TOKEN_T* Eq, BAT_TOKEN_T* Data2) {
72 if (Data1->type != Data2->type || (Data1->type != BAT_TOKEN_TYPE_VARIABLE && Data1->type != BAT_TOKEN_TYPE_NUMBER)) {
73 bat_fatalerror(Line, "You cannot compare different types of data. Only NUMBERS and VARIABLES are allowed to be compared.");
74 return 0;
75 }
76 if (Data1->type == BAT_TOKEN_TYPE_VARIABLE) {
77 eBatCheckModule(Line, EBAT_CONFIG_SYSTEM_SET, "System.Set");
78 eBatCheckVariable(Line, Data1->value, D1);
79 eBatCheckVariable(Line, Data2->value, D2);
80 if (D1 == NULL || D2 == NULL){
81 if (D1 != NULL) free((void*) D1);
82 if (D2 != NULL) free((void*) D2);
83 return 0;
84 }
85
86 int ret = (strcmp(D1, D2) == 0?1:0);
87
88 free(D1);
89 free(D2);
90 return ret;
91 } else if (Data1->type == BAT_TOKEN_TYPE_NUMBER){
92 int a = bat_strtol(Data1->value);
93 int b = bat_strtol(Data2->value);
94 switch (Eq->type) {
95 case BAT_TOKEN_TYPE_EQUAL:{
96 return (a == b?1:0);
97 }
98 case BAT_TOKEN_TYPE_NOT_EQUAL:{
99 return (a != b?1:0);
100 }
101 case BAT_TOKEN_TYPE_GREATER:{
102 return (a > b?1:0);
103 }
104 case BAT_TOKEN_TYPE_LESS:{
105 return (a < b?1:0);
106 }
107 case BAT_TOKEN_TYPE_LESS_EQUAL:{
108 return (a <= b?1:0);
109 }
110 case BAT_TOKEN_TYPE_GREATER_EQUAL:{
111 return (a >= b?1:0);
112 }
113 default:
114 return 0;
115 }
116 }
117 return 0;
118 }
119
120 int bat_runtime_eval(BAT_T* bat,BAT_GROUP_T* group, int line, int offset) {
121 if (group->Size <= 0) {
122 bat_debug("Group Size is 0\n");
123 return 0;
124 }
125
126 BAT_TOKEN_T *MainTok = (BAT_TOKEN_T *) group->Tokens[offset + 0];
127
128
129 bat_debug("[%d] MainTok == %s\n", offset, bat_debug_type(MainTok->type));
130
131 if (MainTok->type == BAT_TOKEN_TYPE_PAUSE){
132 bat_runtime_system_pause();
133 return 0;
134 } else if (MainTok->type == BAT_TOKEN_TYPE_GOTO){
135 EBAT_INVALIDARGC(line, group->Size - offset, 2);
136 BAT_TOKEN_T *Data1 = (BAT_TOKEN_T *) group->Tokens[offset + 1];
137 qemu_warn("Start goto '%s'\n", Data1->value);
138 BAT_GoTo_T* gt = NULL;
139 if (Data1->type == BAT_TOKEN_TYPE_VARIABLE){
140 eBatCheckVariable(line, Data1->value, D1);
141 gt = bat_runtime_find_goto(bat, D1);
142 free(D1);
143 } else {
144 gt = bat_runtime_find_goto(bat, Data1->value);
145 }
146 eBatCheckGoTo(line, gt);
147
148 int ret = 0;
149 for (int x = 0; x < gt->Size; x++){
150 BAT_GROUP_T* group = (BAT_GROUP_T*) gt->Groups[x];
151
152 bat_runtime_echo(bat, group);
153
154 ret = bat_runtime_eval(bat, group, line, 0);
155 bat_debug("sysline: %d | line: %d | ret: %d\n",gt->Line, line, ret);
156 if (EBAT_CONFIG_CRITICAL_STOP == 1 && ret > 0) {
157 bat_debug("CRITICAL OUT\n");
158 bat->ErrorCode = ret;
159 return ret;
160 break;
161 }
162 }
163 bat_runtime_eval(bat, (BAT_GROUP_T*) gt->Groups, line, 0);
164 return ret;
165 }
166
167 if (MainTok->type == BAT_TOKEN_TYPE_EXIT) {
168 EBAT_INVALIDARGC(line, group->Size - offset, 2);
169 BAT_TOKEN_T *Data1 = (BAT_TOKEN_T *) group->Tokens[offset + 1];
170 return (-1 * bat_strtol(Data1->value));
171 }
172
173 if (MainTok->type == BAT_TOKEN_TYPE_SET) {
174 eBatCheckModule(line, EBAT_CONFIG_SYSTEM_SET, "System.Set");
175 EBAT_INVALIDARGC(line, group->Size - offset, 4);
176 BAT_TOKEN_T *VAR = (BAT_TOKEN_T *) group->Tokens[offset + 1];
177 BAT_TOKEN_T *EQ = (BAT_TOKEN_T *) group->Tokens[offset + 2];
178 BAT_TOKEN_T *SET = (BAT_TOKEN_T *) group->Tokens[offset + 3];
179 eBatCheckMixingData(line, EQ->type, BAT_TOKEN_TYPE_SET);
180 if (SET->type == BAT_TOKEN_TYPE_NOT){
181 bat_runtime_system_set(VAR->value, NULL);
182 } else {
183 eBatCheckMixingData(line, SET->type, BAT_TOKEN_TYPE_STRING);
184 bat_runtime_system_set(VAR->value, SET->value);
185 }
186 }
187 if (MainTok->type == BAT_TOKEN_TYPE_ECHO) {
188 EBAT_INVALIDMINARGC(line, group->Size - offset, 2);
189 BAT_TOKEN_T *TextTok = (BAT_TOKEN_T *) group->Tokens[offset + 1];
190 //printf("TextTok is %s => '%s'\n", bat_debug_type(TextTok->type), TextTok->value);
191 if (TextTok->type == BAT_TOKEN_TYPE_DEBUG){
192 bat->Debug = !(bat->Debug);
193 return 0;
194 } else if (TextTok->type == BAT_TOKEN_TYPE_TRUE){
195 bat->Echo = 1;
196 return 0;
197 } else if (TextTok->type == BAT_TOKEN_TYPE_FALSE){
198 bat->Echo = 0;
199 return 0;
200 }
201
202 for (int ec = 1; ec < group->Size - offset; ec++){
203 int isStart = (ec == 1?1:0);
204 int isEnd = (group->Size - offset - 1 == ec?1:0);
205 BAT_TOKEN_T *Echo = (BAT_TOKEN_T *) group->Tokens[offset + ec];
206 //printf("\n |----- [%d | %d] '%s'\n",ec, group->Size - offset - 1, Echo->value);
207 if (Echo->type == BAT_TOKEN_TYPE_VARIABLE){
208 eBatCheckModule(line, EBAT_CONFIG_SYSTEM_SET, "System.Set");
209 eBatCheckVariable(line, Echo->value, Text);
210 bat_runtime_system_echo(Text, isStart, isEnd);
211 free(Text);
212 } else {
213 bat_runtime_system_echo(Echo->value, isStart, isEnd);
214 }
215 }
216 return 0;
217 }
218
219 if (MainTok->type == BAT_TOKEN_TYPE_IF) {
220
221 EBAT_INVALIDMINARGC(line, group->Size - offset, 3);
222
223 int isNOT = 0;
224
225 BAT_TOKEN_T *DataNOT = (BAT_TOKEN_T *) group->Tokens[offset + 1];
226 if (DataNOT->type == BAT_TOKEN_TYPE_NOT){
227 isNOT = 1;
228 }
229
230
231 BAT_TOKEN_T *Data1 = (BAT_TOKEN_T *) group->Tokens[offset + isNOT + 1];
232 BAT_TOKEN_T *Data2 = (BAT_TOKEN_T *) group->Tokens[offset + isNOT + 2];
233 BAT_TOKEN_T *Data3 = (BAT_TOKEN_T *) group->Tokens[offset + isNOT + 3];
234
235 if (Data1->type == BAT_TOKEN_TYPE_EXIST) {
236 qemu_note("D1 == BAT_TOKEN_TYPE_EXIST");
237 eBatCheckModule(line, EBAT_CONFIG_FILEIO_EXIST, "FileIO.Exits");
238 if (Data2->type == BAT_TOKEN_TYPE_STRING){
239 int breq = bat_runtime_fileio_exist(Data2->value);
240 bat_debug("IF EXIST STRING: %d | %d\n", breq, (breq == 1 && isNOT == 0) ||
241 (breq != 1 && isNOT == 1));
242 if ((breq == 1 && isNOT == 0) ||
243 (breq != 1 && isNOT == 1)){
244 bat_debug("Start eval %d\n", offset + isNOT + 3);
245 bat_runtime_eval(bat, group, line, offset + isNOT + 3);
246 }
247 } else {
248 eBatCheckMixingData(line, Data2->type, BAT_TOKEN_TYPE_VARIABLE);
249 eBatCheckModule(line, EBAT_CONFIG_SYSTEM_SET, "System.Set");
250 eBatCheckVariable(line, Data2->value, Path);
251
252 int breq = bat_runtime_fileio_exist(Path);
253 bat_debug("IF EXIST VARIABLE: %d\n", breq);
254 if ((breq == 1 && isNOT == 0) ||
255 (breq != 1 && isNOT == 1)){
256 bat_runtime_eval(bat, group, line, offset + isNOT + 3);
257 }
258
259 free(Path);
260 }
261
262 } else if (Data1->type == BAT_TOKEN_TYPE_NUMBER) {
263 qemu_note("D1 == BAT_TOKEN_TYPE_NUMBER");
264 EBAT_INVALIDMINARGC(line, group->Size - offset, offset + 4);
265
266 int breq = bat_runtime_equal(line, Data1, Data2, Data3);
267 if ((breq == 1 && isNOT == 0) ||
268 (breq != 1 && isNOT == 1)){
269 bat_runtime_eval(bat, group, line, offset + isNOT + 3);
270 }
271 bat_debug("breq: %d | xret\n", breq);
272
273 } else if (Data1->type == BAT_TOKEN_TYPE_VARIABLE && Data3->type == BAT_TOKEN_TYPE_VARIABLE) {
274 EBAT_INVALIDMINARGC(line, group->Size - offset, offset + 4);
275
276 int breq = bat_runtime_equal(line, Data1, Data2, Data3);
277 if ((breq == 1 && isNOT == 0) ||
278 (breq != 1 && isNOT == 1)){
279 bat_runtime_eval(bat, group, line, offset + isNOT + 3);
280 }
281 } else if (Data1->type == BAT_TOKEN_TYPE_VARIABLE && Data3->type == BAT_TOKEN_TYPE_STRING) {
282 qemu_ok("D1 == VAR && D3 == STR");
283 EBAT_INVALIDMINARGC(line, group->Size - offset, offset + 4);
284
285 int breq = bat_runtime_equal_var_and_string(line, Data1, Data2, Data3);
286 if ((breq == 1 && isNOT == 0) ||
287 (breq != 1 && isNOT == 1)) {
288 qemu_ok("[PASS] Line: %d | Off: %d", line, offset + isNOT + 4);
289 bat_runtime_eval(bat, group, line, offset + isNOT + 4);
290 }
291 }
292 }
293 if (MainTok->type == BAT_TOKEN_TYPE_RUN || MainTok->type == BAT_TOKEN_TYPE_STRING) {
294 int argc = group->Size - offset;
295 char **argv = malloc((argc + 1) * sizeof(char*));
296
297 if (argv == NULL) {
298 return 1;
299 }
300 for (int i = 0; i < argc; i++){
301 BAT_TOKEN_T *DataX = (BAT_TOKEN_T *) group->Tokens[offset + i];
302 if (DataX->type == BAT_TOKEN_TYPE_VARIABLE){
303 eBatCheckModule(line, EBAT_CONFIG_SYSTEM_SET, "System.Set");
304 eBatCheckVariable(line, DataX->value, Text);
305 size_t slen = strlen(Text);
306 argv[i] = malloc((slen + 1) * sizeof(char));
307 if (argv[i] == NULL) {
308 return 1;
309 }
310 memset(argv[i], 0, slen + 1);
311 memcpy(argv[i], Text, slen);
312 free(Text);
313 } else {
314 size_t slen = strlen(DataX->value);
315 argv[i] = malloc((slen + 1) * sizeof(char));
316 if (argv[i] == NULL) {
317 return 1;
318 }
319 memset(argv[i], 0, slen + 1);
320 memcpy(argv[i], DataX->value, slen);
321 }
322 printf("[%d] val: '%s'\n", i, DataX->value);
323 }
324 int ret = bar_runtime_system_exec(argc, argv);
325 return ret;
326 }
327
328 return 0;
329 }
330
331 int bat_runtime_exec(BAT_T* bat){
332 bat_debug("========================\n");
333 bat_debug("Runtime EXEC\n");
334 bat_debug("========================\n");
335 int ret = 0;
336 for (int x = 0; x < bat->Size; x++){
337 BAT_GROUP_T* group = (BAT_GROUP_T*) bat->Group[x];
338
339 bat_runtime_echo(bat, group);
340
341 ret = bat_runtime_eval(bat, group, x + 1, 0);
342 bat_debug("line: %d | ret: %d\n", x +1, ret);
343 if (EBAT_CONFIG_CRITICAL_STOP == 1 && ret > 0) {
344 bat_debug("CRITICAL OUT\n");
345 //bat->ErrorCode = ret;
346 break;
347 }
348
349 }
350 bat->ErrorCode = ret;
351 bat_debug("========================\n");
352 return ret;
353 }
strlen
size_t strlen(const char *str)
Возращает длину строки
Definition: string.c:88
strcmp
int strcmp(const char *s1, const char *s2)
Сравнение строк
Definition: string.c:253
memset
void * memset(void *ptr, char value, size_t num)
Заполнение массива указанными символами
Definition: string.c:203
memcpy
void * memcpy(void *restrict destination, const void *restrict source, size_t n)
Копирование непересекающихся массивов используя SSE.
Definition: string.c:173
BAT_GROUP
Definition: eBat.h:77
BAT_TOKEN
Definition: eBat.h:72
BAT
Definition: eBat.h:91
Bat_GOTO
Definition: eBat.h:83