void ofc_parse_file_delete(ofc_parse_file_t* file) { if (!file) return; ofc_parse_stmt_list_delete(file->stmt); ofc_sparse_delete(file->source); free(file); }
ofc_parse_file_t* ofc_parse_file(ofc_sparse_t* src) { ofc_parse_debug_t* debug = ofc_parse_debug_create(); if (!debug) return NULL; ofc_parse_stmt_list_t* list = ofc_parse_stmt_list_create(); if (!list) return NULL; if (!ofc_parse_file_include( src, list, debug)) { ofc_parse_debug_print(debug); ofc_parse_debug_delete(debug); ofc_parse_stmt_list_delete(list); return NULL; } ofc_parse_debug_print(debug); ofc_parse_debug_delete(debug); if (!list) return NULL; ofc_parse_file_t* file = (ofc_parse_file_t*)malloc( sizeof(ofc_parse_file_t)); if (!file) { ofc_parse_stmt_list_delete(list); return NULL; } file->source = src; file->stmt = list; return file; }
int main(int argc, const char* argv[]) { global_opts = OFC_GLOBAL_OPTS_DEFAULT; ofc_lang_opts_t lang_opts = OFC_LANG_OPTS_DEFAULT; ofc_file_t* file = NULL; if (!ofc_cliarg_parse(argc, argv, &file, &lang_opts, &global_opts)) return EXIT_FAILURE; ofc_sparse_t* condense = ofc_prep(file); if (!condense) { if (ofc_file_no_errors()) ofc_file_error(file, NULL, "Failed to preprocess source file"); return EXIT_FAILURE; } ofc_file_delete(file); ofc_parse_stmt_list_t* program = ofc_parse_file(condense); if (!program) { if (ofc_file_no_errors()) ofc_file_error(file, NULL, "Failed to parse program"); ofc_sparse_delete(condense); return EXIT_FAILURE; } if (global_opts.parse_print) { ofc_colstr_t* cs = ofc_colstr_create(72, 0); if (!ofc_parse_stmt_list_print(cs, 0, program)) { ofc_file_error(file, NULL, "Failed to print parse tree"); ofc_parse_stmt_list_delete(program); ofc_sparse_delete(condense); return EXIT_FAILURE; } ofc_colstr_fdprint(cs, STDOUT_FILENO); ofc_colstr_delete(cs); } ofc_sema_scope_t* sema = NULL; if (!global_opts.parse_only) { sema = ofc_sema_scope_global( &lang_opts, program); if (!sema) { if (ofc_file_no_errors()) ofc_file_error(file, NULL, "Program failed semantic analysis"); ofc_parse_stmt_list_delete(program); ofc_sparse_delete(condense); return EXIT_FAILURE; } } if (global_opts.sema_print) { ofc_colstr_t* cs = ofc_colstr_create(72, 0); if (!ofc_sema_scope_print(cs, 0, sema)) { ofc_file_error(file, NULL, "Failed to print semantic tree"); ofc_colstr_delete(cs); ofc_sema_scope_delete(sema); ofc_parse_stmt_list_delete(program); ofc_sparse_delete(condense); return EXIT_FAILURE; } ofc_colstr_fdprint(cs, STDOUT_FILENO); ofc_colstr_delete(cs); } ofc_sema_scope_delete(sema); ofc_parse_stmt_list_delete(program); ofc_sparse_delete(condense); return EXIT_SUCCESS; }
static unsigned ofc_parse_stmt__structure( const ofc_sparse_t* src, const char* ptr, ofc_parse_debug_t* debug, ofc_parse_keyword_e keyword, bool slash, ofc_parse_stmt_t* stmt) { unsigned dpos = ofc_parse_debug_position(debug); unsigned i; if (slash) { i = ofc_parse_keyword( src, ptr, debug, keyword); if (i == 0) return 0; stmt->structure.name = OFC_SPARSE_REF_EMPTY; if (keyword == OFC_PARSE_KEYWORD_STRUCTURE) { if (ptr[i] == '/') { i += 1; unsigned len = ofc_parse_name( src, &ptr[i], debug, &stmt->structure.name); if (len == 0) { ofc_parse_debug_rewind(debug, dpos); return 0; } i += len; if (ptr[i++] != '/') { ofc_parse_debug_rewind(debug, dpos); return 0; } } /* TODO - Parse field list. */ } } else { i = ofc_parse_keyword_named( src, ptr, debug, keyword, &stmt->structure.name); if (i == 0) return 0; } unsigned len; if (!ofc_is_end_statement(&ptr[i], &len)) { ofc_parse_debug_rewind(debug, dpos); return 0; } i += len; stmt->structure.block = ofc_parse_stmt_list( src, &ptr[i], debug, &len); if (stmt->structure.block) { if (ofc_parse_stmt_list_contains_error( stmt->structure.block)) { /* Don't rewind cause we want to report the error. */ ofc_parse_stmt_list_delete( stmt->structure.block); return 0; } i += len; } if (slash) { /* TODO - Handle the following? END STRUCTURE /name/ */ len = ofc_parse_keyword_end( src, &ptr[i], debug, keyword, false); if (len == 0) { ofc_sparse_error_ptr(src, &ptr[i], "Invalid statement in %s body", ofc_parse_keyword_name(keyword)); ofc_parse_stmt_list_delete( stmt->structure.block); stmt->type = OFC_PARSE_STMT_ERROR; return i; } } else { len = ofc_parse_keyword_end_named( src, &ptr[i], debug, keyword, true, &stmt->structure.name); if (len == 0) { ofc_parse_stmt_list_delete( stmt->structure.block); return 0; } } i += len; /* Make sure TYPE (struct) doesn't contain TYPE (print) statement. */ if ((keyword == OFC_PARSE_KEYWORD_TYPE) && stmt->structure.block) { unsigned j; for (j = 0; j < stmt->structure.block->count; j++) { ofc_parse_stmt_t* s = stmt->structure.block->stmt[j]; if (!s) continue; if (s->type == OFC_PARSE_STMT_IO_TYPE) { ofc_parse_stmt_list_delete( stmt->structure.block); return 0; } } } return i; }