Allow multiple arrays to be dimensioned in the same DIM statement
authorNick Downing <nick@ndcode.org>
Mon, 16 May 2022 16:51:26 +0000 (02:51 +1000)
committerNick Downing <nick@ndcode.org>
Mon, 16 May 2022 16:51:26 +0000 (02:51 +1000)
applesoft_basic.t
applesoft_basic.y
test.bas

index 08c89f2..3557e0d 100644 (file)
@@ -74,6 +74,7 @@ class StatementInput: Statement;
 class StatementDim: Statement;
 class StatementPoke: Statement;
 class StatementCall: Statement;
+class DimItem: Node;
 class RValue: Node;
 class RValueOr: RValue;
 class RValueAnd: RValue;
@@ -415,27 +416,28 @@ def execute(self, context):
   self.children[-1].set_val(context, value)
 @method(StatementDim)
 def execute(self, context):
-  dim = [
-    data_types.cint(i.get_float(context)) + 1
-    for i in self.children[1:]
-  ]
-
-  # we don't check for an existing array until here, as it could be
-  # created with the default 11 elements while evaluating dimensions
-  name = self.children[0].str_value
-  if name in context.arrays:
-    raise Exception(
-      f'?REDIM\'D ARRAY ERROR IN {context.line_number():d}'
-    )
+  for i in self.children:
+    dim = [
+      data_types.cint(j.get_float(context)) + 1
+      for j in i.children[1:]
+    ]
+
+    # we don't check for an existing array until here, as it could be
+    # created with the default 11 elements while evaluating dimensions
+    name = i.children[0].str_value
+    if name in context.arrays:
+      raise Exception(
+        f'?REDIM\'D ARRAY ERROR IN {context.line_number():d}'
+      )
 
-  null_value = '' if name[-1] == '$' else 0 if name[-1] == '%' else 0.
-  def create_array(i):
-    return (
-      Variable(null_value)
-    if i >= len(dim) else
-      [create_array(i + 1) for j in range(dim[i])]
-    )
-  context.arrays[name] = create_array(0)
+    null_value = '' if name[-1] == '$' else 0 if name[-1] == '%' else 0.
+    def create_array(j):
+      return (
+        Variable(null_value)
+      if j >= len(dim) else
+        [create_array(j + 1) for k in range(dim[j])]
+      )
+    context.arrays[name] = create_array(0)
 @method(StatementPoke)
 def execute(self, context):
   value0 = self.children[0].get_float()
index f3d99e9..e73477e 100644 (file)
@@ -179,7 +179,7 @@ statement_opt
   | %space (?E{t_def.StatementGet}KEYWORD_GET lvalue)
   | %space (?E{t_def.StatementInput}KEYWORD_INPUT lvalue)
   | %space (?E{t_def.StatementInput}KEYWORD_INPUT STR_LITERAL ';' lvalue)
-  | %space (?E{t_def.StatementDim}KEYWORD_DIM VARIABLE_NAME '(' rvalue_list ')')
+  | %space (?E{t_def.StatementDim}KEYWORD_DIM dim_item_list)
   | %space (?E{t_def.StatementPoke}KEYWORD_POKE lvalue ',' lvalue)
   | %space (?E{t_def.StatementCall}KEYWORD_CALL lvalue)
   ;
@@ -206,6 +206,15 @@ data_item
   | STR_LITERAL
   ;
 
+dim_item_list
+  : dim_item
+  | dim_item_list ',' dim_item
+  ;
+
+dim_item
+  : %space (?E{t_def.DimItem}VARIABLE_NAME '(' rvalue_list ')')
+  ;
+
 rvalue_list
   : rvalue
   | rvalue_list ',' rvalue
index 9fb6d1d..3088010 100644 (file)
--- a/test.bas
+++ b/test.bas
@@ -12,7 +12,7 @@
 110 PRINT "K"K
 120 PRINT STR$(3.14159)
 130 PRINT VAL("3.1515926")
-140 DIM I$(19)
+140 DIM I$(19),AR(5,5)
 150 FOR I=0 TO 19
 160 I$(I)="ELEMENT "+STR$(I)
 170 NEXT I
 200 PRINT J%(4)
 210 PRINT J%(5)
 220 PRINT J%(6)
-230 DIM AR(5,5)
-240 AR(2,2)=3
-250 AR(2,3)=14
-260 PRINT AR(2,1)AR(2,2)"."AR(2,3)
-270 END
+230 AR(2,2)=3
+240 AR(2,3)=14
+250 PRINT AR(2,1)AR(2,2)"."AR(2,3)
+260 END
 1000 I%=I%+1
 1010 RETURN
 2000 DATA 20,30,40.5,50,60