SayoriOS 0.3.3

eBat.c
1 #include "kernel.h"
2 #include "eBat.h"
3 #include "eBatRuntime.h"
4
5
6 BAT_T* bat_create_session(){
7 BAT_T* bat = calloc(1, sizeof *bat);
8 if(!bat) {
9 return 0;
10 }
11 bat->Group = calloc(1, sizeof(size_t));
12 if(!bat->Group) {
13 free(bat);
14 return 0;
15 }
16 bat->GoTo = calloc(1, sizeof(size_t));
17 if(!bat->GoTo) {
18 free(bat);
19 return 0;
20 }
21 bat->Size = 0;
22 bat->Capacity = 1;
23 bat->Size_GT = 0;
24 bat->Capacity_GT = 1;
25 bat->CurGoTo = NULL;
26 return bat;
27 }
28
29 BAT_GROUP_T* bat_create_group(){
30 BAT_GROUP_T* group = calloc(1, sizeof *group);
31 if(!group) {
32 return 0;
33 }
34 group->Tokens = calloc(1, sizeof(size_t));
35 if(!group->Tokens) {
36 free(group);
37
38 return 0;
39 }
40 group->Size = 0;
41 group->Capacity = 1;
42 return group;
43 }
44
45 // Создание хранилища меток GoTo
46 BAT_GoTo_T* goto_create(const char* identifier) {
47 BAT_GoTo_T* goto_store = calloc(1, sizeof *goto_store);
48 if (!goto_store) {
49 return NULL;
50 }
51 goto_store->Identifier = bat_strdup(identifier); // Копируем строку идентификатора
52 if (!goto_store->Identifier) {
53 free(goto_store);
54 return NULL;
55 }
56 goto_store->Groups = calloc(1, sizeof(BAT_GROUP_T*));
57 if (!goto_store->Groups) {
58 free(goto_store->Identifier);
59 free(goto_store);
60 return NULL;
61 }
62 goto_store->Size = 0;
63 goto_store->Capacity = 1;
64 return goto_store;
65 }
66
67 // Добавление группы в хранилище GoTo
68 void goto_add_group(BAT_GoTo_T* goto_store, BAT_GROUP_T* group) {
69 if (goto_store->Size >= goto_store->Capacity) {
70 size_t new_cap = goto_store->Capacity + ((goto_store->Capacity + 1) / 2);
71 void* new_buf = realloc(goto_store->Groups, sizeof(BAT_GROUP_T*) * new_cap);
72
73 if (!new_buf)
74 return;
75
76 goto_store->Groups = (BAT_GROUP_T**)new_buf;
77 goto_store->Capacity = new_cap;
78 }
79 goto_store->Groups[goto_store->Size++] = group;
80 }
81
82 void bat_add_group(BAT_T * bat, size_t element) {
83 if(bat->Size >= bat->Capacity) {
84 size_t new_cap = bat->Capacity + ((bat->Capacity + 1) / 2);
85 void* new_buf = realloc(bat->Group, sizeof(size_t) * new_cap);
86
87 if(!new_buf)
88 return;
89
90 bat->Group = new_buf;
91 bat->Capacity = new_cap;
92 }
93 bat->Group[bat->Size++] = element;
94 }
95
96 void bat_add_goto(BAT_T* bat, size_t element){
97 if(bat->Size_GT >= bat->Capacity_GT) {
98 size_t new_cap = bat->Capacity_GT + ((bat->Capacity_GT + 1) / 2);
99 void* new_buf = realloc(bat->GoTo, sizeof(size_t) * new_cap);
100
101 if(!new_buf)
102 return;
103
104 bat->GoTo = new_buf;
105 bat->Capacity_GT = new_cap;
106 }
107 bat->GoTo[bat->Size_GT++] = element;
108 }
109
110 void bat_add_token(BAT_GROUP_T* bat, size_t element) {
111 if(bat->Size >= bat->Capacity) {
112 size_t new_cap = bat->Capacity + ((bat->Capacity + 1) / 2);
113 void* new_buf = realloc(bat->Tokens, sizeof(size_t) * new_cap);
114
115 if(!new_buf)
116 return;
117
118 bat->Tokens = new_buf;
119 bat->Capacity = new_cap;
120 }
121 bat->Tokens[bat->Size++] = element;
122 }
123 BAT_TOKEN_T* bat_create_token(BAT_TOKEN_TYPE type, char* value) {
124 BAT_TOKEN_T* token = calloc(1, sizeof(BAT_TOKEN_T));
125 if (token == 0){
126 return NULL;
127 }
128 memset(token, 0, sizeof(BAT_TOKEN_T));
129 token->type = type;
130
131 int len = strlen(value);
132
133 token->value = malloc(len + 1);
134 memset(token->value, 0, len + 1);
135 memcpy(token->value, value, len);
136
137 //bat_fatalerror(0, "Get: '%s'\nIns: '%s'\n",token->value,value);
138 return token;
139 }
140 char* bat_debug_type(BAT_TOKEN_TYPE Type){
141 switch (Type) {
142 case BAT_TOKEN_TYPE_GOTO: return "GOTO";
143 case BAT_TOKEN_TYPE_ECHO: return "ECHO";
144 case BAT_TOKEN_TYPE_IF: return "IF";
145 case BAT_TOKEN_TYPE_SET: return "SET";
146 case BAT_TOKEN_TYPE_TRUE: return "TRUE";
147 case BAT_TOKEN_TYPE_FALSE: return "FALSE";
148 case BAT_TOKEN_TYPE_NOT: return "NOT";
149 case BAT_TOKEN_TYPE_EXIST: return "EXIST";
150 case BAT_TOKEN_TYPE_ISSET: return "ISSET";
151 case BAT_TOKEN_TYPE_STRING: return "STRING";
152 case BAT_TOKEN_TYPE_NUMBER: return "NUMBER";
153 case BAT_TOKEN_TYPE_OPERATOR: return "OPERATOR";
154 case BAT_TOKEN_TYPE_EQUAL: return "EQUAL";
155 case BAT_TOKEN_TYPE_NOT_EQUAL: return "NOT_EQUAL";
156 case BAT_TOKEN_TYPE_GREATER: return "GREATER";
157 case BAT_TOKEN_TYPE_LESS: return "LESS";
158 case BAT_TOKEN_TYPE_LESS_EQUAL: return "LESS_EQUAL";
159 case BAT_TOKEN_TYPE_GREATER_EQUAL: return "GREATER_EQUAL";
160 case BAT_TOKEN_TYPE_EXIT: return "EXIT";
161 case BAT_TOKEN_TYPE_VARIABLE: return "VARIABLE";
162 case BAT_TOKEN_TYPE_ALIAS: return "ALIAS";
163 case BAT_TOKEN_TYPE_START: return "START";
164 case BAT_TOKEN_TYPE_FOR: return "FOR";
165 case BAT_TOKEN_TYPE_WHILE: return "WHILE";
166 case BAT_TOKEN_TYPE_DO: return "DO";
167 case BAT_TOKEN_TYPE_IN: return "IN";
168 case BAT_TOKEN_TYPE_STEP: return "STEP";
169 case BAT_TOKEN_TYPE_BREAK: return "BREAK";
170 case BAT_TOKEN_TYPE_DEBUG: return "DEBUG";
171 case BAT_TOKEN_TYPE_COMMENT: return "COMMENT";
172 case BAT_TOKEN_TYPE_CONTINUE: return "CONTINUE";
173 default: return "UNKNOWN";
174 }
175 }
176 // Функция для определения типа лексемы
177 BAT_TOKEN_TYPE bat_parse_token(char* str) {
178 bat_trim(str);
179 str = bat_toLower(str);
180 bat_str_debug(str);
181
182 if (strcmp(str, "echo") == 0) return BAT_TOKEN_TYPE_ECHO;
183 if (strcmp(str, "if") == 0) return BAT_TOKEN_TYPE_IF;
184 if (strcmp(str, "set") == 0) return BAT_TOKEN_TYPE_SET;
185 if (strcmp(str, "=") == 0) return BAT_TOKEN_TYPE_SET;
186 if (strcmp(str, "goto") == 0) return BAT_TOKEN_TYPE_GOTO;
187 if (strcmp(str, "isset") == 0) return BAT_TOKEN_TYPE_ISSET;
188 if (strcmp(str, "debug") == 0) return BAT_TOKEN_TYPE_DEBUG;
189 if (strcmp(str, "null") == 0) return BAT_TOKEN_TYPE_NOT;
190
191 if (strcmp(str, "rem") == 0) return BAT_TOKEN_TYPE_COMMENT;
192 if (strcmp(str, "::") == 0) return BAT_TOKEN_TYPE_COMMENT;
193
194 if (strcmp(str, "on") == 0 || strcmp(str, "true") == 0 || strcmp(str, "enabled") == 0) return BAT_TOKEN_TYPE_TRUE;
195 if (strcmp(str, "off") == 0 || strcmp(str, "false") == 0 || strcmp(str, "disabled") == 0) return BAT_TOKEN_TYPE_FALSE;
196
197
198 if (strcmp(str, "not") == 0) return BAT_TOKEN_TYPE_NOT;
199 if (strcmp(str, "exist") == 0) return BAT_TOKEN_TYPE_EXIST;
200 if (strcmp(str, "exit") == 0) return BAT_TOKEN_TYPE_EXIT;
201
202
203 if (strcmp(str, "start") == 0) return BAT_TOKEN_TYPE_START;
204 if (strcmp(str, "alias") == 0) return BAT_TOKEN_TYPE_ALIAS;
205
206 if (strcmp(str, "==") == 0) return BAT_TOKEN_TYPE_EQUAL;
207 if (strcmp(str, "!=") == 0) return BAT_TOKEN_TYPE_NOT_EQUAL;
208 if (strcmp(str, ">") == 0) return BAT_TOKEN_TYPE_GREATER;
209 if (strcmp(str, "<") == 0) return BAT_TOKEN_TYPE_LESS;
210 if (strcmp(str, "<=") == 0) return BAT_TOKEN_TYPE_LESS_EQUAL;
211 if (strcmp(str, ">=") == 0) return BAT_TOKEN_TYPE_GREATER_EQUAL;
212
213 if (strcmp(str, "equ") == 0) return BAT_TOKEN_TYPE_EQUAL;
214 if (strcmp(str, "neq") == 0) return BAT_TOKEN_TYPE_NOT_EQUAL;
215 if (strcmp(str, "gtr") == 0) return BAT_TOKEN_TYPE_GREATER;
216 if (strcmp(str, "lss") == 0) return BAT_TOKEN_TYPE_LESS;
217 if (strcmp(str, "leq") == 0) return BAT_TOKEN_TYPE_LESS_EQUAL;
218 if (strcmp(str, "geq") == 0) return BAT_TOKEN_TYPE_GREATER_EQUAL;
219
220 if (strcmp(str, "pause") == 0) return BAT_TOKEN_TYPE_PAUSE;
221
222 if (strcmp(str, "for") == 0) return BAT_TOKEN_TYPE_FOR;
223 if (strcmp(str, "while") == 0) return BAT_TOKEN_TYPE_WHILE;
224 if (strcmp(str, "do") == 0) return BAT_TOKEN_TYPE_DO;
225 if (strcmp(str, "in") == 0) return BAT_TOKEN_TYPE_IN;
226 if (strcmp(str, "step") == 0) return BAT_TOKEN_TYPE_STEP;
227 if (strcmp(str, "break") == 0) return BAT_TOKEN_TYPE_BREAK;
228 if (strcmp(str, "continue") == 0) return BAT_TOKEN_TYPE_CONTINUE;
229 if (strcmp(str, "run") == 0) return BAT_TOKEN_TYPE_RUN;
230
231 if (isdigit(str[0])) {
232 return BAT_TOKEN_TYPE_NUMBER;
233 } else {
234 return BAT_TOKEN_TYPE_UNKNOWN;
235 }
236 }
237 BAT_GROUP_T* bat_parse_line(BAT_T* bat, char* Line){
238 BAT_GROUP_T* group = bat_create_group();
239
240 int c = str_cdsp2(Line, 0x20);
241 char** exp = explode(Line, 0x20);
242
243 int curline = 1;
244
245 int inString = 0;
246
247 char* currentString = NULL;
248 for (int u = 0; u <= c; u++){
249 curline++;
250 bat_debug(" |--- [%u] %s\n", u, exp[u]);
251 bat_trim(exp[u]);
252 size_t len = strlen(exp[u]);
253 if (exp[u][0] == 0x3a && exp[u][1] != 0x3a){
254 currentString = malloc(len * sizeof(char) + 1 );
255 if (currentString == NULL){
256 bat_debug("MALLOC ERROR\n");
257 return group;
258 }
259 memset(currentString, 0, len * sizeof(char) + 1);
260 memcpy(currentString, exp[u] + 1 , len - 1);
261
262 currentString[len - 1] = '\0';
263
264 //BAT_TOKEN_T* xtok = bat_create_token(BAT_TOKEN_TYPE_GOTO_INIT, currentString);
265
266
267
269 bat_debug("Create goto: %s\n", currentString);
270
271 BAT_GoTo_T* gt = goto_create(currentString);
272 if (gt == NULL){
273 bat_debug("ERROR CREATE GOTO\n");
274 free(currentString);
275 return group;
276 }
277 bat_debug("Line: %d\n", curline);
278 gt->Line = curline;
279 bat->CurGoTo = gt;
280 bat_add_goto(bat, (size_t) gt);
281 //BAT_GOTO_T * gt = bat_create_goto(currentString);
282 //bat_add_goto(bat, (size_t) gt);
283 //bat->CurGoTo = bat->Size_GoTo;
284 //bat_debug(" CurGoTo: %d | SizeGoTo:%d\n", bat->CurGoTo, bat->Size_GoTo);
285 free(currentString);
286 return group;
287 } else if (exp[u][0] == '"' && !inString && exp[u][len - 1] == '"'){
288 currentString = malloc(len * sizeof(char) + 1 );
289 memset(currentString, 0, len * sizeof(char) + 1);
290 memcpy(currentString, exp[u] + 1 , len - 2);
291
292 currentString[len - 1] = '\0';
293 //inString = 0;
294 BAT_TOKEN_T* xtok = bat_create_token(BAT_TOKEN_TYPE_STRING, currentString);
295 bat_debug("create token string method 1: '%s'\n", currentString);
296 bat_add_token(group, (size_t) xtok);
297 free(currentString);
298 } else if (exp[u][0] == '"' && !inString) {
299 inString = 1;
300 currentString = malloc(len * sizeof(char));
301 memset(currentString, 0, len * sizeof(char));
302 strcpy(currentString, exp[u] + 1);
303 } else if (inString) {
304 if (exp[u][len - 1] == '"') {
305 currentString = realloc(currentString, (strlen(currentString) + len + 2) * sizeof(char));
306 strcat(currentString, " ");
307 strcat(currentString, exp[u]);
308 currentString[strlen(currentString) - 1] = '\0';
309 inString = 0;
310 BAT_TOKEN_T* xtok = bat_create_token(BAT_TOKEN_TYPE_STRING, currentString);
311
312 bat_debug("create token string method 2: '%s'\n", currentString);
313 bat_add_token(group, (size_t) xtok);
314 free(currentString);
315 } else {
316 currentString = realloc(currentString, (strlen(currentString) + len + 2) * sizeof(char));
317 strcat(currentString, " ");
318 strcat(currentString, exp[u]);
319 }
320 } else {
321 bat_str_debug(exp[u]);
322
323 if (exp[u][0] == '%' && exp[u][len - 1] == '%'){
324 char* temp = malloc(len);
325 memset(temp, 0, len);
326 memcpy(temp, exp[u] + 1, len - 2);
327 bat_debug("create token variable method 1: '%s'\n", temp);
328 BAT_TOKEN_T* xtok = bat_create_token(BAT_TOKEN_TYPE_VARIABLE, temp);
329 bat_add_token(group, (size_t) xtok);
330 } else {
331 BAT_TOKEN_TYPE type = bat_parse_token(exp[u]);
332 bat_debug("[AUTO_DETECT TYPE] Type: %s | Str: '%s'\n", bat_debug_type(type), exp[u]);
333 if (type == BAT_TOKEN_TYPE_COMMENT){
334 return group;
335 }
336 BAT_TOKEN_T* xtok = bat_create_token(type, exp[u]);
337 bat_add_token(group, (size_t) xtok);
338
339 }
340
341 }
342
343
344 }
345 if (inString) {
346 currentString = realloc(currentString, (strlen(currentString) + 1) * sizeof(char));
347 currentString[strlen(currentString) - 2] = '\0';
348 inString = 0;
349
350 bat_debug("create token string method 3: '%s'\n", currentString);
351 BAT_TOKEN_T* xtok = bat_create_token(BAT_TOKEN_TYPE_STRING, currentString);
352 bat_add_token(group, (size_t) xtok);
353
354 free(currentString);
355 }
356 for (int u = 0; u <= c; u++){
357 free(exp[u]);
358 }
359 free(exp);
360
361 return group;
362 }
363 BAT_T* bat_parse_string(char* String){
364 BAT_T* bat = bat_create_session();
365 bat_debug("\n========================\n");
366 bat_debug("%s", String);
367 bat_debug("\n========================\n");
368
369 int cLine = str_cdsp2(String, '\n');
370 char** Line = explode(String, '\n');
371 for (int uL = 0; uL <= cLine; uL++){
372 if (Line[uL] == NULL){
373 continue;
374 }
375 int len = strlen(Line[uL]);
376 bat_debug("[LINE %d | %d] [len: %d] %s\n", uL +1, cLine +1, len, Line[uL]);
377 bat_debug("[0x%x] '%c'\n", Line[uL][0], Line[uL][0]);
378 if (len == 0 || (len == 1 && Line[uL][0] == 0xd)){
379 bat_debug("!RESET TO CurGoTo!\n");
380 bat->CurGoTo = NULL;
381 continue;
382 }
383 BAT_GROUP_T* group = bat_parse_line(bat, Line[uL]);
384 if (group == NULL){
385 bat_debug("!group is NULL! SKIP\n");
386 } else if (bat->CurGoTo != NULL){
387 bat_debug("GOTO group (%s) ins\n", bat->CurGoTo->Identifier);
388 goto_add_group(bat->CurGoTo, group);
389 } else {
390 bat_debug("Classic group ins\n");
391 bat_add_group(bat, (size_t) group);
392 }
393 free(Line[uL]);
394 }
395 free(Line);
396 return bat;
397 }
398
399 void bat_destroy_token(BAT_TOKEN_T** token, int Size){
400 qemu_log("[BAT] [Destroy] [Tokens] Size: %d");
401 for (int x = 0; x < Size; x++){
402 BAT_TOKEN_T* tok = token[x];
403 qemu_log(" |--- [%d | %d] TYPE: %s | Value: '%s'",x + 1, Size, bat_debug_type(tok->type), tok->value);
404 free(tok->value);
405 free(tok);
406 }
407 free(token);
408 }
409 /*
410 * @todo FIX ME
411 */
412 void bat_destroy_group(BAT_GROUP_T** group, int Size){
413 qemu_log("[BAT] [Destroy] [Group] Size: %d", Size);
414 for (int x = 0; x < Size; x++){
415 BAT_GROUP_T* gz = group[x];
416 qemu_log(" |--- [%d | %d]",x + 1, Size);
417 //bat_destroy_token((BAT_TOKEN_T**) gz->Tokens, gz->Size);
418 free(gz);
419 }
420 free(group);
421 }
422
423 void bat_destroy(BAT_T* bat){
424 qemu_log("[BAT] [Destroy]");
425 qemu_log(" |--- Goto (%d)", bat->Size_GT);
426 for (int a = 0; a < bat->Size_GT; a++){
427 BAT_GoTo_T* gt = (BAT_GoTo_T*) bat->GoTo[a];
428 qemu_log(" |--- ID: %s", gt->Identifier);
429 if (gt->Identifier != NULL){
430 free(gt->Identifier);
431 }
432 bat_destroy_group(gt->Groups, gt->Size);
433 free(gt);
434 }
435 free(bat->GoTo);
436 bat_destroy_group((BAT_GROUP_T**) bat->Group, bat->Size);
437 free(bat);
438 }
str_cdsp2
uint32_t str_cdsp2(const char *a_str, char del)
Функция отладки
Definition: explode.c:21
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
strcpy
int strcpy(char *dest, const char *src)
Копирование строк
Definition: string.c:282
strcat
char * strcat(char *destination, const char *source)
Объединение строк
Definition: string.c:463
BAT_GROUP
Definition: eBat.h:77
BAT_TOKEN
Definition: eBat.h:72
BAT
Definition: eBat.h:91
Bat_GOTO
Definition: eBat.h:83