interpreter.h (17696B)
1 #ifndef AWA_INTERPRETER_H_ 2 #define AWA_INTERPRETER_H_ 3 4 #include "common.h" 5 6 static void awa_recursive_bubble_free(awa_bubble_t* bubble) { 7 if (bubble) { 8 for (awa_bubble_t *next, *b = bubble->first; b; b = next) { 9 next = b->next; 10 awa_recursive_bubble_free(b); 11 } 12 free(bubble); 13 } 14 } 15 #define bubble_pop(prog) do { \ 16 awa_bubble_t* tmp = (prog)->bubble_first; \ 17 llist_stack_pop((prog)->bubble_first); \ 18 tmp->next = NULL; \ 19 awa_recursive_bubble_free(tmp); \ 20 } while (0); 21 22 23 static void awa_recursive_print_bubble(awa_bubble_t* bubble) { 24 if (bubble->first) { 25 for (awa_bubble_t* b = bubble->first; b; b = b->next) { 26 awa_recursive_print_bubble(b); 27 } 28 } else { 29 if (bubble->val <= 63) 30 putchar(awascii_table[bubble->val]); 31 } 32 } 33 static void awa_recursive_print_num_bubble(awa_bubble_t* bubble, bool first) { 34 if (bubble->first) { 35 for (awa_bubble_t* b = bubble->first; b; b = b->next) { 36 awa_recursive_print_num_bubble(b, false); 37 } 38 } else { 39 if (!first) putchar(' '); 40 printf("%d", bubble->val); 41 } 42 } 43 44 static void awa_recursive_bubble_deep_copy(awa_bubble_t* to, awa_bubble_t* from) { 45 for (awa_bubble_t* from_inside = from->first; from_inside; from_inside = from_inside->next) { 46 awa_bubble_t* b = calloc(sizeof(*b), 1); 47 awa_recursive_bubble_deep_copy(b, from_inside); 48 llist_queue_push(to->first, to->last, b); 49 } 50 to->val = from->val; 51 } 52 53 enum awa_arithmetic_op { 54 AWA_ARITH_ADD, 55 AWA_ARITH_SUB, 56 AWA_ARITH_MUL, 57 AWA_ARITH_DIV, 58 }; 59 static void awa_bubble_arithmetic_val(awa_bubble_t* new, awa_bubble_t* a, awa_bubble_t* b, enum awa_arithmetic_op op) { 60 switch(op) { 61 case AWA_ARITH_ADD: new->val = a->val + b->val; break; 62 case AWA_ARITH_SUB: new->val = a->val - b->val; break; 63 case AWA_ARITH_MUL: new->val = a->val * b->val; break; 64 case AWA_ARITH_DIV: { 65 awa_bubble_t* res = calloc(sizeof(*res), 1); 66 res->val = a->val / b->val; 67 awa_bubble_t* rem = calloc(sizeof(*rem), 1); 68 rem->val = a->val % b->val; 69 llist_queue_push(new->first, new->last, res); 70 llist_queue_push(new->first, new->last, rem); 71 break; 72 } 73 } 74 } 75 76 static awa_bubble_t* awa_recursive_bubble_arithmetic(awa_bubble_t* a, awa_bubble_t* b, enum awa_arithmetic_op op) { 77 awa_bubble_t* new = calloc(sizeof(*new), 1); 78 if (!a->first && !b->first) { 79 awa_bubble_arithmetic_val(new, a, b, op); 80 } else if (a->first && !b->first) { 81 for (awa_bubble_t* a_inside = a->first; a_inside; a_inside = a_inside->next) { 82 awa_bubble_t* new_inside = awa_recursive_bubble_arithmetic(a_inside, b, op); 83 llist_queue_push(new->first, new->last, new_inside); 84 } 85 } else if (!a->first && b->first) { 86 for (awa_bubble_t* b_inside = b->first; b_inside; b_inside = b_inside->next) { 87 awa_bubble_t* new_inside = awa_recursive_bubble_arithmetic(a, b_inside, op); 88 llist_queue_push(new->first, new->last, new_inside); 89 } 90 } else { 91 for (awa_bubble_t* b_inside = b->first, *a_inside = a->first; b_inside && a_inside; b_inside = b_inside->next, a_inside = a_inside->next) { 92 awa_bubble_t* new_inside = awa_recursive_bubble_arithmetic(a_inside, b_inside, op); 93 llist_queue_push(new->first, new->last, new_inside); 94 } 95 } 96 return new; 97 } 98 99 static void awa_bubble_arithmetic(awa_program_t* program, enum awa_arithmetic_op op) { 100 if (program->bubble_first) { 101 if (program->bubble_first->next) { 102 awa_bubble_t* new = awa_recursive_bubble_arithmetic(program->bubble_first, program->bubble_first->next, op); 103 new->next = program->bubble_first->next->next; 104 105 awa_recursive_bubble_free(program->bubble_first->next); 106 awa_recursive_bubble_free(program->bubble_first); 107 program->bubble_first = new; 108 } 109 } 110 } 111 112 enum awa_cmp_op { 113 AWA_CMP_EQ, 114 AWA_CMP_LESS, 115 AWA_CMP_GRTR, 116 }; 117 static bool awa_bubble_cmp_val(awa_bubble_t* a, awa_bubble_t* b, enum awa_cmp_op op) { 118 switch(op) { 119 case AWA_CMP_EQ: return a->val == b->val; 120 case AWA_CMP_LESS: return a->val < b->val; 121 case AWA_CMP_GRTR: return a->val > b->val; 122 } 123 return false; 124 } 125 static bool awa_recursive_bubble_cmp(awa_bubble_t* a, awa_bubble_t* b, enum awa_cmp_op op) { 126 if (!a->first && !b->first) { 127 if (!awa_bubble_cmp_val(a, b, op)) 128 return false; 129 } else if (a->first && !b->first) { 130 for (awa_bubble_t* a_inside = a->first; a_inside; a_inside = a_inside->next) { 131 if (!awa_recursive_bubble_cmp(a_inside, b, op)) 132 return false; 133 } 134 } else if (!a->first && b->first) { 135 for (awa_bubble_t* b_inside = b->first; b_inside; b_inside = b_inside->next) { 136 if (!awa_recursive_bubble_cmp(a, b_inside, op)) 137 return false; 138 } 139 } else { 140 awa_bubble_t* b_inside = b->first, *a_inside = a->first; 141 for (; b_inside && a_inside; b_inside = b_inside->next, a_inside = a_inside->next) { 142 if (!awa_recursive_bubble_cmp(a_inside, b_inside, op)) 143 return false; 144 } 145 if (a_inside != b_inside) 146 return false; 147 } 148 return true; 149 } 150 static void awa_bubble_cmp(awa_program_t* program, enum awa_cmp_op op) { 151 if (program->bubble_first) { 152 if (program->bubble_first->next) { 153 if (!awa_recursive_bubble_cmp(program->bubble_first, program->bubble_first->next, op)) { 154 program->cmp_skip_next_flag = true; 155 } 156 } 157 } 158 } 159 160 static size_t awa_recursive_get_bubble_count(awa_bubble_t* bubble) { 161 if (bubble->first) { 162 size_t count = 0; 163 for (awa_bubble_t* b = bubble->first; b; b = b->next) 164 count += awa_recursive_get_bubble_count(b); 165 return count; 166 } else { 167 return 1; 168 } 169 } 170 static void awa_recursive_to_bytes(awa_bubble_t* bubble, uint8_t** bytes) { 171 if (bubble->first) { 172 for (awa_bubble_t* b = bubble->first; b; b = b->next) 173 awa_recursive_to_bytes(b, bytes); 174 } else { 175 **bytes = bubble->val; 176 *bytes += 1; 177 } 178 } 179 static size_t awa_get_syscall_param(bool* is_ptr_out, awa_bubble_t* bubble) { 180 if (bubble->first) { 181 size_t count = awa_recursive_get_bubble_count(bubble); 182 uint8_t* ptr = malloc(count); 183 { 184 uint8_t* tmp = ptr; 185 awa_recursive_to_bytes(bubble, &tmp); 186 } 187 *is_ptr_out = true; 188 return (size_t)ptr; 189 } else { 190 *is_ptr_out = false; 191 return bubble->val; 192 } 193 } 194 195 static void awa_program_run(awa_program_t program, bool print_debug, bool step_through, bool enable_syscalls) { 196 for (awatism_t* current_awatism = program.awatism_first; current_awatism; current_awatism = current_awatism->next) { 197 rerun_current_awatism:; 198 if (print_debug) { 199 printf("\t<<<"); 200 printf("("); 201 for (awa_bubble_t* b = program.bubble_first; b; b = b->next) { 202 if (b != program.bubble_first) printf(", "); 203 awa_recursive_debug_print_bubble(b); 204 } 205 printf(")"); 206 printf(" | "); 207 awa_print_awatism(*current_awatism); 208 if (program.cmp_skip_next_flag) 209 printf(" | SKIPPING"); 210 printf(">>>\n"); 211 } 212 if (step_through) 213 getchar(); 214 215 if (program.cmp_skip_next_flag) { 216 program.cmp_skip_next_flag = false; 217 continue; 218 } 219 switch((enum awatisms)current_awatism->opcode) { 220 case AWA_NOP: { 221 // nothing 222 } break; 223 case AWA_PRINT: { 224 if (program.bubble_first) { 225 awa_recursive_print_bubble(program.bubble_first); 226 program.last_print_was_number_flag = false; 227 bubble_pop(&program); 228 } 229 } break; 230 case AWA_PRINT_NUM: { 231 if (program.bubble_first) { 232 awa_recursive_print_num_bubble(program.bubble_first, !program.last_print_was_number_flag); 233 program.last_print_was_number_flag = true; 234 bubble_pop(&program); 235 } 236 } break; 237 case AWA_READ: { 238 printf(">>>AWA INTERPRETER IS REQUESTING INPUT(text): "); 239 char buf[1024] = {0}; 240 fgets(buf, sizeof(buf), stdin); 241 int i = 0; 242 awa_bubble_t* new = calloc(sizeof(*new), 1); 243 for (; buf[i] && buf[i] != '\n'; i++) { 244 uint8_t c = awascii_table_inverse[(uint8_t)buf[i]]; 245 if (c && buf[i] != 'A') { 246 awa_bubble_t* b = calloc(sizeof(*b), 1); 247 b->val = c; 248 llist_queue_push(new->first, new->last, b); 249 } 250 } 251 if (new->first) llist_stack_push(program.bubble_first, new); 252 else free(new); 253 printf(">>>AWA INTERPRETER READ INPUT [%.*s]\n", i, buf); 254 } break; 255 case AWA_READ_NUM: { 256 printf(">>>AWA INTERPRETER IS REQUESTING INPUT(numb): "); 257 char buf[1024] = {0}; 258 fgets(buf, sizeof(buf), stdin); 259 awa_bubble_t* b = calloc(sizeof(*b), 1); 260 sscanf(buf, "%d", &b->val); 261 llist_stack_push(program.bubble_first, b); 262 printf(">>>AWA INTERPRETER READ INPUT [%d]\n", b->val); 263 } break; 264 case AWA_TERMINATE: { 265 goto program_end; 266 } break; 267 case AWA_BLOW: { 268 awa_bubble_t* b = calloc(sizeof(*b), 1); 269 b->val = current_awatism->s8; 270 llist_stack_push(program.bubble_first, b); 271 } break; 272 case AWA_SUBMERGE: { 273 if (program.bubble_first && program.bubble_first->next) { 274 awa_bubble_t* sub = program.bubble_first; 275 int depth = current_awatism->u8; 276 llist_stack_pop(program.bubble_first); 277 278 awa_bubble_t* last = program.bubble_first; 279 int i = 1; 280 for (awa_bubble_t* b = last->next; b && i != depth; b = b->next, i++) { 281 last = b; 282 } 283 sub->next = last->next; 284 last->next = sub; 285 } 286 } break; 287 case AWA_POP: { 288 if (program.bubble_first) { 289 awa_bubble_t* tmp = program.bubble_first; 290 llist_stack_pop(program.bubble_first); 291 if (tmp->first) { 292 while (tmp->first) { 293 if (tmp->first->next == NULL) { 294 llist_stack_push(program.bubble_first, tmp->first); 295 break; 296 } 297 for (awa_bubble_t* b = tmp->first; b; b = b->next) { 298 if (b->next->next == NULL) { 299 llist_stack_push(program.bubble_first, b->next); 300 b->next = NULL; 301 break; 302 } 303 } 304 } 305 } 306 free(tmp); 307 } 308 } break; 309 case AWA_DUPLICATE: { 310 if (program.bubble_first) { 311 awa_bubble_t* b = calloc(sizeof(*b), 1); 312 awa_recursive_bubble_deep_copy(b, program.bubble_first); 313 llist_stack_push(program.bubble_first, b); 314 } 315 } break; 316 case AWA_SURROUND: { 317 if (program.bubble_first && current_awatism->u8) { 318 awa_bubble_t* b = calloc(sizeof(*b), 1); 319 for (int i = 0; i < current_awatism->u8; i++) { 320 awa_bubble_t* b_inside = program.bubble_first; 321 if (!b_inside) break; 322 llist_stack_pop(program.bubble_first); 323 b_inside->next = NULL; 324 llist_queue_push(b->first, b->last, b_inside); 325 } 326 llist_stack_push(program.bubble_first, b); 327 } 328 } break; 329 case AWA_MERGE: { 330 awa_bubble_t* two[2]; 331 if (program.bubble_first) { 332 two[0] = program.bubble_first; 333 if (program.bubble_first->next) { 334 two[1] = program.bubble_first->next; 335 336 if (!two[0]->first && !two[1]->first) { 337 two[0]->val += two[1]->val; 338 two[0]->next = two[1]->next; 339 free(two[1]); 340 } else { 341 awa_bubble_t* new = calloc(sizeof(*new), 1); 342 new->next = two[1]->next; 343 program.bubble_first = new; 344 345 for (int i = 0; i < 2; i++) { 346 if (two[i]->first) { 347 for (awa_bubble_t* next, *b = two[i]->first; b; b = next) { 348 next = b->next; 349 llist_queue_push(new->first, new->last, b); 350 } 351 free(two[i]); 352 } else { 353 llist_queue_push(new->first, new->last, two[i]); 354 } 355 } 356 } 357 } 358 } 359 } break; 360 case AWA_ADD: { 361 awa_bubble_arithmetic(&program, AWA_ARITH_ADD); 362 } break; 363 case AWA_SUBTRACT: { 364 awa_bubble_arithmetic(&program, AWA_ARITH_SUB); 365 } break; 366 case AWA_MULTIPLY: { 367 awa_bubble_arithmetic(&program, AWA_ARITH_MUL); 368 } break; 369 case AWA_DIVIDE: { 370 awa_bubble_arithmetic(&program, AWA_ARITH_DIV); 371 } break; 372 case AWA_COUNT: { 373 if (program.bubble_first) { 374 int count = 0; 375 for (awa_bubble_t* b = program.bubble_first->first; b; b = b->next) { 376 count++; 377 } 378 awa_bubble_t* b = calloc(sizeof(*b), 1); 379 b->val = count; 380 llist_stack_push(program.bubble_first, b); 381 } 382 } break; 383 case AWA_LABEL: { 384 // nothing 385 } break; 386 case AWA_JUMP: { 387 if (program.awalabel_table[current_awatism->u8]) { 388 current_awatism = program.awalabel_table[current_awatism->u8]; 389 goto rerun_current_awatism; 390 } else { 391 awa_debug_printf("interpreter: unable to find label %d\n", current_awatism->u8); 392 } 393 } break; 394 case AWA_EQUAL_TO: { 395 awa_bubble_cmp(&program, AWA_CMP_EQ); 396 } break; 397 case AWA_LESS_THAN: { 398 awa_bubble_cmp(&program, AWA_CMP_LESS); 399 } break; 400 case AWA_GREATER_THAN: { 401 awa_bubble_cmp(&program, AWA_CMP_GRTR); 402 } break; 403 case AWA_SYSCALL: { 404 #ifndef awa_syscall 405 awa_debug_printf("syscalls are not supported on this platform, terminating\n"); 406 goto program_end; 407 #endif 408 if (!enable_syscalls) { 409 awa_debug_printf("syscalls are intentionally disabled!"); 410 goto program_end; 411 } 412 if (program.bubble_first) { 413 int count = 0; 414 for (awa_bubble_t* b = program.bubble_first->first; b; b = b->next) 415 count++; 416 if (count > 0 && count <= 7) { 417 size_t args[6] = {0}; 418 bool is_ptr[6] = {0}; 419 { 420 awa_bubble_t* b = program.bubble_first->first; 421 for (int i = 0; i < count; i++, b = b->next) 422 args[i] = awa_get_syscall_param(&is_ptr[i], b); 423 } 424 425 long val = -1; 426 switch(count) { 427 case 1: val = awa_syscall(current_awatism->u16, args[0]); break; 428 case 2: val = awa_syscall(current_awatism->u16, args[0], args[1]); break; 429 case 3: val = awa_syscall(current_awatism->u16, args[0], args[1], args[2]); break; 430 case 4: val = awa_syscall(current_awatism->u16, args[0], args[1], args[2], args[3]); break; 431 case 5: val = awa_syscall(current_awatism->u16, args[0], args[1], args[2], args[3], args[4]); break; 432 case 6: val = awa_syscall(current_awatism->u16, args[0], args[1], args[2], args[3], args[4], args[5]); break; 433 } 434 435 for (int i = 0; i < count; i++) 436 if (is_ptr[i]) free((void*)args[i]); 437 awa_bubble_t* n = calloc(sizeof(*n), 1); 438 n->val = val; 439 llist_stack_push(program.bubble_first, n); 440 } else { 441 awa_debug_printf("syscall(%d) had an invalid number of arguments %d\n", current_awatism->u16, count); 442 goto program_end; 443 } 444 } 445 } break; 446 case AWA_DOUBLE_POP: { 447 if (program.bubble_first) 448 bubble_pop(&program); 449 } break; 450 default: { 451 awa_debug_printf("interpreter: invalid opcode %d\n", current_awatism->opcode); 452 } break; 453 } 454 } 455 program_end:; 456 while(program.bubble_first) 457 bubble_pop(&program); 458 } 459 460 461 #endif // AWA_INTERPRETER_H_