Bulk add statements and functions in token order (reorder those already there)
authorNick Downing <nick@ndcode.org>
Tue, 17 May 2022 12:26:40 +0000 (22:26 +1000)
committerNick Downing <nick@ndcode.org>
Tue, 17 May 2022 13:38:07 +0000 (23:38 +1000)
apple_io.py
applesoft_basic.t
applesoft_basic.y

index f6e3b6d..66d28fa 100755 (executable)
@@ -276,7 +276,7 @@ def text():
 def gr():
   pass
 
-def color():
+def color(n):
   pass
 
 def plot(x, y):
index e0b6666..d7e58ca 100644 (file)
@@ -49,66 +49,124 @@ class VariableName: Text;
 class Program: Node;
 class Line: Node;
 class Statement: Node;
-class StatementLet: Statement;
-class StatementPrint: Statement {
-  bool semicolon;
-};
-class StatementGoto: Statement;
-class StatementIf: Statement;
 class StatementEnd: Statement;
-class StatementGosub: Statement;
-class StatementReturn: Statement;
 class StatementFor: Statement;
 class StatementNext: Statement;
-class StatementRead: Statement;
-class StatementRestore: Statement;
 class StatementData: Statement;
-class StatementHome: Statement;
-class StatementNormal: Statement;
-class StatementInverse: Statement;
-class StatementFlash: Statement;
-class StatementHTab: Statement;
-class StatementVTab: Statement;
-class StatementGet: Statement;
 class StatementInput: Statement;
+class StatementDel: Statement;
 class StatementDim: Statement;
-class StatementPoke: Statement;
-class StatementCall: Statement;
-class StatementText: Statement;
+class StatementRead: Statement;
 class StatementGr: Statement;
-class StatementColorEqual: Statement;
+class StatementText: Statement;
+class StatementPrHash: Statement;
+class StatementInHash: Statement;
+class StatementCall: Statement;
 class StatementPlot: Statement;
 class StatementHLin: Statement;
 class StatementVLin: Statement;
+class StatementHGR2: Statement;
+class StatementHGR: Statement;
+class StatementHColorEqual: Statement;
+class StatementHPlot: Statement;
+class StatementDraw: Statement;
+class StatementXDraw: Statement;
+class StatementHTab: Statement;
+class StatementHome: Statement;
+class StatementRotEqual: Statement;
+class StatementScaleEqual: Statement;
+class StatementShLoad: Statement;
+class StatementTrace: Statement;
+class StatementNoTrace: Statement;
+class StatementNormal: Statement;
+class StatementInverse: Statement;
+class StatementFlash: Statement;
+class StatementColorEqual: Statement;
+class StatementPop: Statement;
+class StatementVTab: Statement;
+class StatementHimemColon: Statement;
+class StatementLomemColon: Statement;
+class StatementOnErr: Statement;
+class StatementResume: Statement;
+class StatementRecall: Statement;
+class StatementStore: Statement;
+class StatementSpeedEqual: Statement;
+class StatementLet: Statement;
+class StatementGoto: Statement;
+class StatementRun: Statement;
+class StatementIf: Statement;
+class StatementRestore: Statement;
+class StatementAmpersand: Statement;
+class StatementGosub: Statement;
+class StatementReturn: Statement;
 class StatementRem: Statement;
+class StatementStop: Statement;
+class StatementOnGoto: Statement;
+class StatementOnGosub: Statement;
+class StatementWait: Statement;
+class StatementLoad: Statement;
+class StatementSave: Statement;
+class StatementDef: Statement;
+class StatementPoke: Statement;
+class StatementPrint: Statement {
+  bool semicolon;
+};
+class StatementCont: Statement;
+class StatementList: Statement;
+class StatementClear: Statement;
+class StatementGet: Statement;
+class StatementNew: Statement;
 class DataText: Node;
 class DimItem: Node;
 class RemText: Node;
 class RValue: Node;
-class RValueOr: RValue;
-class RValueAnd: RValue;
-class RValueLT: RValue;
-class RValueEqual: RValue;
-class RValueGT: RValue;
-class RValueGE: RValue;
-class RValueLE: RValue;
-class RValueNE: RValue;
+class RValueStrLiteral: RValue;
+class RValueFloatLiteral: RValue;
+class RValueIntLiteral: RValue;
+class RValueTabLParen: RValue;
+class RValueSpcLParen: RValue;
+class RValueNot: RValue;
+class RValueSign: RValue {
+  int sign;
+};
 class RValueAdd: RValue;
 class RValueSubtract: RValue;
 class RValueMultiply: RValue;
 class RValueDivide: RValue;
 class RValuePower: RValue;
-class RValueSign: RValue {
-  int sign;
-};
-class RValueNot: RValue;
-class RValueIntLiteral: RValue;
-class RValueFloatLiteral: RValue;
-class RValueStrLiteral: RValue;
+class RValueAnd: RValue;
+class RValueOr: RValue;
+class RValueGT: RValue;
+class RValueEqual: RValue;
+class RValueLT: RValue;
+class RValueGE: RValue;
+class RValueLE: RValue;
+class RValueNE: RValue;
+class RValueSgn: RValue;
+class RValueInt: RValue;
+class RValueAbs: RValue;
+class RValueUsr: RValue;
+class RValueFre: RValue;
+class RValueScrnLParen: RValue;
+class RValuePdl: RValue;
+class RValuePos: RValue;
+class RValueSqr: RValue;
+class RValueRnd: RValue;
+class RValueLog: RValue;
+class RValueExp: RValue;
+class RValueCos: RValue;
+class RValueSin: RValue;
+class RValueTan: RValue;
+class RValueAtn: RValue;
+class RValuePeek: RValue;
+class RValueLen: RValue;
 class RValueStrDollar: RValue;
 class RValueVal: RValue;
-class RValuePeek: RValue;
-class RValueTabLParen: RValue;
+class RValueAsc: RValue;
+class RValueChrDollar: RValue;
+class RValueLeftDollar: RValue;
+class RValueRightDollar: RValue;
+class RValueMidDollar: RValue;
 class LValue: RValue;
 class LValueVariable: LValue;
 class LValueArray: LValue;
@@ -260,51 +318,9 @@ del post_process
 @method(Statement)
 def execute(self, context):
   raise NotImplementedError()
-@method(StatementLet)
-def execute(self, context):
-  value = self.children[1].get(context)
-  self.children[0].set(context, value)
-@method(StatementPrint)
-def execute(self, context):
-  for i in self.children:
-    value = i.get(context)
-    if isinstance(value, float):
-      value = data_types.str_dollar(value)
-    apple_io._print(value)
-  if not self.semicolon:
-    apple_io._print('\r')
-@method(StatementGoto)
-def execute(self, context):
-  context.i = context.find_line(self.children[0].int_value)
-  context.j = 1
-@method(StatementIf)
-def execute(self, context):
-  value = self.children[0].get(context)
-  if value == '' or value == 0.:
-    context.i += 1
-    context.j = 1
 @method(StatementEnd)
 def execute(self, context):
   raise EndException()
-@method(StatementGosub)
-def execute(self, context):
-  i = context.i
-  j = context.j
-  context.i = context.find_line(self.children[0].int_value)
-  context.j = 1
-  try:
-    context.execute()
-  except ReturnException:
-    pass
-  except NextException:
-    raise Exception(
-      f'?NEXT WITHOUT FOR ERROR IN {context.line_number():d}'
-    )
-  context.i = i
-  context.j = j
-@method(StatementReturn)
-def execute(self, context):
-  raise ReturnException()
 @method(StatementFor)
 def execute(self, context):
   name = self.children[0].str_value
@@ -331,7 +347,7 @@ def execute(self, context):
       context.execute()
     except NextException:
       pass
-  
+
     assert context.i < len(context.program.children)
     line = context.program.children[context.i]
     assert context.j > 1 and context.j <= len(line.children)
@@ -344,7 +360,7 @@ def execute(self, context):
       raise Exception(
         f'?NEXT WITHOUT FOR ERROR IN {context.line_number():d}'
       )
-  
+
     variable.value += step
     if variable.value > end:
       break
@@ -354,68 +370,9 @@ def execute(self, context):
 @method(StatementNext)
 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):
-        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
-    context.l = 1
-    assert context.m == 0
-  raise Exception(
-    f'?OUT OF DATA ERROR IN {context.line_number():d}'
-  )
-
-@method(StatementRestore)
-def execute(self, context):
-  context.k = (
-    context.find_line(self.children[0].int_value)
-  if len(self.children) >= 1 else
-    0
-  )
-  context.l = 1
-  context.m = 0
 @method(StatementData)
 def execute(self, context):
   pass
-@method(StatementHome)
-def execute(self, context):
-  apple_io.home()
-@method(StatementNormal)
-def execute(self, context):
-  apple_io.normal()
-@method(StatementInverse)
-def execute(self, context):
-  apple_io.inverse()
-@method(StatementFlash)
-def execute(self, context):
-  apple_io.flash()
-@method(StatementHTab)
-def execute(self, context):
-  value = self.children[0].get_float(context)
-  apple_io.htab(data_types.cint(value))
-@method(StatementVTab)
-def execute(self, context):
-  value = self.children[0].get_float(context)
-  apple_io.vtab(data_types.cint(value))
-@method(StatementGet)
-def execute(self, context):
-  value = apple_io.get()
-  # note: if the lvalue isn't a string then we will print a type
-  # mismatch error, whereas applesoft would print a syntax error
-  self.children[0].set(context, value)
 @method(StatementInput)
 def execute(self, context):
   apple_io._print(
@@ -425,6 +382,9 @@ def execute(self, context):
   )
   value = apple_io.input()
   self.children[-1].set_val(context, value)
+@method(StatementDel)
+def execute(self, context):
+  assert False
 @method(StatementDim)
 def execute(self, context):
   for i in self.children:
@@ -449,25 +409,45 @@ def execute(self, context):
         [create_array(j + 1) for k in range(dim[j])]
       )
     context.arrays[name] = create_array(0)
-@method(StatementPoke)
+@method(StatementRead)
 def execute(self, context):
-  value0 = self.children[0].get_float()
-  value1 = self.children[1].get_float()
-  apple_io.poke(data_types.cint(value0), data_types.cint(value1))
-@method(StatementCall)
+  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):
+        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
+    context.l = 1
+    assert context.m == 0
+  raise Exception(
+    f'?OUT OF DATA ERROR IN {context.line_number():d}'
+  )
+@method(StatementGr)
 def execute(self, context):
-  value = self.children[0].get_float()
-  apple_io.call(data_types.cint(value))
+  apple_io.gr()
 @method(StatementText)
 def execute(self, context):
   apple_io.text()
-@method(StatementGr)
+@method(StatementPrHash)
 def execute(self, context):
-  apple_io.gr()
-@method(StatementColorEqual)
+  assert False
+@method(StatementInHash)
+def execute(self, context):
+  assert False
+@method(StatementCall)
 def execute(self, context):
   value = self.children[0].get_float()
-  apple_io.color(data_types.cint(value))
+  apple_io.call(data_types.cint(value))
 @method(StatementPlot)
 def execute(self, context):
   value0 = self.children[0].get_float()
@@ -493,25 +473,261 @@ def execute(self, context):
     data_types.cint(value1),
     data_types.cint(value2)
   )
+@method(StatementHGR2)
+def execute(self, context):
+  assert False
+@method(StatementHGR)
+def execute(self, context):
+  assert False
+@method(StatementHColorEqual)
+def execute(self, context):
+  assert False
+@method(StatementHPlot)
+def execute(self, context):
+  assert False
+@method(StatementDraw)
+def execute(self, context):
+  assert False
+@method(StatementXDraw)
+def execute(self, context):
+  assert False
+@method(StatementHTab)
+def execute(self, context):
+  value = self.children[0].get_float(context)
+  apple_io.htab(data_types.cint(value))
+@method(StatementHome)
+def execute(self, context):
+  apple_io.home()
+@method(StatementRotEqual)
+def execute(self, context):
+  assert False
+@method(StatementScaleEqual)
+def execute(self, context):
+  assert False
+@method(StatementShLoad)
+def execute(self, context):
+  assert False
+@method(StatementTrace)
+def execute(self, context):
+  assert False
+@method(StatementNoTrace)
+def execute(self, context):
+  assert False
+@method(StatementNormal)
+def execute(self, context):
+  apple_io.normal()
+@method(StatementInverse)
+def execute(self, context):
+  apple_io.inverse()
+@method(StatementFlash)
+def execute(self, context):
+  apple_io.flash()
+@method(StatementColorEqual)
+def execute(self, context):
+  value = self.children[0].get_float()
+  apple_io.color(data_types.cint(value))
+@method(StatementPop)
+def execute(self, context):
+  assert False
+@method(StatementVTab)
+def execute(self, context):
+  value = self.children[0].get_float(context)
+  apple_io.vtab(data_types.cint(value))
+@method(StatementHimemColon)
+def execute(self, context):
+  assert False
+@method(StatementLomemColon)
+def execute(self, context):
+  assert False
+@method(StatementOnErr)
+def execute(self, context):
+  assert False
+@method(StatementResume)
+def execute(self, context):
+  assert False
+@method(StatementRecall)
+def execute(self, context):
+  assert False
+@method(StatementStore)
+def execute(self, context):
+  assert False
+@method(StatementSpeedEqual)
+def execute(self, context):
+  assert False
+@method(StatementLet)
+def execute(self, context):
+  value = self.children[1].get(context)
+  self.children[0].set(context, value)
+@method(StatementGoto)
+def execute(self, context):
+  context.i = context.find_line(self.children[0].int_value)
+  context.j = 1
+@method(StatementRun)
+def execute(self, context):
+  assert False
+@method(StatementIf)
+def execute(self, context):
+  value = self.children[0].get(context)
+  if value == '' or value == 0.:
+    context.i += 1
+    context.j = 1
+@method(StatementRestore)
+def execute(self, context):
+  context.k = (
+    context.find_line(self.children[0].int_value)
+  if len(self.children) >= 1 else
+    0
+  )
+  context.l = 1
+  context.m = 0
+@method(StatementAmpersand)
+def execute(self, context):
+  assert False
+@method(StatementGosub)
+def execute(self, context):
+  i = context.i
+  j = context.j
+  context.i = context.find_line(self.children[0].int_value)
+  context.j = 1
+  try:
+    context.execute()
+  except ReturnException:
+    pass
+  except NextException:
+    raise Exception(
+      f'?NEXT WITHOUT FOR ERROR IN {context.line_number():d}'
+    )
+  context.i = i
+  context.j = j
+@method(StatementReturn)
+def execute(self, context):
+  raise ReturnException()
 @method(StatementRem)
 def execute(self, context):
-  pass 
+  pass
+@method(StatementStop)
+def execute(self, context):
+  assert False
+@method(StatementOnGoto)
+def execute(self, context):
+  assert False
+@method(StatementOnGosub)
+def execute(self, context):
+  assert False
+@method(StatementWait)
+def execute(self, context):
+  assert False
+@method(StatementLoad)
+def execute(self, context):
+  assert False
+@method(StatementSave)
+def execute(self, context):
+  assert False
+@method(StatementDef)
+def execute(self, context):
+  assert False
+@method(StatementPoke)
+def execute(self, context):
+  value0 = self.children[0].get_float()
+  value1 = self.children[1].get_float()
+  apple_io.poke(data_types.cint(value0), data_types.cint(value1))
+@method(StatementPrint)
+def execute(self, context):
+  for i in self.children:
+    value = i.get(context)
+    if isinstance(value, float):
+      value = data_types.str_dollar(value)
+    apple_io._print(value)
+  if not self.semicolon:
+    apple_io._print('\r')
+@method(StatementCont)
+def execute(self, context):
+  assert False
+@method(StatementList)
+def execute(self, context):
+  assert False
+@method(StatementClear)
+def execute(self, context):
+  assert False
+@method(StatementGet)
+def execute(self, context):
+  value = apple_io.get()
+  # note: if the lvalue isn't a string then we will print a type
+  # mismatch error, whereas applesoft would print a syntax error
+  self.children[0].set(context, value)
+@method(StatementNew)
+def execute(self, context):
+  assert False
 del execute
 
 @method(RValue)
 def get(self, context):
   raise NotImplementedError()
-@method(RValueOr)
+@method(RValueStrLiteral)
+def get(self, context):
+  return self.children[0].text[0]
+@method(RValueFloatLiteral)
+def get(self, context):
+  return self.children[0].float_value
+@method(RValueIntLiteral)
+def get(self, context):
+  return float(self.children[0].int_value)
+@method(RValueTabLParen)
+def get(self, context):
+  value = self.children[0].get_float(context)
+  return apple_io.tab(data_types.cint(value))
+@method(RValueSpcLParen)
+def get(self, context):
+  value = self.children[0].get(context)
+  assert False
+@method(RValueNot)
+def get(self, context):
+  value = self.children[0].get_float(context)
+  return float(value == 0.)
+@method(RValueSign)
+def get(self, context):
+  value = self.children[0].get_float(context)
+  return self.sign * value
+@method(RValueAdd)
+def get(self, context):
+  value0 = self.children[0].get(context)
+  value1 = (
+    self.children[1].get_float(context)
+  if isinstance(value0, float) else
+    self.children[1].get_str(context)
+  )
+  return value0 + value1
+@method(RValueSubtract)
 def get(self, context):
   value0 = self.children[0].get_float(context)
   value1 = self.children[1].get_float(context)
-  return float(value0 != 0. or value1 != 0.)
+  return value0 - value1
+@method(RValueMultiply)
+def get(self, context):
+  value0 = self.children[0].get_float(context)
+  value1 = self.children[1].get_float(context)
+  return value0 * value1
+@method(RValueDivide)
+def get(self, context):
+  value0 = self.children[0].get_float(context)
+  value1 = self.children[1].get_float(context)
+  return value0 / value1
+@method(RValuePower)
+def get(self, context):
+  value0 = self.children[0].get_float(context)
+  value1 = self.children[1].get_float(context)
+  return value0 ** value1
 @method(RValueAnd)
 def get(self, context):
   value0 = self.children[0].get_float(context)
   value1 = self.children[1].get_float(context)
   return float(value0 != 0. and value1 != 0.)
-@method(RValueLT)
+@method(RValueOr)
+def get(self, context):
+  value0 = self.children[0].get_float(context)
+  value1 = self.children[1].get_float(context)
+  return float(value0 != 0. or value1 != 0.)
+@method(RValueGT)
 def get(self, context):
   value0 = self.children[0].get(context)
   value1 = (
@@ -519,7 +735,7 @@ def get(self, context):
   if isinstance(value0, float) else
     self.children[1].get_str(context)
   )
-  return float(value0 < value1)
+  return float(value0 > value1)
 @method(RValueEqual)
 def get(self, context):
   value0 = self.children[0].get(context)
@@ -529,7 +745,7 @@ def get(self, context):
     self.children[1].get_str(context)
   )
   return float(value0 == value1)
-@method(RValueGT)
+@method(RValueLT)
 def get(self, context):
   value0 = self.children[0].get(context)
   value1 = (
@@ -537,7 +753,7 @@ def get(self, context):
   if isinstance(value0, float) else
     self.children[1].get_str(context)
   )
-  return float(value0 > value1)
+  return float(value0 < value1)
 @method(RValueGE)
 def get(self, context):
   value0 = self.children[0].get(context)
@@ -565,52 +781,78 @@ def get(self, context):
     self.children[1].get_str(context)
   )
   return float(value0 != value1)
-@method(RValueAdd)
+@method(RValueSgn)
 def get(self, context):
-  value0 = self.children[0].get(context)
-  value1 = (
-    self.children[1].get_float(context)
-  if isinstance(value0, float) else
-    self.children[1].get_str(context)
-  )
-  return value0 + value1
-@method(RValueSubtract)
+  value = self.children[0].get(context)
+  assert False
+@method(RValueInt)
 def get(self, context):
-  value0 = self.children[0].get_float(context)
-  value1 = self.children[1].get_float(context)
-  return value0 - value1
-@method(RValueMultiply)
+  value = self.children[0].get(context)
+  assert False
+@method(RValueAbs)
 def get(self, context):
-  value0 = self.children[0].get_float(context)
-  value1 = self.children[1].get_float(context)
-  return value0 * value1
-@method(RValueDivide)
+  value = self.children[0].get(context)
+  assert False
+@method(RValueUsr)
 def get(self, context):
-  value0 = self.children[0].get_float(context)
-  value1 = self.children[1].get_float(context)
-  return value0 / value1
-@method(RValuePower)
+  value = self.children[0].get(context)
+  assert False
+@method(RValueFre)
 def get(self, context):
-  value0 = self.children[0].get_float(context)
-  value1 = self.children[1].get_float(context)
-  return value0 ** value1
-@method(RValueSign)
+  value = self.children[0].get(context)
+  assert False
+@method(RValueScrnLParen)
 def get(self, context):
-  value = self.children[0].get_float(context)
-  return self.sign * value
-@method(RValueNot)
+  value = self.children[0].get(context)
+  assert False
+@method(RValuePdl)
 def get(self, context):
-  value = self.children[0].get_float(context)
-  return float(value == 0.)
-@method(RValueIntLiteral)
+  value = self.children[0].get(context)
+  assert False
+@method(RValuePos)
 def get(self, context):
-  return float(self.children[0].int_value)
-@method(RValueFloatLiteral)
+  value = self.children[0].get(context)
+  assert False
+@method(RValueSqr)
 def get(self, context):
-  return self.children[0].float_value
-@method(RValueStrLiteral)
+  value = self.children[0].get(context)
+  assert False
+@method(RValueRnd)
 def get(self, context):
-  return self.children[0].text[0]
+  value = self.children[0].get(context)
+  assert False
+@method(RValueLog)
+def get(self, context):
+  value = self.children[0].get(context)
+  assert False
+@method(RValueExp)
+def get(self, context):
+  value = self.children[0].get(context)
+  assert False
+@method(RValueCos)
+def get(self, context):
+  value = self.children[0].get(context)
+  assert False
+@method(RValueSin)
+def get(self, context):
+  value = self.children[0].get(context)
+  assert False
+@method(RValueTan)
+def get(self, context):
+  value = self.children[0].get(context)
+  assert False
+@method(RValueAtn)
+def get(self, context):
+  value = self.children[0].get(context)
+  assert False
+@method(RValuePeek)
+def get(self, context):
+  value = self.children[0].get_str(context)
+  return float(apple_io.peek(data_types.cint(value)))
+@method(RValueLen)
+def get(self, context):
+  value = self.children[0].get(context)
+  assert False
 @method(RValueStrDollar)
 def get(self, context):
   value = self.children[0].get_float(context)
@@ -619,14 +861,26 @@ def get(self, context):
 def get(self, context):
   value = self.children[0].get_str(context)
   return data_types.val(value)
-@method(RValuePeek)
+@method(RValueAsc)
 def get(self, context):
-  value = self.children[0].get_str(context)
-  return float(apple_io.peek(data_types.cint(value)))
-@method(RValueTabLParen)
+  value = self.children[0].get(context)
+  assert False
+@method(RValueChrDollar)
 def get(self, context):
-  value = self.children[0].get_float(context)
-  return apple_io.tab(data_types.cint(value))
+  value = self.children[0].get(context)
+  assert False
+@method(RValueLeftDollar)
+def get(self, context):
+  value = self.children[0].get(context)
+  assert False
+@method(RValueRightDollar)
+def get(self, context):
+  value = self.children[0].get(context)
+  assert False
+@method(RValueMidDollar)
+def get(self, context):
+  value = self.children[0].get(context)
+  assert False
 @method(LValue)
 def get(self, context):
   value = self.find_variable(context).value
index 0793bb3..8d53880 100644 (file)
@@ -166,43 +166,78 @@ statement_list
 
 statement_opt
   :
-  | %space (?E{t_def.StatementLet}lvalue TOKEN_EQUAL rvalue)
-  | %space (?E{t_def.StatementLet}TOKEN_LET lvalue TOKEN_EQUAL rvalue)
-  | %space (?E{t_def.StatementPrint, semicolon = False}TOKEN_PRINT print_item_list0)
-  | %space (?E{t_def.StatementPrint, semicolon = True}TOKEN_PRINT print_item_list1)
-  | %space (?E{t_def.StatementGoto}TOKEN_GOTO INT_LITERAL)
-  | %space (?E{t_def.StatementIf}TOKEN_IF rvalue TOKEN_THEN) statement_opt
-  | %space (?E{t_def.StatementIf}TOKEN_IF rvalue TOKEN_THEN) %space (?E{t_def.StatementGoto}INT_LITERAL)
   | %space (?E{t_def.StatementEnd}TOKEN_END)
-  | %space (?E{t_def.StatementGosub}TOKEN_GOSUB INT_LITERAL)
-  | %space (?E{t_def.StatementReturn}TOKEN_RETURN)
   | %space (?E{t_def.StatementFor}TOKEN_FOR VARIABLE_NAME TOKEN_EQUAL rvalue TOKEN_TO rvalue)
   | %space (?E{t_def.StatementFor}TOKEN_FOR VARIABLE_NAME TOKEN_EQUAL rvalue TOKEN_TO rvalue TOKEN_STEP rvalue)
   | %space (?E{t_def.StatementNext}TOKEN_NEXT)
   | %space (?E{t_def.StatementNext}TOKEN_NEXT VARIABLE_NAME)
-  | %space (?E{t_def.StatementRead}TOKEN_READ lvalue_list)
-  | %space (?E{t_def.StatementRestore}TOKEN_RESTORE)
-  | %space (?E{t_def.StatementRestore}TOKEN_RESTORE INT_LITERAL)
   | %space (?E{t_def.StatementData}TOKEN_DATA data_item_list)
-  | %space (?E{t_def.StatementHome}TOKEN_HOME)
-  | %space (?E{t_def.StatementNormal}TOKEN_NORMAL)
-  | %space (?E{t_def.StatementInverse}TOKEN_INVERSE)
-  | %space (?E{t_def.StatementFlash}TOKEN_FLASH)
-  | %space (?E{t_def.StatementHTab}TOKEN_HTAB rvalue)
-  | %space (?E{t_def.StatementVTab}TOKEN_VTAB rvalue)
-  | %space (?E{t_def.StatementGet}TOKEN_GET lvalue)
   | %space (?E{t_def.StatementInput}TOKEN_INPUT lvalue)
   | %space (?E{t_def.StatementInput}TOKEN_INPUT STR_LITERAL ';' lvalue)
+  | %space (?E{t_def.StatementDel}TOKEN_DEL)
   | %space (?E{t_def.StatementDim}TOKEN_DIM dim_item_list)
-  | %space (?E{t_def.StatementPoke}TOKEN_POKE rvalue ',' rvalue)
-  | %space (?E{t_def.StatementCall}TOKEN_CALL rvalue)
-  | %space (?E{t_def.StatementText}TOKEN_TEXT)
+  | %space (?E{t_def.StatementRead}TOKEN_READ lvalue_list)
   | %space (?E{t_def.StatementGr}TOKEN_GR)
-  | %space (?E{t_def.StatementColorEqual}TOKEN_COLOR_EQUAL rvalue)
+  | %space (?E{t_def.StatementText}TOKEN_TEXT)
+  | %space (?E{t_def.StatementPrHash}TOKEN_PR_HASH)
+  | %space (?E{t_def.StatementInHash}TOKEN_IN_HASH)
+  | %space (?E{t_def.StatementCall}TOKEN_CALL rvalue)
   | %space (?E{t_def.StatementPlot}TOKEN_PLOT rvalue ',' rvalue)
   | %space (?E{t_def.StatementHLin}TOKEN_HLIN rvalue ',' rvalue TOKEN_AT rvalue)
   | %space (?E{t_def.StatementVLin}TOKEN_VLIN rvalue ',' rvalue TOKEN_AT rvalue)
+  | %space (?E{t_def.StatementHGR2}TOKEN_HGR2)
+  | %space (?E{t_def.StatementHGR}TOKEN_HGR)
+  | %space (?E{t_def.StatementHColorEqual}TOKEN_HCOLOR_EQUAL)
+  | %space (?E{t_def.StatementHPlot}TOKEN_HPLOT)
+  | %space (?E{t_def.StatementDraw}TOKEN_DRAW)
+  | %space (?E{t_def.StatementXDraw}TOKEN_XDRAW)
+  | %space (?E{t_def.StatementHTab}TOKEN_HTAB rvalue)
+  | %space (?E{t_def.StatementHome}TOKEN_HOME)
+  | %space (?E{t_def.StatementRotEqual}TOKEN_ROT_EQUAL)
+  | %space (?E{t_def.StatementScaleEqual}TOKEN_SCALE_EQUAL)
+  | %space (?E{t_def.StatementShLoad}TOKEN_SHLOAD)
+  | %space (?E{t_def.StatementTrace}TOKEN_TRACE)
+  | %space (?E{t_def.StatementNoTrace}TOKEN_NOTRACE)
+  | %space (?E{t_def.StatementNormal}TOKEN_NORMAL)
+  | %space (?E{t_def.StatementInverse}TOKEN_INVERSE)
+  | %space (?E{t_def.StatementFlash}TOKEN_FLASH)
+  | %space (?E{t_def.StatementColorEqual}TOKEN_COLOR_EQUAL rvalue)
+  | %space (?E{t_def.StatementPop}TOKEN_POP)
+  | %space (?E{t_def.StatementVTab}TOKEN_VTAB rvalue)
+  | %space (?E{t_def.StatementHimemColon}TOKEN_HIMEM_COLON)
+  | %space (?E{t_def.StatementLomemColon}TOKEN_LOMEM_COLON)
+  | %space (?E{t_def.StatementOnErr}TOKEN_ONERR)
+  | %space (?E{t_def.StatementResume}TOKEN_RESUME)
+  | %space (?E{t_def.StatementRecall}TOKEN_RECALL)
+  | %space (?E{t_def.StatementStore}TOKEN_STORE)
+  | %space (?E{t_def.StatementSpeedEqual}TOKEN_SPEED_EQUAL)
+  | %space (?E{t_def.StatementLet}lvalue TOKEN_EQUAL rvalue)
+  | %space (?E{t_def.StatementLet}TOKEN_LET lvalue TOKEN_EQUAL rvalue)
+  | %space (?E{t_def.StatementGoto}TOKEN_GOTO INT_LITERAL)
+  | %space (?E{t_def.StatementRun}TOKEN_RUN)
+  | %space (?E{t_def.StatementIf}TOKEN_IF rvalue TOKEN_THEN) statement_opt
+  | %space (?E{t_def.StatementIf}TOKEN_IF rvalue TOKEN_THEN) %space (?E{t_def.StatementGoto}INT_LITERAL)
+  | %space (?E{t_def.StatementRestore}TOKEN_RESTORE)
+  | %space (?E{t_def.StatementRestore}TOKEN_RESTORE INT_LITERAL)
+  | %space (?E{t_def.StatementAmpersand}TOKEN_AMPERSAND)
+  | %space (?E{t_def.StatementGosub}TOKEN_GOSUB INT_LITERAL)
+  | %space (?E{t_def.StatementReturn}TOKEN_RETURN)
   | %space (?E{t_def.StatementRem}TOKEN_REM REM_TEXT)
+  | %space (?E{t_def.StatementStop}TOKEN_STOP)
+  | %space (?E{t_def.StatementOnGoto}TOKEN_ON rvalue TOKEN_GOTO int_literal_list_opt)
+  | %space (?E{t_def.StatementOnGosub}TOKEN_ON rvalue TOKEN_GOSUB int_literal_list_opt)
+  | %space (?E{t_def.StatementWait}TOKEN_WAIT)
+  | %space (?E{t_def.StatementLoad}TOKEN_LOAD)
+  | %space (?E{t_def.StatementSave}TOKEN_SAVE)
+  | %space (?E{t_def.StatementDef}TOKEN_DEF)
+  | %space (?E{t_def.StatementPoke}TOKEN_POKE rvalue ',' rvalue)
+  | %space (?E{t_def.StatementPrint, semicolon = False}TOKEN_PRINT print_item_list0)
+  | %space (?E{t_def.StatementPrint, semicolon = True}TOKEN_PRINT print_item_list1)
+  | %space (?E{t_def.StatementCont}TOKEN_CONT)
+  | %space (?E{t_def.StatementList}TOKEN_LIST)
+  | %space (?E{t_def.StatementClear}TOKEN_CLEAR)
+  | %space (?E{t_def.StatementGet}TOKEN_GET lvalue)
+  | %space (?E{t_def.StatementNew}TOKEN_NEW)
   ;
 
 print_item_list0
@@ -226,6 +261,16 @@ lvalue_list
   | lvalue_list ',' lvalue
   ;
 
+int_literal_list_opt
+  :
+  | int_literal_list
+  ;
+
+int_literal_list
+  : INT_LITERAL
+  | int_literal_list ',' INT_LITERAL
+  ;
+
 data_item_list
   : data_item
   | data_item_list ',' data_item
@@ -257,25 +302,48 @@ rvalue
   | %space (?E{t_def.RValueStrLiteral}STR_LITERAL)
   | %space (?E{t_def.RValueFloatLiteral}FLOAT_LITERAL)
   | %space (?E{t_def.RValueIntLiteral}INT_LITERAL)
+  | %space (?E{t_def.RValueSpcLParen}TOKEN_SPC_LPAREN rvalue ')')
   | %space (?E{t_def.RValueNot}TOKEN_NOT rvalue)
   | %space (?E{t_def.RValueSign, sign = 1}TOKEN_PLUS rvalue) %prec UNARY
   | %space (?E{t_def.RValueSign, sign = -1}TOKEN_MINUS rvalue) %prec UNARY
-  | %space (?E{t_def.RValuePower}rvalue TOKEN_CARET rvalue)
-  | %space (?E{t_def.RValueDivide}rvalue TOKEN_SLASH rvalue)
-  | %space (?E{t_def.RValueMultiply}rvalue TOKEN_ASTERISK rvalue)
-  | %space (?E{t_def.RValueSubtract}rvalue TOKEN_MINUS rvalue)
   | %space (?E{t_def.RValueAdd}rvalue TOKEN_PLUS rvalue)
-  | %space (?E{t_def.RValueNE}rvalue OPERATOR_NE rvalue)
-  | %space (?E{t_def.RValueLE}rvalue OPERATOR_LE rvalue)
-  | %space (?E{t_def.RValueGE}rvalue OPERATOR_GE rvalue)
+  | %space (?E{t_def.RValueSubtract}rvalue TOKEN_MINUS rvalue)
+  | %space (?E{t_def.RValueMultiply}rvalue TOKEN_ASTERISK rvalue)
+  | %space (?E{t_def.RValueDivide}rvalue TOKEN_SLASH rvalue)
+  | %space (?E{t_def.RValuePower}rvalue TOKEN_CARET rvalue)
+  | %space (?E{t_def.RValueAnd}rvalue TOKEN_AND rvalue)
+  | %space (?E{t_def.RValueOr}rvalue TOKEN_OR rvalue)
   | %space (?E{t_def.RValueGT}rvalue TOKEN_GREATER_THAN rvalue)
   | %space (?E{t_def.RValueEqual}rvalue TOKEN_EQUAL rvalue)
   | %space (?E{t_def.RValueLT}rvalue TOKEN_LESS_THAN rvalue)
-  | %space (?E{t_def.RValueAnd}rvalue TOKEN_AND rvalue)
-  | %space (?E{t_def.RValueOr}rvalue TOKEN_OR rvalue)
+  | %space (?E{t_def.RValueGE}rvalue OPERATOR_GE rvalue)
+  | %space (?E{t_def.RValueLE}rvalue OPERATOR_LE rvalue)
+  | %space (?E{t_def.RValueNE}rvalue OPERATOR_NE rvalue)
+  | %space (?E{t_def.RValueSgn}TOKEN_SGN '(' rvalue ')')
+  | %space (?E{t_def.RValueInt}TOKEN_INT '(' rvalue ')')
+  | %space (?E{t_def.RValueAbs}TOKEN_ABS '(' rvalue ')')
+  | %space (?E{t_def.RValueUsr}TOKEN_USR '(' rvalue ')')
+  | %space (?E{t_def.RValueFre}TOKEN_FRE '(' rvalue ')')
+  | %space (?E{t_def.RValueScrnLParen}TOKEN_SCRN_LPAREN rvalue ')')
+  | %space (?E{t_def.RValuePdl}TOKEN_PDL '(' rvalue ')')
+  | %space (?E{t_def.RValuePos}TOKEN_POS '(' rvalue ')')
+  | %space (?E{t_def.RValueSqr}TOKEN_SQR '(' rvalue ')')
+  | %space (?E{t_def.RValueRnd}TOKEN_RND '(' rvalue ')')
+  | %space (?E{t_def.RValueLog}TOKEN_LOG '(' rvalue ')')
+  | %space (?E{t_def.RValueExp}TOKEN_EXP '(' rvalue ')')
+  | %space (?E{t_def.RValueCos}TOKEN_COS '(' rvalue ')')
+  | %space (?E{t_def.RValueSin}TOKEN_SIN '(' rvalue ')')
+  | %space (?E{t_def.RValueTan}TOKEN_TAN '(' rvalue ')')
+  | %space (?E{t_def.RValueAtn}TOKEN_ATN '(' rvalue ')')
+  | %space (?E{t_def.RValuePeek}TOKEN_PEEK '(' rvalue ')')
+  | %space (?E{t_def.RValueLen}TOKEN_LEN '(' rvalue ')')
   | %space (?E{t_def.RValueStrDollar}TOKEN_STR_DOLLAR '(' rvalue ')')
   | %space (?E{t_def.RValueVal}TOKEN_VAL '(' rvalue ')')
-  | %space (?E{t_def.RValuePeek}TOKEN_PEEK '(' rvalue ')')
+  | %space (?E{t_def.RValueAsc}TOKEN_ASC '(' rvalue ')')
+  | %space (?E{t_def.RValueChrDollar}TOKEN_CHR_DOLLAR '(' rvalue ')')
+  | %space (?E{t_def.RValueLeftDollar}TOKEN_LEFT_DOLLAR '(' rvalue ')')
+  | %space (?E{t_def.RValueRightDollar}TOKEN_RIGHT_DOLLAR '(' rvalue ')')
+  | %space (?E{t_def.RValueMidDollar}TOKEN_MID_DOLLAR '(' rvalue ')')
   ;
 
 lvalue