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 }
uint32_t str_cdsp2(const char *a_str, char del)
Функция отладки
Definition: explode.c:21
size_t strlen(const char *str)
Возращает длину строки
Definition: string.c:88
int strcmp(const char *s1, const char *s2)
Сравнение строк
Definition: string.c:253
void * memset(void *ptr, char value, size_t num)
Заполнение массива указанными символами
Definition: string.c:203
void * memcpy(void *restrict destination, const void *restrict source, size_t n)
Копирование непересекающихся массивов используя SSE.
Definition: string.c:173
int strcpy(char *dest, const char *src)
Копирование строк
Definition: string.c:282
char * strcat(char *destination, const char *source)
Объединение строк
Definition: string.c:463
Definition: eBat.h:77
Definition: eBat.h:72
Definition: eBat.h:91
Definition: eBat.h:83