main.c (5902B)
1 #include "token.h" 2 #include "command.h" 3 #include "machine.h" 4 #include "timing.h" 5 #include "tui.h" 6 7 #include <assert.h> 8 #include <string.h> 9 #include <errno.h> 10 11 void print_state( 12 const Machine* machine, 13 const ExecutionResult* execution_result 14 ) { 15 type(set_cursor(1, 2)); 16 printf("gcode interpreter"); 17 type(clear_to_end_of_line); 18 19 type(set_cursor(3, 2)); 20 printf("machine state:"); 21 type(clear_to_end_of_line); 22 23 type(set_cursor(4, 6)); 24 printf( 25 "xyz: [ %4.3f %4.3f %4.3f ] (%s/sec)", 26 machine->x, 27 machine->y, 28 machine->z, 29 UNITS_STRINGS[machine->units] 30 ); 31 type(clear_to_end_of_line); 32 33 type(set_cursor(5, 6)); 34 printf( 35 "feed rate: [ %4.3f ] (%s/min)", 36 machine->feed_rate, 37 UNITS_STRINGS[machine->units] 38 ); 39 type(clear_to_end_of_line); 40 41 type(set_cursor(6, 6)); 42 printf( 43 "positioning_mode: %s", 44 POSITIONING_MODE_STRINGS[machine->positioning_mode] 45 ); 46 type(clear_to_end_of_line); 47 } 48 49 void print_token_error(const Token* token, unsigned int* error_count) { 50 type(set_cursor(8, 2)); 51 printf( 52 "%c [L%d C%d] -- %s\n", 53 token->type, 54 token->line_idx, 55 token->char_idx, 56 TOKEN_ERROR_STRINGS[token->value.error_value] 57 ); 58 type(clear_to_end_of_line); 59 60 type(set_cursor(9, 2)); 61 printf("total error count: %d", *error_count); 62 type(clear_to_end_of_line); 63 64 type(set_cursor(10, 2)); 65 fprintf( 66 stderr, 67 "%c [L%d C%d] -- %s\n", 68 token->type, 69 token->line_idx, 70 token->char_idx, 71 TOKEN_ERROR_STRINGS[token->value.error_value] 72 ); 73 } 74 75 void print_execution_error( 76 const Command* command, 77 const ExecutionResult* result, 78 unsigned int* error_count 79 ) { 80 type(set_cursor(8, 2)); 81 printf( 82 "! [%c%-3d] -- %s", 83 command->code.type, 84 command->code.value, 85 MACHINE_ERROR_STRINGS[result->status] 86 ); 87 type(clear_to_end_of_line); 88 89 type(set_cursor(9, 2)); 90 printf("total error count: %d", *error_count); 91 type(clear_to_end_of_line); 92 93 type(set_cursor(10, 2)); 94 fprintf( 95 stderr, 96 "! [%c%-3d] -- %s\n", 97 command->code.type, 98 command->code.value, 99 MACHINE_ERROR_STRINGS[result->status] 100 ); 101 } 102 103 void save_output( 104 FILE* file, 105 const ExecutionResult* result, 106 const Time* now 107 ) { 108 if (!result->has_data) { 109 return; 110 } 111 fprintf( 112 file, 113 "%10ld (s) %10ld (ns) - [ %4.3f %4.3f %4.3f ]\n", 114 now->time_s, 115 now->time_ns, 116 result->data.x, 117 result->data.y, 118 result->data.z 119 ); 120 } 121 122 int main(int argc, char** argv) { 123 freopen("error.log", "w", stderr); 124 initialize_terminal(); 125 126 if (argc < 2) { 127 fprintf(stderr, "! []: input filename must be provided.\n"); 128 return -1; 129 } 130 131 FILE* file = fopen(argv[1], "r"); 132 if (file == NULL) { 133 fprintf(stderr, "! [%s]: %s\n", argv[1], strerror(errno)); 134 return -1; 135 } 136 137 const char* output_filename = "out"; 138 FILE* output_file = fopen(output_filename, "w"); 139 if (output_file == NULL) { 140 fprintf(stderr, "! [%s]: %s\n", output_filename, strerror(errno)); 141 return -1; 142 } 143 144 Cursor cursor; 145 cursor_init(&cursor, file); 146 147 Command command; 148 command_init(&command); 149 150 Machine machine; 151 machine_init(&machine); 152 153 Token token; 154 CommandStatus command_status = COMMAND_STATUS__NOT_READY; 155 ExecutionResult execution_result = { 156 .status = EXECUTE_STATUS__IDLE, 157 .has_data = false, 158 }; 159 160 unsigned int error_count = 0; 161 162 print_state(&machine, &execution_result); 163 164 Time now; 165 for (;;) { 166 now = time_get(); 167 168 switch (execution_result.status) { 169 case EXECUTE_STATUS__IDLE: { 170 token = parse_token(&cursor); 171 if (token.type == TOKEN_ERROR) { 172 error_count += 1; 173 print_token_error(&token, &error_count); 174 recover_from_error(&cursor, &token); 175 } 176 if (token.type == TOKEN_EOF) { 177 return 0; 178 } 179 180 command_status = command_process_token(&command, &token); 181 if (command_status == COMMAND_STATUS__READY) { 182 execution_result = machine_execute_command( 183 &machine, 184 &command, 185 &now 186 ); 187 save_output(output_file, &execution_result, &now); 188 print_state(&machine, &execution_result); 189 } 190 break; 191 } 192 case EXECUTE_STATUS__IN_PROGRESS: { 193 execution_result = machine_execute_command( 194 &machine, 195 &command, 196 &now 197 ); 198 save_output(output_file, &execution_result, &now); 199 print_state(&machine, &execution_result); 200 break; 201 } 202 case EXECUTE_STATUS__UNRECOGNIZED_COMMAND: 203 case EXECUTE_STATUS__UNRECOGNIZED_MCODE: 204 case EXECUTE_STATUS__UNRECOGNIZED_GCODE: 205 error_count += 1; 206 print_execution_error( 207 &command, 208 &execution_result, 209 &error_count 210 ); 211 case EXECUTE_STATUS__FINISHED: { 212 command_init(&command); 213 command_status = command_process_token(&command, &token); 214 assert(command_status == COMMAND_STATUS__NOT_READY); 215 execution_result.status = EXECUTE_STATUS__IDLE; 216 execution_result.has_data = false; 217 break; 218 } 219 default: 220 return 0; 221 } 222 223 } 224 return 0; 225 } 226