Correctly handle DATA other than STR_LITERAL as unquoted possibly empty strings,...
authorNick Downing <nick@ndcode.org>
Tue, 17 May 2022 05:35:53 +0000 (15:35 +1000)
committerNick Downing <nick@ndcode.org>
Tue, 17 May 2022 05:35:53 +0000 (15:35 +1000)
applesoft_basic.l
applesoft_basic.t
applesoft_basic.y
test.bas

index 216d5bf..8739728 100644 (file)
 %}
 
 %option nodefault
-%start REM
+%start DATA REM
 
 %%
 
+<INITIAL,DATA>{
+  " "
+}
 <INITIAL>{
-  [ ]
   X\ *P\ *L\ *O\ *T/(\ *[A-Z0-9])*(\ *[$%])? {
     return y_tab.KEYWORD_XPLOT
   }
     return y_tab.KEYWORD_DEF
   }
   D\ *A\ *T\ *A/(\ *[A-Z0-9])*(\ *[$%])? {
+    BEGIN(DATA)
     return y_tab.KEYWORD_DATA
   }
   C\ *O\ *S/(\ *[A-Z0-9])*(\ *[$%])? {
   (?E{t_def.FloatLiteral}((?E{t_def.FloatLiteral.Integer}(?E{t_def.Text.Char}[0-9])(\ *(?E{t_def.Text.Char}[0-9]))*)(?E{t_def.FloatLiteral.Fraction}"")|(?E{t_def.FloatLiteral.Integer}((?E{t_def.Text.Char}[0-9])\ *)*)(?E{t_def.FloatLiteral.Fraction}\.(\ *(?E{t_def.Text.Char}[0-9]))*))(?E{t_def.FloatLiteral.Exponent}\ *E(?E{t_def.FloatLiteral.Sign}(\ *(?E{t_def.Text.Char}[+-]))?)\ *(?E{t_def.FloatLiteral.Integer}(?E{t_def.Text.Char}[0-9])(\ *(?E{t_def.Text.Char}[0-9]))*))?) {
     return y_tab.FLOAT_LITERAL
   }
+}
+<INITIAL,DATA>{
   \"(?E{t_def.StrLiteral}[^"\n]*)\" {
     return y_tab.STR_LITERAL
   }
+}
+<INITIAL>{
   \>\ *=|=\ *\> {
     return y_tab.OPERATOR_GE
   }
   \<\ *\>|\>\ *\< {
     return y_tab.OPERATOR_NE
   }
-  . {
+}
+<DATA>{
+  (?E{t_def.DataText}[^\n ",:][^\n,:]*) {
+    return y_tab.DATA_TEXT
+  }
+  :|\n {
+    BEGIN(INITIAL)
     return ord(yytext[0])
   }
-  \n {
-    return ord('\n')
+}
+<INITIAL,DATA>{
+  .|\n {
+    return ord(yytext[0])
   }
 }
 
 <REM>{
   (?E{t_def.RemText}.*) {
-    BEGIN(INITIAL)
     return y_tab.REM_TEXT
   }
+  \n {
+    BEGIN(INITIAL)
+    return ord(yytext[0])
+  }
 }
index d480f31..a6f5f6d 100644 (file)
@@ -81,6 +81,7 @@ class StatementPlot: Statement;
 class StatementHLin: Statement;
 class StatementVLin: Statement;
 class StatementRem: Statement;
+class DataText: Node;
 class DimItem: Node;
 class RemText: Node;
 class RValue: Node;
@@ -355,18 +356,19 @@ def execute(self, context):
   raise NextException()
 @method(StatementRead)
 def execute(self, context):
+  i = 0
   while context.k < len(context.program.children):
     line = context.program.children[context.k]
     while context.l < len(line.children):
       statement = line.children[context.l]
-      if (
-        isinstance(statement, StatementData) and
-          context.m < len(statement.children)
-      ):
-        item = statement.children[context.m]
-        self.children[0].set_val(context, element.to_text(item))
-        context.m += 1
-        return
+      if isinstance(statement, StatementData):
+        while context.m < len(statement.children):
+          item = statement.children[context.m]
+          context.m += 1
+          self.children[i].set_val(context, item.text[0])
+          i += 1
+          if i >= len(self.children):
+            return
       context.l += 1
       context.m = 0
     context.k += 1
index f11927c..df99187 100644 (file)
@@ -23,6 +23,7 @@
 
 %locations
 
+%token DATA_TEXT
 %token KEYWORD_ABS
 %token KEYWORD_AND
 %token KEYWORD_ASC
@@ -168,7 +169,8 @@ statement_opt
   | %space (?E{t_def.StatementFor}KEYWORD_FOR VARIABLE_NAME '=' rvalue KEYWORD_TO rvalue KEYWORD_STEP rvalue)
   | %space (?E{t_def.StatementNext}KEYWORD_NEXT)
   | %space (?E{t_def.StatementNext}KEYWORD_NEXT VARIABLE_NAME)
-  | %space (?E{t_def.StatementRead}KEYWORD_READ lvalue)
+  | %space (?E{t_def.StatementRead}KEYWORD_READ lvalue_list)
+  | %space (?E{t_def.StatementRestore}KEYWORD_RESTORE)
   | %space (?E{t_def.StatementRestore}KEYWORD_RESTORE INT_LITERAL)
   | %space (?E{t_def.StatementData}KEYWORD_DATA data_item_list)
   | %space (?E{t_def.StatementHome}KEYWORD_HOME)
@@ -208,14 +210,19 @@ print_item
   | %space (?E{t_def.RValueTabLParen}KEYWORD_TAB_LPAREN rvalue ')')
   ;
 
+lvalue_list
+  : lvalue
+  | lvalue_list ',' lvalue
+  ;
+
 data_item_list
   : data_item
   | data_item_list ',' data_item
   ;
 
 data_item
-  : INT_LITERAL
-  | FLOAT_LITERAL
+  : (?E{t_def.DataText} %empty)
+  | DATA_TEXT
   | STR_LITERAL
   ;
 
index 707e54c..a35fa2c 100644 (file)
--- a/test.bas
+++ b/test.bas
 230 AR(2,2)=3
 240 AR(2,3)=14
 250 PRINT AR(2,1)AR(2,2)"."AR(2,3)
-260 END
+260 RESTORE 2030
+270 READ G$,O$
+280 PRINT "'"G$"'"
+290 PRINT "'"O$"'"
+300 READ G$,O$
+310 PRINT "'"G$"'"
+320 PRINT "'"O$"'"
+330 FOR L=1 TO 6
+340 READ L$
+350 PRINT "L";L;" '";L$;"'"
+360 NEXT
+370 RESTORE
+380 READ M
+390 PRINT "M"M
+400 END
 1000 REM SUBROUTINE
 1010 I%=I%+1
 1020 RETURN
 2000 REM DATA
 2010 DATA 20,30,40.5,50,60
 2020 DATA 70,80,90,100,110,120
+2030 DATA GOOD , NIGHT 
+2040 DATA "GOOD" , "NIGHT" ,,
+2050 DATA ,,
+2060 DATA FIN