X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=parser.c;h=75014cb23607ab581341a36aaf424ed3d9af1b2b;hb=1ad849d9391c55c85bb51b6a07237aa2185123af;hp=4454085008f5471c0cbf18c72ce2294ae8681cd7;hpb=3e576bd1f3336fb2ece646d0a60da1a8eaa67ecc;p=xonotic%2Fgmqcc.git diff --git a/parser.c b/parser.c index 4454085..75014cb 100644 --- a/parser.c +++ b/parser.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012, 2013, 2014 + * Copyright (C) 2012, 2013, 2014, 2015 * Wolfgang Bumiller * Dale Weiler * @@ -953,6 +953,9 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy) } } (void)check_write_to(ctx, exprs[0]); + /* When we're a vector of part of an entity field we use STOREP */ + if (ast_istype(exprs[0], ast_member) && ast_istype(((ast_member*)exprs[0])->owner, ast_entfield)) + assignop = INSTR_STOREP_F; out = (ast_expression*)ast_store_new(ctx, assignop, exprs[0], exprs[1]); break; case opid3('+','+','P'): @@ -1145,6 +1148,22 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy) out = (ast_expression*)asbinstore; break; + case opid3('l', 'e', 'n'): + if (exprs[0]->vtype != TYPE_STRING && exprs[0]->vtype != TYPE_ARRAY) { + ast_type_to_string(exprs[0], ty1, sizeof(ty1)); + compile_error(ast_ctx(exprs[0]), "invalid type for length operator: %s", ty1); + return false; + } + /* strings must be const, arrays are statically sized */ + if (exprs[0]->vtype == TYPE_STRING && + !(((ast_value*)exprs[0])->hasvalue && ((ast_value*)exprs[0])->cvq == CV_CONST)) + { + compile_error(ast_ctx(exprs[0]), "operand of length operator not a valid constant expression"); + return false; + } + out = fold_op(parser->fold, op, exprs); + break; + case opid2('~', 'P'): if (exprs[0]->vtype != TYPE_FLOAT && exprs[0]->vtype != TYPE_VECTOR) { ast_type_to_string(exprs[0], ty1, sizeof(ty1)); @@ -1634,9 +1653,6 @@ static bool parse_sya_operand(parser_t *parser, shunt *sy, bool with_labels) if (!var) { - char *correct = NULL; - size_t i; - /* * sometimes people use preprocessing predefs without enabling them * i've done this thousands of times already myself. Lets check for @@ -1647,34 +1663,6 @@ static bool parse_sya_operand(parser_t *parser, shunt *sy, bool with_labels) return false; } - /* - * TODO: determine the best score for the identifier: be it - * a variable, a field. - * - * We should also consider adding correction tables for - * other things as well. - */ - if (OPTS_OPTION_BOOL(OPTION_CORRECTION) && strlen(parser_tokval(parser)) <= 16) { - correction_t corr; - correct_init(&corr); - - for (i = 0; i < vec_size(parser->correct_variables); i++) { - correct = correct_str(&corr, parser->correct_variables[i], parser_tokval(parser)); - if (strcmp(correct, parser_tokval(parser))) { - break; - } else { - mem_d(correct); - correct = NULL; - } - } - correct_free(&corr); - - if (correct) { - parseerror(parser, "unexpected identifier: %s (did you mean %s?)", parser_tokval(parser), correct); - mem_d(correct); - return false; - } - } parseerror(parser, "unexpected identifier: %s", parser_tokval(parser)); return false; } @@ -2026,10 +2014,6 @@ static void parser_enterblock(parser_t *parser) vec_push(parser->typedefs, util_htnew(TYPEDEF_HT_SIZE)); vec_push(parser->_blocktypedefs, vec_size(parser->_typedefs)); vec_push(parser->_block_ctx, parser_ctx(parser)); - - /* corrector */ - vec_push(parser->correct_variables, correct_trie_new()); - vec_push(parser->correct_variables_score, NULL); } static bool parser_leaveblock(parser_t *parser) @@ -2043,11 +2027,8 @@ static bool parser_leaveblock(parser_t *parser) } util_htdel(vec_last(parser->variables)); - correct_del(vec_last(parser->correct_variables), vec_last(parser->correct_variables_score)); vec_pop(parser->variables); - vec_pop(parser->correct_variables); - vec_pop(parser->correct_variables_score); if (!vec_size(parser->_blocklocals)) { parseerror(parser, "internal error: parser_leaveblock with no block (2)"); return false; @@ -2082,26 +2063,12 @@ static void parser_addlocal(parser_t *parser, const char *name, ast_expression * { vec_push(parser->_locals, e); util_htset(vec_last(parser->variables), name, (void*)e); - - /* corrector */ - correct_add ( - vec_last(parser->correct_variables), - &vec_last(parser->correct_variables_score), - name - ); } static void parser_addglobal(parser_t *parser, const char *name, ast_expression *e) { vec_push(parser->globals, e); util_htset(parser->htglobals, name, e); - - /* corrector */ - correct_add ( - parser->correct_variables[0], - &parser->correct_variables_score[0], - name - ); } static ast_expression* process_condition(parser_t *parser, ast_expression *cond, bool *_ifnot) @@ -2569,16 +2536,17 @@ static bool parse_for_go(parser_t *parser, ast_block *block, ast_expression **ou initexpr = parse_expression_leave(parser, false, false, false); if (!initexpr) goto onerr; - } - /* move on to condition */ - if (parser->tok != ';') { - parseerror(parser, "expected semicolon after for-loop initializer"); - goto onerr; - } - if (!parser_next(parser)) { - parseerror(parser, "expected for-loop condition"); - goto onerr; + /* move on to condition */ + if (parser->tok != ';') { + parseerror(parser, "expected semicolon after for-loop initializer"); + goto onerr; + } + + if (!parser_next(parser)) { + parseerror(parser, "expected for-loop condition"); + goto onerr; + } } /* parse the condition */ @@ -5490,22 +5458,8 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield return false; } - /* - * add alias to aliases table and to corrector - * so corrections can apply for aliases as well. - */ util_htset(parser->aliases, var->name, find); - /* - * add to corrector so corrections can work - * even for aliases too. - */ - correct_add ( - vec_last(parser->correct_variables), - &vec_last(parser->correct_variables_score), - var->name - ); - /* generate aliases for vector components */ if (isvector) { char *buffer[3]; @@ -5521,26 +5475,6 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield mem_d(buffer[0]); mem_d(buffer[1]); mem_d(buffer[2]); - - /* - * add to corrector so corrections can work - * even for aliases too. - */ - correct_add ( - vec_last(parser->correct_variables), - &vec_last(parser->correct_variables_score), - me[0]->name - ); - correct_add ( - vec_last(parser->correct_variables), - &vec_last(parser->correct_variables_score), - me[1]->name - ); - correct_add ( - vec_last(parser->correct_variables), - &vec_last(parser->correct_variables_score), - me[2]->name - ); } } } @@ -5563,13 +5497,6 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield /* Add it to the local scope */ util_htset(vec_last(parser->variables), var->name, (void*)var); - /* corrector */ - correct_add ( - vec_last(parser->correct_variables), - &vec_last(parser->correct_variables_score), - var->name - ); - /* now rename the global */ ln = strlen(var->name); vec_append(defname, ln, var->name); @@ -5601,13 +5528,6 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield for (i = 0; i < 3; ++i) { util_htset(vec_last(parser->variables), me[i]->name, (void*)(me[i])); - /* corrector */ - correct_add( - vec_last(parser->correct_variables), - &vec_last(parser->correct_variables_score), - me[i]->name - ); - vec_shrinkto(defname, prefix_len); ln = strlen(me[i]->name); vec_append(defname, ln, me[i]->name); @@ -6144,10 +6064,6 @@ parser_t *parser_create() parser->aliases = util_htnew(PARSER_HT_SIZE); - /* corrector */ - vec_push(parser->correct_variables, correct_trie_new()); - vec_push(parser->correct_variables_score, NULL); - empty_ctx.file = ""; empty_ctx.line = 0; empty_ctx.column = 0; @@ -6260,13 +6176,6 @@ static void parser_remove_ast(parser_t *parser) vec_free(parser->_blocklocals); vec_free(parser->_locals); - /* corrector */ - for (i = 0; i < vec_size(parser->correct_variables); ++i) { - correct_del(parser->correct_variables[i], parser->correct_variables_score[i]); - } - vec_free(parser->correct_variables); - vec_free(parser->correct_variables_score); - for (i = 0; i < vec_size(parser->_typedefs); ++i) ast_delete(parser->_typedefs[i]); vec_free(parser->_typedefs);