/** * Builds a script buffer and adds its code to the bytecode output buffer and * stores references to its functions and variables in the Compiler object. * After several input buffers of scripts have been built, you can copy the * bytecode to a buffer for execution using compiler_bytecode(). * compiler: an instance of compiler that will receive the bytecode. * input: an input buffer that contains the script code. * inputLen: the number of bytes in length of the input. * returns: true if the compile operation succeeds, and false if it fails. */ bool compiler_build(Compiler * compiler, char * input, size_t inputLen) { assert(compiler != NULL); assert(input != NULL); assert(inputLen > 0); Lexer * lexer = lexer_new(input, inputLen); LexerType type; size_t tokenLen; /* check that lexer alloc didn't fail, and push symtbl for global variables */ if(lexer == NULL || !symtblstk_push(compiler)) { compiler_set_err(compiler, COMPILERERR_ALLOC_FAILED); lexer_free(lexer); return false; } compiler_set_err(compiler, COMPILERERR_SUCCESS); /* get first token */ lexer_next(lexer, &type, &tokenLen); /* handle script imports/"depends" */ if(!parse_dependencies(compiler, lexer)) { return false; } /* compile loop */ while(lexer_current_token(lexer, &type, &tokenLen) != NULL) { parse_function_definitions(compiler, lexer); /* handle errors */ if(lexer_get_err(lexer) != LEXERERR_SUCCESS) { compiler->err = COMPILERERR_LEXER_ERR; compiler->lexerErr = lexer_get_err(lexer); compiler->errorLineNum = lexer_line_num(lexer); } if(compiler->err != COMPILERERR_SUCCESS) { compiler->lexerErr = lexer_get_err(lexer); compiler->errorLineNum = lexer_line_num(lexer); lexer_free(lexer); return false; } } /* we're done here: pop globals symtable */ symtbl_free(symtblstk_pop(compiler)); lexer_free(lexer); return true; }
static int config_parse(struct darray *sections, const char *file, bool always_open) { char *file_data; struct lexer lex; struct base_token token; struct strref section_name; FILE *f; f = os_fopen(file, "rb"); if (always_open && !f) f = os_fopen(file, "w+"); if (!f) return CONFIG_FILENOTFOUND; os_fread_utf8(f, &file_data); fclose(f); if (!file_data) return CONFIG_SUCCESS; lexer_init(&lex); lexer_start_move(&lex, file_data); base_token_clear(&token); while (lexer_getbasetoken(&lex, &token, PARSE_WHITESPACE)) { struct config_section *section; while (token.type == BASETOKEN_WHITESPACE) { if (!lexer_getbasetoken(&lex, &token, PARSE_WHITESPACE)) goto complete; } if (*token.text.array != '[') { while (!is_newline(*token.text.array)) { if (!lexer_getbasetoken(&lex, &token, PARSE_WHITESPACE)) goto complete; } continue; } strref_clear(§ion_name); config_parse_string(&lex, §ion_name, ']'); if (!section_name.len) break; section = darray_push_back_new(sizeof(struct config_section), sections); section->name = bstrdup_n(section_name.array, section_name.len); config_parse_section(section, &lex); } complete: lexer_free(&lex); return CONFIG_SUCCESS; }
static int config_parse_file(struct darray *sections, const char *file, bool always_open) { char *file_data; struct lexer lex; FILE *f; f = os_fopen(file, "rb"); if (always_open && !f) f = os_fopen(file, "w+"); if (!f) return CONFIG_FILENOTFOUND; os_fread_utf8(f, &file_data); fclose(f); if (!file_data) return CONFIG_SUCCESS; lexer_init(&lex); lexer_start_move(&lex, file_data); parse_config_data(sections, &lex); lexer_free(&lex); return CONFIG_SUCCESS; }
void cf_lexer_free(struct cf_lexer *lex) { bfree(lex->file); bfree(lex->reformatted); lexer_free(&lex->base_lexer); da_free(lex->tokens); lex->file = NULL; lex->reformatted = NULL; lex->write_offset = NULL; lex->unexpected_eof = false; }
int config_open_string(config_t **config, const char *str) { struct lexer lex; if (!config) return CONFIG_ERROR; *config = bzalloc(sizeof(struct config_data)); if (!*config) return CONFIG_ERROR; (*config)->file = NULL; lexer_init(&lex); lexer_start(&lex, str); parse_config_data(&(*config)->sections, &lex); lexer_free(&lex); return CONFIG_SUCCESS; }
inline ~BaseLexer() {lexer_free(&lex);}
void cleanup() { lexer_free(); freeobj(literalTable); vm_free(); }