X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=parser.c;h=0e43f50c526e91daa3303c0623c485a68ab4617c;hb=072bff44e6d574f5f32657875adcbe48fc27cb5b;hp=8c1ba3480c30ab263bb059bdfe871b3e10abe707;hpb=25e86c04eb1b35493c08d17ad260bc74e2effbbb;p=xonotic%2Fgmqcc.git diff --git a/parser.c b/parser.c index 8c1ba34..0e43f50 100644 --- a/parser.c +++ b/parser.c @@ -687,12 +687,44 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy) case opid2('<','<'): case opid2('>','>'): + if (NotSameType(TYPE_FLOAT)) { + compile_error(ctx, "invalid types used in expression: cannot perform shift between types %s and %s", + type_name[exprs[0]->vtype], + type_name[exprs[1]->vtype]); + return false; + } + + if (!(out = fold_op(parser->fold, op, exprs))) { + ast_expression *shift = intrin_func(parser->intrin, (op->id == opid2('<','<')) ? "__builtin_lshift" : "__builtin_rshift"); + ast_call *call = ast_call_new(parser_ctx(parser), shift); + vec_push(call->params, exprs[0]); + vec_push(call->params, exprs[1]); + out = (ast_expression*)call; + } + break; + case opid3('<','<','='): case opid3('>','>','='): - if(!(out = fold_op(parser->fold, op, exprs))) { - compile_error(ast_ctx(exprs[0]), "Not Yet Implemented: bit-shifts"); + if (NotSameType(TYPE_FLOAT)) { + compile_error(ctx, "invalid types used in expression: cannot perform shift operation between types %s and %s", + type_name[exprs[0]->vtype], + type_name[exprs[1]->vtype]); return false; } + + if(!(out = fold_op(parser->fold, op, exprs))) { + ast_expression *shift = intrin_func(parser->intrin, (op->id == opid3('<','<','=')) ? "__builtin_lshift" : "__builtin_rshift"); + ast_call *call = ast_call_new(parser_ctx(parser), shift); + vec_push(call->params, exprs[0]); + vec_push(call->params, exprs[1]); + out = (ast_expression*)ast_store_new( + parser_ctx(parser), + INSTR_STORE_F, + exprs[0], + (ast_expression*)call + ); + } + break; case opid2('|','|'): @@ -1590,7 +1622,7 @@ static bool parse_sya_operand(parser_t *parser, shunt *sy, bool with_labels) */ if (!var) { if ((var = intrin_func(parser->intrin, parser_tokval(parser)))) { - (void)!!!compile_warning( + (void)!compile_warning( parser_ctx(parser), WARN_BUILTINS, "using implicitly defined builtin `__builtin_%s' for `%s'", @@ -5441,6 +5473,7 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield */ char *defname = NULL; size_t prefix_len, ln; + size_t sn, sn_size; ln = strlen(parser->function->name); vec_append(defname, ln, parser->function->name); @@ -5462,6 +5495,24 @@ static bool parse_variable(parser_t *parser, ast_block *localblock, bool nofield /* now rename the global */ ln = strlen(var->name); vec_append(defname, ln, var->name); + /* if a variable of that name already existed, add the + * counter value. + * The counter is incremented either way. + */ + sn_size = vec_size(parser->function->static_names); + for (sn = 0; sn != sn_size; ++sn) { + if (strcmp(parser->function->static_names[sn], var->name) == 0) + break; + } + if (sn != sn_size) { + char *num = NULL; + int len = util_asprintf(&num, "#%u", parser->function->static_count); + vec_append(defname, len, num); + mem_d(num); + } + else + vec_push(parser->function->static_names, util_strdup(var->name)); + parser->function->static_count++; ast_value_set_name(var, defname); /* push it to the to-be-generated globals */ @@ -5712,17 +5763,18 @@ skipvar: if (!cexp) break; - if (!localblock) { + if (!localblock || is_static) { cval = (ast_value*)cexp; if (cval != parser->nil && (!ast_istype(cval, ast_value) || ((!cval->hasvalue || cval->cvq != CV_CONST) && !cval->isfield)) ) { - parseerror(parser, "cannot initialize a global constant variable with a non-constant expression"); + parseerror(parser, "initializer is non constant"); } else { - if (!OPTS_FLAG(INITIALIZED_NONCONSTANTS) && + if (!is_static && + !OPTS_FLAG(INITIALIZED_NONCONSTANTS) && qualifier != CV_VAR) { var->cvq = CV_CONST;