Update to commit af5309356bfa197d7a7ea09101c317f94e9b856b
[inform.git] / src / states.c
index cd3b695a5777486926eec58c57e950c634bc8dc5..3f0e8740a09a85b90266f8d603a2e1a74fc816e4 100644 (file)
@@ -1,9 +1,8 @@
 /* ------------------------------------------------------------------------- */
 /*   "states" :  Statement translator                                        */
 /*                                                                           */
-/* 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      */
@@ -16,7 +15,7 @@
 /* GNU General Public License for more details.                              */
 /*                                                                           */
 /* You should have received a copy of the GNU General Public License         */
-/* along with Inform. If not, see https://gnu.org/licenses/                  */
+/* along with Inform. If not, see https://gnu.org/licenses/                  *
 /*                                                                           */
 /* ------------------------------------------------------------------------- */
 
@@ -184,7 +183,7 @@ static void parse_action(void)
             if (version_number==4)
                 assemblez_4_to(call_vs_zc, AO, AO2, AO3, AO4, temp_var1);
             else
-                assemblez_4(call_zc, AO, AO2, AO3, AO4);
+                assemblez_4_to(call_zc, AO, AO2, AO3, AO4, temp_var1);
             break;
           case 3:
             AO5 = code_generate(AO5, QUANTITY_CONTEXT, -1);
@@ -854,9 +853,9 @@ static void parse_statement_z(int break_label, int continue_label)
                          if (j > ln2) ln2 = j;
                      }
                      put_token_back();
-                     array_entry(ln++,parse_expression(CONSTANT_CONTEXT));
+                     array_entry(ln++, FALSE, parse_expression(CONSTANT_CONTEXT));
                  } while (TRUE);
-                 finish_array(ln);
+                 finish_array(ln, FALSE);
                  if (ln == 0)
                      error("No lines of text given for 'box' display");
 
@@ -1192,6 +1191,14 @@ static void parse_statement_z(int break_label, int continue_label)
 
                  statements.enabled = TRUE;
                  get_next_token();
+
+                 /* An #if directive around the ELSE clause is legal. */
+                 while ((token_type == SEP_TT) && (token_value == HASH_SEP))
+                 {   parse_directive(TRUE);
+                     statements.enabled = TRUE;
+                     get_next_token();
+                 }
+                 
                  if ((token_type == STATEMENT_TT) && (token_value == ELSE_CODE))
                  {   flag = TRUE;
                      if (ln >= 0)
@@ -1590,6 +1597,15 @@ static void parse_statement_z(int break_label, int continue_label)
                  assemblez_2_to(loadw_zc, AO, AO2, AO3);
                  AO2 = code_generate(parse_expression(QUANTITY_CONTEXT),
                      QUANTITY_CONTEXT, -1);
+                 if (is_constant_ot(AO2.type) && AO2.marker == 0) {
+                     if (AO2.value >= 96)
+                     {   error("Z-machine dynamic strings are limited to 96");
+                         AO2.value = 0;
+                     }
+                     if (AO2.value < 0 || AO2.value >= MAX_DYNAMIC_STRINGS) {
+                         memoryerror("MAX_DYNAMIC_STRINGS", MAX_DYNAMIC_STRINGS);
+                     }
+                 }
                  get_next_token();
                  if (token_type == DQ_TT)
                  {   INITAOT(&AO4, LONG_CONSTANT_OT);
@@ -1815,9 +1831,9 @@ static void parse_statement_g(int break_label, int continue_label)
                          if (j > ln2) ln2 = j;
                      }
                      put_token_back();
-                     array_entry(ln++,parse_expression(CONSTANT_CONTEXT));
+                     array_entry(ln++, FALSE, parse_expression(CONSTANT_CONTEXT));
                  } while (TRUE);
-                 finish_array(ln);
+                 finish_array(ln, FALSE);
                  if (ln == 0)
                      error("No lines of text given for 'box' display");
 
@@ -2166,6 +2182,14 @@ static void parse_statement_g(int break_label, int continue_label)
 
                  statements.enabled = TRUE;
                  get_next_token();
+                 
+                 /* An #if directive around the ELSE clause is legal. */
+                 while ((token_type == SEP_TT) && (token_value == HASH_SEP))
+                 {   parse_directive(TRUE);
+                     statements.enabled = TRUE;
+                     get_next_token();
+                 }
+                 
                  if ((token_type == STATEMENT_TT) && (token_value == ELSE_CODE))
                  {   flag = TRUE;
                      if (ln >= 0)
@@ -2514,6 +2538,11 @@ static void parse_statement_g(int break_label, int continue_label)
         case STRING_CODE:
                  AO2 = code_generate(parse_expression(QUANTITY_CONTEXT),
                      QUANTITY_CONTEXT, -1);
+                 if (is_constant_ot(AO2.type) && AO2.marker == 0) {
+                     if (AO2.value < 0 || AO2.value >= MAX_DYNAMIC_STRINGS) {
+                         memoryerror("MAX_DYNAMIC_STRINGS", MAX_DYNAMIC_STRINGS);
+                     }
+                 }
                  get_next_token();
                  if (token_type == DQ_TT)
                  {   INITAOT(&AO4, CONSTANT_OT);