X-Git-Url: https://jxself.org/git/?a=blobdiff_plain;f=src%2Fexpressc.c;h=61a5d5aadb1f3a445a837e85babd72ae457d7fc9;hb=56a5292888e1d46fe3033cd1d5c636051692453f;hp=f8c75530f67eb365f497e48a8980407c1c9e8b8c;hpb=8e63120c630c94c598d4e2d6ba823dac59bce8fa;p=inform.git diff --git a/src/expressc.c b/src/expressc.c index f8c7553..61a5d5a 100644 --- a/src/expressc.c +++ b/src/expressc.c @@ -1,8 +1,8 @@ /* ------------------------------------------------------------------------- */ /* "expressc" : The expression code generator */ /* */ -/* Part of Inform 6.40 */ -/* copyright (c) Graham Nelson 1993 - 2022 */ +/* Part of Inform 6.42 */ +/* copyright (c) Graham Nelson 1993 - 2024 */ /* */ /* Inform is free software: you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ @@ -448,7 +448,7 @@ static void access_memory_z(int oc, assembly_operand AO1, assembly_operand AO2, assembly_operand zero_ao, max_ao, size_ao, en_ao, type_ao, an_ao, index_ao; - int x = 0, y = 0, byte_flag = FALSE, read_flag = FALSE, from_module = FALSE; + int x = 0, y = 0, byte_flag = FALSE, read_flag = FALSE; INITAO(&zero_ao); INITAO(&size_ao); @@ -476,10 +476,12 @@ static void access_memory_z(int oc, assembly_operand AO1, assembly_operand AO2, error("Cannot write to a static array"); } - if (size_ao.value==-1) - from_module=TRUE; + if (size_ao.value==-1) { + /* This case was originally meant for module linking. + It should no longer be possible. */ + compiler_error("Array size cannot be negative"); + } else { - from_module=FALSE; type_ao = zero_ao; type_ao.value = arrays[y].type; if ((!is_systemfile())) @@ -511,7 +513,7 @@ static void access_memory_z(int oc, assembly_operand AO1, assembly_operand AO2, /* If we recognise AO1 as arising textually from a declared array, we can check bounds explicitly. */ - if ((AO1.marker == ARRAY_MV || AO1.marker == STATIC_ARRAY_MV) && (!from_module)) + if ((AO1.marker == ARRAY_MV || AO1.marker == STATIC_ARRAY_MV)) { int passed_label = next_label++, failed_label = next_label++, final_label = next_label++; @@ -1082,10 +1084,16 @@ static assembly_operand check_nonzero_at_runtime_g(assembly_operand AO1, /* Test if inside the "Class" object... */ INITAOTV(&AO3, BYTECONSTANT_OT, GOBJFIELD_PARENT()); assembleg_3(aload_gc, AO, AO3, stack_pointer); - ln = symbol_index("Class", -1); - AO3.value = symbols[ln].value; - AO3.marker = OBJECT_MV; - AO3.type = CONSTANT_OT; + ln = get_symbol_index("Class"); + if (ln < 0) { + error("No 'Class' object found"); + AO3 = zero_operand; + } + else { + AO3.value = symbols[ln].value; + AO3.marker = OBJECT_MV; + AO3.type = CONSTANT_OT; + } assembleg_2_branch(jne_gc, stack_pointer, AO3, passed_label); } @@ -1103,10 +1111,16 @@ static assembly_operand check_nonzero_at_runtime_g(assembly_operand AO1, } else { /* Build the symbol for "Object" */ - ln = symbol_index("Object", -1); - AO2.value = symbols[ln].value; - AO2.marker = OBJECT_MV; - AO2.type = CONSTANT_OT; + ln = get_symbol_index("Object"); + if (ln < 0) { + error("No 'Object' object found"); + AO2 = zero_operand; + } + else { + AO2.value = symbols[ln].value; + AO2.marker = OBJECT_MV; + AO2.type = CONSTANT_OT; + } if (check_sp) { /* Push "Object" */ assembleg_store(AO1, AO2); @@ -2641,11 +2655,48 @@ static void generate_code_from(int n, int void_flag) assembleg_2(random_gc, AO, stack_pointer); assembleg_3(aload_gc, AO2, stack_pointer, Result); } + else if (is_constant_ot(ET[ET[below].right].value.type) && ET[ET[below].right].value.marker == 0) { + /* One argument, value known at compile time */ + int32 arg = ET[ET[below].right].value.value; /* signed */ + if (arg > 0) { + assembly_operand AO; + INITAO(&AO); + AO.value = arg; + set_constant_ot(&AO); + assembleg_2(random_gc, + AO, stack_pointer); + assembleg_3(add_gc, stack_pointer, one_operand, + Result); + } + else { + /* This handles zero or negative */ + assembly_operand AO; + INITAO(&AO); + AO.value = -arg; + set_constant_ot(&AO); + assembleg_1(setrandom_gc, + AO); + assembleg_store(Result, zero_operand); + } + } else { + /* One argument, not known at compile time */ + int ln, ln2; + assembleg_store(temp_var1, ET[ET[below].right].value); + ln = next_label++; + ln2 = next_label++; + assembleg_2_branch(jle_gc, temp_var1, zero_operand, ln); assembleg_2(random_gc, - ET[ET[below].right].value, stack_pointer); + temp_var1, stack_pointer); assembleg_3(add_gc, stack_pointer, one_operand, Result); + assembleg_0_branch(jump_gc, ln2); + assemble_label_no(ln); + assembleg_2(neg_gc, temp_var1, stack_pointer); + assembleg_1(setrandom_gc, + stack_pointer); + assembleg_store(Result, zero_operand); + assemble_label_no(ln2); } break; @@ -2999,7 +3050,7 @@ assembly_operand code_generate(assembly_operand AO, int context, int label) } if (expr_trace_level >= 2) - { printf("Raw parse tree:\n"); show_tree(AO, FALSE); + { printf("Raw parse tree:\n"); show_tree(&AO, FALSE); } if (context == CONDITION_CONTEXT) @@ -3019,7 +3070,7 @@ assembly_operand code_generate(assembly_operand AO, int context, int label) default: printf("* ILLEGAL *"); break; } printf(" context with annotated tree:\n"); - show_tree(AO, TRUE); + show_tree(&AO, TRUE); } generate_code_from(AO.value, (context==VOID_CONTEXT));