@@ -147,7 +147,7 @@ static bool var_accessible(parser_state_t* state, thecl_variable_t* var);
147147/* Returns variable of the given name in the specified sub, or NULL if the variable doesn't exist/is out of scope */
148148static thecl_variable_t * var_get (parser_state_t * state, thecl_sub_t * sub, const char * name);
149149/* Returns the stack offset of a specified variable in the specified sub. */
150- static int var_stack (parser_state_t * state, thecl_sub_t * sub, const char * name);
150+ static int var_stack (parser_state_t * state, thecl_sub_t * sub, const char * name, int use_type );
151151/* Returns the type of a specified variable in the specified sub. */
152152static int var_type (parser_state_t * state, thecl_sub_t * sub, const char * name);
153153/* Returns 1 if a variable of a given name exists, and 0 if it doesn't. */
@@ -1148,7 +1148,12 @@ Assignment:
11481148 } else {
11491149 if ($1 ->value.val.f >= 0 .0f ) var = state->current_sub->vars[(int )$1 ->value.val.f / 4 ];
11501150 }
1151- if (var != NULL ) var->is_written = true ;
1151+ if (var != NULL ) {
1152+ var->is_written = true ;
1153+ if ($1 ->value.type != var->type) {
1154+ var->is_punned = true ;
1155+ }
1156+ }
11521157 }
11531158 | Address " +=" ExpressionAny { var_shorthand_assign(state, $1 , $3 , ADDI, ADDF); }
11541159 | Address " -=" ExpressionAny { var_shorthand_assign(state, $1 , $3 , SUBTRACTI, SUBTRACTF); }
@@ -1360,13 +1365,13 @@ Address:
13601365 | ' $' IDENTIFIER {
13611366 $$ = param_new(' S' );
13621367 $$ ->stack = 1 ;
1363- $$ ->value.val.S = var_stack(state, state->current_sub, $2 );
1368+ $$ ->value.val.S = var_stack(state, state->current_sub, $2 , ' S ' );
13641369 free ($2 );
13651370 }
13661371 | ' %' IDENTIFIER {
13671372 $$ = param_new(' f' );
13681373 $$ ->stack = 1 ;
1369- $$ ->value.val.f = var_stack(state, state->current_sub, $2 );
1374+ $$ ->value.val.f = var_stack(state, state->current_sub, $2 , ' f ' );
13701375 free ($2 );
13711376 }
13721377 | IDENTIFIER {
@@ -1379,9 +1384,9 @@ Address:
13791384 $$ = param_new(type);
13801385 $$ ->stack = 1 ;
13811386 if (type == ' S' ) {
1382- $$ ->value.val.S = var_stack(state, state->current_sub, $1 );
1387+ $$ ->value.val.S = var_stack(state, state->current_sub, $1 , ' S ' );
13831388 } else {
1384- $$ ->value.val.f = var_stack(state, state->current_sub, $1 );
1389+ $$ ->value.val.f = var_stack(state, state->current_sub, $1 , ' f ' );
13851390 }
13861391 } else {
13871392 global_definition_t *def = global_get(state, $1 );
@@ -1761,7 +1766,7 @@ static void instr_create_inline_call(
17611766 param_free (param);
17621767 return ;
17631768 }
1764- if (sub->format [i] != param->type ) {
1769+ if (sub->format [i] != ' ? ' && sub-> format [i] != param->type ) {
17651770 yyerror (state, " wrong parameter %i when calling inline sub \" %s\" , expected type: %c\n " , i + 1 , sub->name , sub->format [i]);
17661771 list_for_each (params, param)
17671772 param_free (param);
@@ -1793,9 +1798,9 @@ static void instr_create_inline_call(
17931798
17941799 list_for_each (params, param) { /* It has alredy been verified that param amount is correct. */
17951800 var = sub->vars [i];
1796- if (var->is_written || param->is_expression_param || param_is_system_var (state, param)) {
1801+ if (var->is_written || var-> is_punned || param->is_expression_param || param_is_system_var (state, param)) {
17971802
1798- if (param->is_expression_param && !var->is_written ) {
1803+ if (param->is_expression_param && !var->is_written && !var-> is_punned ) {
17991804 /* Check if the passed expression can be simplified to a literal value. */
18001805 list_node_t * node = state->expressions .tail ;
18011806 expression_t * expr = (expression_t *)node->data ;
@@ -1933,17 +1938,29 @@ static void instr_create_inline_call(
19331938 } else if (param->value .type == ' S' ) {
19341939 if (param->value .val .S < sub->arity *4 && param->value .val .S >= 0 ) {
19351940 /* Parameter. */
1936- param_node->data = param_copy (param_replace[param->value .val .S / 4 ]);
1941+ thecl_param_t * replacement = param_copy (param_replace[param->value .val .S / 4 ]);
1942+ if (replacement->type == ' f' ) {
1943+ replacement->value .type = ' S' ;
1944+ replacement->value .val .S = (int )replacement->value .val .f ;
1945+ }
1946+ param_node->data = replacement;
19371947 param_free (param);
19381948 } else if (param->value .val .S > 0 ) {
19391949 /* Regular stack variable, needs adjusting the offset. */
19401950 param->value .val .S = stack_replace[param->value .val .S / 4 - sub->arity ]->stack ;
19411951 }
19421952 } else if (param->value .type == ' f' ) {
19431953 if (param->value .val .f < (float )(sub->arity *4 ) && param->value .val .f >= 0 .0f ) {
1944- param_node->data = param_copy (param_replace[(int )param->value .val .f / 4 ]);
1954+ /* Parameter. */
1955+ thecl_param_t * replacement = param_copy (param_replace[(int )param->value .val .f / 4 ]);
1956+ if (replacement->type == ' S' ) {
1957+ replacement->value .type = ' f' ;
1958+ replacement->value .val .f = (float )replacement->value .val .S ;
1959+ }
1960+ param_node->data = replacement;
19451961 param_free (param);
19461962 } else if (param->value .val .f > 0 .0f ) {
1963+ /* Regular stack variable, needs adjusting the offset. */
19471964 param->value .val .f = (float )stack_replace[(int )param->value .val .f / 4 - sub->arity ]->stack ;
19481965 }
19491966 }
@@ -2978,6 +2995,7 @@ var_create(
29782995 var->stack = var_get_new_stack (state, sub);
29792996 var->is_written = false ;
29802997 var->is_unused = false ;
2998+ var->is_punned = false ;
29812999 var->scope = state->scope_stack [state->scope_cnt - 1 ];
29823000
29833001 ++sub->var_count ;
@@ -3055,14 +3073,19 @@ static int
30553073var_stack (
30563074 parser_state_t * state,
30573075 thecl_sub_t * sub,
3058- const char * name)
3076+ const char * name,
3077+ int use_type)
30593078{
30603079 seqmap_entry_t * ent = seqmap_find (g_eclmap->gvar_names , name);
30613080 if (ent) return ent->key ;
30623081
30633082 thecl_variable_t * var = var_get (state, sub, name);
3064- if (var != NULL )
3083+ if (var != NULL ) {
3084+ if (var->type != use_type) {
3085+ var->is_punned = true ;
3086+ }
30653087 return var->stack ;
3088+ }
30663089
30673090 yyerror (state, " variable not found: %s" , name);
30683091 return 0 ;
@@ -3133,7 +3156,12 @@ var_shorthand_assign(
31333156 } else {
31343157 if (param->value .val .f >= 0 .0f ) var = state->current_sub ->vars [(int )param->value .val .f / 4 ];
31353158 }
3136- if (var != NULL ) var->is_written = true ;
3159+ if (var != NULL ) {
3160+ var->is_written = true ;
3161+ if (param->value .type != var->type ) {
3162+ var->is_punned = true ;
3163+ }
3164+ }
31373165}
31383166
31393167static void
0 commit comments