common.h (6342B)
1 #ifndef AWA_COMMON_H_ 2 #define AWA_COMMON_H_ 3 4 #include <stdlib.h> 5 #include <string.h> 6 #include <stdint.h> 7 #include <stdio.h> 8 #include <stdbool.h> 9 #include <ctype.h> 10 #include <errno.h> 11 #include <assert.h> 12 13 static char awascii_table[64] = "AWawJELYHOSIUMjelyhosiumPCNTpcntBDFGRbdfgr0123456789 .,!'()~_/;\n"; 14 static uint8_t awascii_table_inverse[256] = { 15 ['A'] = 0, ['W'] = 1, ['a'] = 2, ['w'] = 3, 16 ['J'] = 4, ['E'] = 5, ['L'] = 6, ['Y'] = 7, 17 ['H'] = 8, ['O'] = 9, ['S'] = 10, ['I'] = 11, ['U'] = 12, ['M'] = 13, 18 ['j'] = 14, ['e'] = 15, ['l'] = 16, ['y'] = 17, 19 ['h'] = 18, ['o'] = 19, ['s'] = 20, ['i'] = 21, ['u'] = 22, ['m'] = 23, 20 ['P'] = 24, ['C'] = 25, ['N'] = 26, ['T'] = 27, 21 ['p'] = 28, ['c'] = 29, ['n'] = 30, ['t'] = 31, 22 ['B'] = 32, ['D'] = 33, ['F'] = 34, ['G'] = 35, ['R'] = 36, 23 ['b'] = 37, ['d'] = 38, ['f'] = 39, ['g'] = 40, ['r'] = 41, 24 ['0'] = 42, ['1'] = 43, ['2'] = 44, ['3'] = 45, ['4'] = 46, ['5'] = 47, ['6'] = 48, ['7'] = 49, ['8'] = 50, ['9'] = 51, 25 [' '] = 52, ['.'] = 53, [','] = 54, ['!'] = 55, ['\''] = 56, ['('] = 57, [')'] = 58, ['~'] = 59, ['_'] = 60, ['/'] = 61, [';'] = 62, ['\n'] = 63, 26 }; 27 28 enum awatisms { 29 AWA_NOP = 0x00, 30 AWA_PRINT = 0x01, 31 AWA_PRINT_NUM = 0x02, 32 AWA_READ = 0x03, 33 AWA_READ_NUM = 0x04, 34 AWA_TERMINATE = 0x1F, 35 36 AWA_BLOW = 0x05, 37 AWA_SUBMERGE = 0x06, 38 AWA_POP = 0x07, 39 AWA_DUPLICATE = 0x08, 40 AWA_SURROUND = 0x09, 41 AWA_MERGE = 0x0A, 42 43 AWA_ADD = 0x0B, 44 AWA_SUBTRACT = 0x0C, 45 AWA_MULTIPLY = 0x0D, 46 AWA_DIVIDE = 0x0E, 47 AWA_COUNT = 0x0F, 48 49 AWA_LABEL = 0x10, 50 AWA_JUMP = 0x11, 51 AWA_EQUAL_TO = 0x12, 52 AWA_LESS_THAN = 0x13, 53 AWA_GREATER_THAN = 0x14, 54 55 AWA_SYSCALL = 0x15, 56 AWA_DOUBLE_POP = 0x16, 57 58 }; 59 #define AWA_OPCODE_MAX 32 60 61 #ifdef __linux 62 #include "sys/syscall.h" 63 #include "unistd.h" 64 #define awa_syscall(...) syscall(__VA_ARGS__) 65 #endif 66 67 static char* awatism_opcode_names[AWA_OPCODE_MAX] = { 68 [AWA_NOP] = "nop", 69 [AWA_PRINT] = "prn", 70 [AWA_PRINT_NUM] = "pr1", 71 [AWA_READ] = "red", 72 [AWA_READ_NUM] = "r3d", 73 [AWA_TERMINATE] = "trm", 74 75 [AWA_BLOW] = "blo", 76 [AWA_SUBMERGE] = "sbm", 77 [AWA_POP] = "pop", 78 [AWA_DUPLICATE] = "dpl", 79 [AWA_SURROUND] = "srn", 80 [AWA_MERGE] = "mrg", 81 82 [AWA_ADD] = "4dd", 83 [AWA_SUBTRACT] = "sub", 84 [AWA_MULTIPLY] = "mul", 85 [AWA_DIVIDE] = "div", 86 [AWA_COUNT] = "cnt", 87 88 [AWA_LABEL] = "lbl", 89 [AWA_JUMP] = "jmp", 90 [AWA_EQUAL_TO] = "eql", 91 [AWA_LESS_THAN] = "lss", 92 [AWA_GREATER_THAN] = "gr8", 93 94 [AWA_SYSCALL] = "sys", 95 [AWA_DOUBLE_POP] = "p0p", 96 }; 97 98 static uint8_t awatism_param_sizes_bits[AWA_OPCODE_MAX] = { 99 [AWA_BLOW] = 8, 100 [AWA_SUBMERGE] = 5, 101 [AWA_SURROUND] = 5, 102 [AWA_LABEL] = 5, 103 [AWA_JUMP] = 5, 104 [AWA_SYSCALL] = 10, 105 }; 106 107 typedef struct awatism awatism_t; 108 struct awatism { 109 uint8_t opcode; 110 union { 111 uint8_t u8; 112 int8_t s8; 113 uint16_t u16; 114 }; 115 116 awatism_t* next; 117 118 int current_pos_bytes; 119 }; 120 121 #define llist_queue_push(f,l,n) ((f)==0) ? (f)=(l)=(n) : ((l)->next=(n), (l)=(n), (n)->next=0) 122 #define llist_queue_pop(f,l) ((f)==(l)) ? ((f)=(l)=0) : ((f)=(f)->next) 123 124 #define llist_stack_push(f,n) ((n)->next=(f), (f)=(n)) 125 #define llist_stack_pop(f) ((f)==0) ? 0 : ((f)=(f->next)) 126 127 #define awa_debug_printf(...) printf(__VA_ARGS__) 128 129 typedef struct awa_bubble awa_bubble_t; 130 struct awa_bubble { 131 awa_bubble_t* next; 132 awa_bubble_t* first; 133 awa_bubble_t* last; 134 int val; 135 }; 136 137 typedef struct { 138 bool failed_parse; 139 140 char* source; 141 142 awatism_t* awatism_first; 143 awatism_t* awatism_last; 144 145 awatism_t* awalabel_table[64]; 146 147 awa_bubble_t* bubble_first; 148 149 bool cmp_skip_next_flag; 150 bool last_print_was_number_flag; 151 } awa_program_t; 152 153 typedef struct { 154 const char* awatalk; 155 int pos; 156 int total_size; 157 } awa_parser_t; 158 159 typedef struct { 160 const char* line_start; 161 int col; 162 int line; 163 int line_len; 164 } awa_line_info_t; 165 166 static awa_line_info_t awa_get_line_and_col(awa_parser_t parser) 167 { 168 awa_line_info_t res = {0}; 169 res.line_start = parser.awatalk; 170 for (;;) { 171 const char* current_newline = strchr(res.line_start == parser.awatalk ? parser.awatalk : res.line_start, '\n'); 172 if (!current_newline) break; 173 if (parser.pos < current_newline - parser.awatalk) break; 174 res.line_start = current_newline + 1; 175 res.line++; 176 } 177 const char* newline_after = strchr(res.line_start, '\n'); 178 if (newline_after) res.line_len = newline_after - res.line_start - 1; 179 else res.line_len = strlen(res.line_start); 180 res.col = parser.pos - (res.line_start - parser.awatalk); 181 return res; 182 } 183 184 static void awa_print_line(awa_line_info_t line) 185 { 186 awa_debug_printf("%.*s\n", line.line_len+1, line.line_start); 187 } 188 189 static void awa_print_awatism(awatism_t awatism) { 190 awa_debug_printf("%s", awatism_opcode_names[awatism.opcode]); 191 switch (awatism.opcode) { 192 case AWA_BLOW: 193 { 194 if (awatism.u8 < 64) { 195 if (awascii_table[awatism.u8] == '\n') 196 awa_debug_printf(" %d [\\n]", (int)awatism.s8); 197 else 198 awa_debug_printf(" %d [%c]", (int)awatism.s8, awascii_table[awatism.s8]); 199 } else { 200 awa_debug_printf(" %d", (int)awatism.s8); 201 } 202 break; 203 } break; 204 case AWA_SUBMERGE: 205 case AWA_SURROUND: 206 case AWA_LABEL: 207 case AWA_JUMP: 208 case AWA_SYSCALL: 209 { 210 awa_debug_printf(" %d", (int)awatism.u8); 211 break; 212 } break; 213 } 214 } 215 216 static void awa_recursive_debug_print_bubble(awa_bubble_t* bubble) { 217 if (bubble->first) { 218 awa_debug_printf("("); 219 for (awa_bubble_t* b = bubble->first; b; b = b->next) { 220 if (b != bubble->first) awa_debug_printf(", "); 221 awa_recursive_debug_print_bubble(b); 222 } 223 awa_debug_printf(")"); 224 } else { 225 awa_debug_printf("%d", bubble->val); 226 } 227 } 228 229 230 #endif // AWA_COMMON_H_