Update to Inform v6.35
[inform.git] / src / expressc.c
index e6db119c32cd23378932b4eff41b98a60a483847..6651547081a0fb45ffa93c83ac9ff00113ded6b0 100644 (file)
@@ -1,9 +1,8 @@
 /* ------------------------------------------------------------------------- */
 /*   "expressc" :  The expression code generator                             */
 /*                                                                           */
-/* Copyright (c) Graham Nelson 1993 - 2018                                   */
-/*                                                                           */
-/* This file is part of Inform.                                              */
+/*   Part of Inform 6.35                                                     */
+/*   copyright (c) Graham Nelson 1993 - 2021                                 */
 /*                                                                           */
 /* Inform is free software: you can redistribute it and/or modify            */
 /* it under the terms of the GNU General Public License as published by      */
@@ -451,10 +450,12 @@ static void access_memory_z(int oc, assembly_operand AO1, assembly_operand AO2,
         index_ao;
     int x = 0, y = 0, byte_flag = FALSE, read_flag = FALSE, from_module = FALSE;
 
-    if (AO1.marker == ARRAY_MV)
-    {   
-        INITAO(&zero_ao);
+    INITAO(&zero_ao);
+    INITAO(&size_ao);
+    INITAO(&type_ao);
 
+    if (AO1.marker == ARRAY_MV || AO1.marker == STATIC_ARRAY_MV)
+    {   
         if ((oc == loadb_zc) || (oc == storeb_zc)) byte_flag=TRUE;
         else byte_flag = FALSE;
         if ((oc == loadb_zc) || (oc == loadw_zc)) read_flag=TRUE;
@@ -465,10 +466,16 @@ static void access_memory_z(int oc, assembly_operand AO1, assembly_operand AO2,
 
         size_ao = zero_ao; size_ao.value = -1;
         for (x=0; x<no_arrays; x++)
-        {   if (AO1.value == svals[array_symbols[x]])
+        {   if (((AO1.marker == ARRAY_MV) == (!array_locs[x]))
+                && (AO1.value == svals[array_symbols[x]]))
             {   size_ao.value = array_sizes[x]; y=x;
             }
         }
+        
+        if (array_locs[y] && !read_flag) {
+            error("Cannot write to a static array");
+        }
+
         if (size_ao.value==-1) 
             from_module=TRUE;
         else {
@@ -504,7 +511,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) && (!from_module))
+    if ((AO1.marker == ARRAY_MV || AO1.marker == STATIC_ARRAY_MV) && (!from_module))
     {   
         int passed_label = next_label++, failed_label = next_label++,
             final_label = next_label++; 
@@ -816,13 +823,16 @@ static void access_memory_g(int oc, assembly_operand AO1, assembly_operand AO2,
     else 
       read_flag = FALSE;
 
-    if (AO1.marker == ARRAY_MV)
+    INITAO(&zero_ao);
+    INITAO(&size_ao);
+    INITAO(&type_ao);
+    
+    if (AO1.marker == ARRAY_MV || AO1.marker == STATIC_ARRAY_MV)
     {   
-        INITAO(&zero_ao);
-
         size_ao = zero_ao; size_ao.value = -1;
         for (x=0; x<no_arrays; x++)
-        {   if (AO1.value == svals[array_symbols[x]])
+        {   if (((AO1.marker == ARRAY_MV) == (!array_locs[x]))
+                && (AO1.value == svals[array_symbols[x]]))
             {   size_ao.value = array_sizes[x]; y=x;
             }
         }
@@ -830,6 +840,10 @@ static void access_memory_g(int oc, assembly_operand AO1, assembly_operand AO2,
 
         type_ao = zero_ao; type_ao.value = array_types[y];
 
+        if (array_locs[y] && !read_flag) {
+            error("Cannot write to a static array");
+        }
+
         if ((!is_systemfile()))
         {   if (data_len == 1)
             {
@@ -856,7 +870,7 @@ static void access_memory_g(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)
+    if (AO1.marker == ARRAY_MV || AO1.marker == STATIC_ARRAY_MV)
     {   
         /* Calculate the largest permitted array entry + 1
            Here "size_ao.value" = largest permitted entry of its own kind */
@@ -1789,9 +1803,9 @@ static void generate_code_from(int n, int void_flag)
                                  arg_c++, arg_et = ET[arg_et].right)
                             {   if (ET[arg_et].value.type == VARIABLE_OT)
               error("Only constants can be used as possible 'random' results");
-                                array_entry(arg_c, ET[arg_et].value);
+                                array_entry(arg_c, FALSE, ET[arg_et].value);
                             }
-                            finish_array(arg_c);
+                            finish_array(arg_c, FALSE);
 
                             assemblez_1_to(random_zc, AO, temp_var1);
                             assemblez_dec(temp_var1);
@@ -2525,9 +2539,9 @@ static void generate_code_from(int n, int void_flag)
                             {   if (ET[arg_et].value.type == LOCALVAR_OT
                                     || ET[arg_et].value.type == GLOBALVAR_OT)
               error("Only constants can be used as possible 'random' results");
-                                array_entry(arg_c, ET[arg_et].value);
+                                array_entry(arg_c, FALSE, ET[arg_et].value);
                             }
-                            finish_array(arg_c);
+                            finish_array(arg_c, FALSE);
 
                             assembleg_2(random_gc, AO, stack_pointer);
                             assembleg_3(aload_gc, AO2, stack_pointer, Result);