/* generic */
class Node;
-class NodeText: Node {
+class Text: Node {
class Char;
str str_value = '';
};
/* lexical tokens */
-class NodeTextIntLiteral: NodeText {
+class IntLiteral: Text {
int int_value = 0;
};
-class NodeFloatLiteral: Node {
- class NodeTextSign: NodeText;
- class NodeTextInteger: NodeText;
- class NodeTextFraction: NodeText;
- class NodeExponent: Node;
+class FloatLiteral: Node {
+ class Sign: Text;
+ class Integer: Text;
+ class Fraction: Text;
+ class Exponent: Node;
float float_value = 0.;
};
-class NodeStrLiteral: Node;
-class NodeTextVariableName: NodeText;
+class StrLiteral: Node;
+class VariableName: Text;
/* grammar productions */
-class NodeProgram: Node;
-class NodeLine: Node;
-class NodeStatement: Node;
-class NodeStatementLet: NodeStatement;
-class NodeStatementPrint: NodeStatement {
+class Program: Node;
+class Line: Node;
+class Statement: Node;
+class StatementLet: Statement;
+class StatementPrint: Statement {
bool semicolon;
};
-class NodeStatementGoto: NodeStatement;
-class NodeStatementIf: NodeStatement;
-class NodeStatementEnd: NodeStatement;
-class NodeStatementGosub: NodeStatement;
-class NodeStatementReturn: NodeStatement;
-class NodeStatementFor: NodeStatement;
-class NodeStatementNext: NodeStatement;
-class NodeStatementRead: NodeStatement;
-class NodeStatementRestore: NodeStatement;
-class NodeStatementData: NodeStatement;
-class NodeStatementHome: NodeStatement;
-class NodeStatementNormal: NodeStatement;
-class NodeStatementInverse: NodeStatement;
-class NodeStatementFlash: NodeStatement;
-class NodeStatementHTab: NodeStatement;
-class NodeStatementVTab: NodeStatement;
-class NodeStatementGet: NodeStatement;
-class NodeStatementInput: NodeStatement;
-class NodeRValue: Node;
-class NodeRValueOr: NodeRValue;
-class NodeRValueAnd: NodeRValue;
-class NodeRValueLT: NodeRValue;
-class NodeRValueEqual: NodeRValue;
-class NodeRValueGT: NodeRValue;
-class NodeRValueGE: NodeRValue;
-class NodeRValueLE: NodeRValue;
-class NodeRValueNE: NodeRValue;
-class NodeRValueAdd: NodeRValue;
-class NodeRValueSubtract: NodeRValue;
-class NodeRValueMultiply: NodeRValue;
-class NodeRValueDivide: NodeRValue;
-class NodeRValuePower: NodeRValue;
-class NodeRValueSign: NodeRValue {
+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 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 RValueAdd: RValue;
+class RValueSubtract: RValue;
+class RValueMultiply: RValue;
+class RValueDivide: RValue;
+class RValuePower: RValue;
+class RValueSign: RValue {
int sign;
};
-class NodeRValueNot: NodeRValue;
-class NodeRValueIntLiteral: NodeRValue;
-class NodeRValueFloatLiteral: NodeRValue;
-class NodeRValueStrLiteral: NodeRValue;
-class NodeRValueVariable: NodeRValue;
-class NodeRValueStrDollar: NodeRValue;
-class NodeRValueVal: NodeRValue;
+class RValueNot: RValue;
+class RValueIntLiteral: RValue;
+class RValueFloatLiteral: RValue;
+class RValueStrLiteral: RValue;
+class RValueVariable: RValue;
+class RValueStrDollar: RValue;
+class RValueVal: RValue;
%%
l = 1,
m = 0
):
- self.program = program if program is not None else NodeProgram()
+ self.program = program if program is not None else Program()
self.variables = variables if variables is not None else {}
# execute pointer (line index, statement index)
def post_process(self, program):
for i in self.children:
i.post_process(program)
-@method(NodeText)
+@method(Text)
def post_process(self, program):
self.str_value = ''.join([i.text[0] for i in self.children])
-@method(NodeTextIntLiteral)
+@method(IntLiteral)
def post_process(self, program):
- NodeText.post_process(self, program)
+ Text.post_process(self, program)
self.int_value = int(self.str_value)
del post_process
-@method(NodeFloatLiteral)
+@method(FloatLiteral)
def post_process(self, program):
Node.post_process(self, program)
exponent_value = 0
self.float_value = value
del post_process
-@method(NodeStatement)
+@method(Statement)
def execute(self, context):
raise NotImplementedError()
-@method(NodeStatementLet)
+@method(StatementLet)
def execute(self, context):
name = self.children[0].str_value
if name[-1] == '$':
if name[-1] == '$':
value = data_types.cint(value)
context.find_variable(name).value = value
-@method(NodeStatementPrint)
+@method(StatementPrint)
def execute(self, context):
for i in self.children:
value = i.get(context)
apple_io._print(value)
if not self.semicolon:
apple_io.cr() # really writes \r\n
-@method(NodeStatementGoto)
+@method(StatementGoto)
def execute(self, context):
context.i = context.find_line(self.children[0].int_value)
context.j = 1
-@method(NodeStatementIf)
+@method(StatementIf)
def execute(self, context):
value = self.children[0].get(context)
if value == '' or value == 0.:
context.i += 1
context.j = 1
-@method(NodeStatementEnd)
+@method(StatementEnd)
def execute(self, context):
raise EndException()
-@method(NodeStatementGosub)
+@method(StatementGosub)
def execute(self, context):
i = context.i
j = context.j
)
context.i = i
context.j = j
-@method(NodeStatementReturn)
+@method(StatementReturn)
def execute(self, context):
raise ReturnException()
-@method(NodeStatementFor)
+@method(StatementFor)
def execute(self, context):
name = self.children[0].str_value
if name[-1] == '$':
line = context.program.children[context.i]
assert context.j > 1 and context.j <= len(line.children)
statement = line.children[context.j - 1]
- assert isinstance(statement, NodeStatementNext)
+ assert isinstance(statement, StatementNext)
if (
len(statement.children) >= 1 and
statement.children[0].str_value != name
context.i = i
context.j = j
-@method(NodeStatementNext)
+@method(StatementNext)
def execute(self, context):
raise NextException()
-@method(NodeStatementRead)
+@method(StatementRead)
def execute(self, context):
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, NodeStatementData) and
+ isinstance(statement, StatementData) and
context.m < len(statement.children)
):
item = statement.children[context.m]
name = self.children[0].str_value
if name[-1] == '$':
- if not isinstance(item, NodeStrLiteral):
+ if not isinstance(item, StrLiteral):
raise Exception(
f'?TYPE MISMATCH ERROR IN {context.line_number():d}'
)
value = item.text[0]
else:
- if isinstance(item, NodeTextIntLiteral):
+ if isinstance(item, IntLiteral):
value = float(item.int_value)
- elif isinstance(item, NodeFloatLiteral):
+ elif isinstance(item, FloatLiteral):
value = item.float_value
else:
raise Exception(
if name[-1] == '%':
value = data_types.cint(value)
context.find_variable(name).value = value
-@method(NodeStatementRestore)
+@method(StatementRestore)
def execute(self, context):
context.k = (
context.find_line(self.children[0].int_value)
)
context.l = 1
context.m = 0
-@method(NodeStatementData)
+@method(StatementData)
def execute(self, context):
pass
-@method(NodeStatementHome)
+@method(StatementHome)
def execute(self, context):
apple_io.home()
-@method(NodeStatementNormal)
+@method(StatementNormal)
def execute(self, context):
apple_io.normal()
-@method(NodeStatementInverse)
+@method(StatementInverse)
def execute(self, context):
apple_io.inverse()
-@method(NodeStatementFlash)
+@method(StatementFlash)
def execute(self, context):
apple_io.flash()
-@method(NodeStatementHTab)
+@method(StatementHTab)
def execute(self, context):
value = self.children[0].get_float(context)
apple_io.htab(data_types.cint(value))
-@method(NodeStatementVTab)
+@method(StatementVTab)
def execute(self, context):
value = self.children[0].get_float(context)
apple_io.vtab(data_types.cint(value))
-@method(NodeStatementGet)
+@method(StatementGet)
def execute(self, context):
name = self.children[0].str_value
value = apple_io.get()
f'?SYNTAX ERROR IN {context.line_number():d}'
)
context.find_variable(name).value = value
-@method(NodeStatementInput)
+@method(StatementInput)
def execute(self, context):
apple_io._print(
self.children[-2].text[0]
context.find_variable(name).value = value
del execute
-@method(NodeRValue)
+@method(RValue)
def get(self, context):
raise NotImplementedError()
-@method(NodeRValueOr)
+@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(NodeRValueAnd)
+@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(NodeRValueLT)
+@method(RValueLT)
def get(self, context):
value0 = self.children[0].get(context)
value1 = (
self.children[1].get_str(context)
)
return float(value0 < value1)
-@method(NodeRValueEqual)
+@method(RValueEqual)
def get(self, context):
value0 = self.children[0].get(context)
value1 = (
self.children[1].get_str(context)
)
return float(value0 == value1)
-@method(NodeRValueGT)
+@method(RValueGT)
def get(self, context):
value0 = self.children[0].get(context)
value1 = (
self.children[1].get_str(context)
)
return float(value0 > value1)
-@method(NodeRValueGE)
+@method(RValueGE)
def get(self, context):
value0 = self.children[0].get(context)
value1 = (
self.children[1].get_str(context)
)
return float(value0 >= value1)
-@method(NodeRValueLE)
+@method(RValueLE)
def get(self, context):
value0 = self.children[0].get(context)
value1 = (
self.children[1].get_str(context)
)
return float(value0 <= value1)
-@method(NodeRValueNE)
+@method(RValueNE)
def get(self, context):
value0 = self.children[0].get(context)
value1 = (
self.children[1].get_str(context)
)
return float(value0 != value1)
-@method(NodeRValueAdd)
+@method(RValueAdd)
def get(self, context):
value0 = self.children[0].get(context)
value1 = (
self.children[1].get_str(context)
)
return value0 + value1
-@method(NodeRValueSubtract)
+@method(RValueSubtract)
def get(self, context):
value0 = self.children[0].get_float(context)
value1 = self.children[1].get_float(context)
return value0 - value1
-@method(NodeRValueMultiply)
+@method(RValueMultiply)
def get(self, context):
value0 = self.children[0].get_float(context)
value1 = self.children[1].get_float(context)
return value0 * value1
-@method(NodeRValueDivide)
+@method(RValueDivide)
def get(self, context):
value0 = self.children[0].get_float(context)
value1 = self.children[1].get_float(context)
return value0 / value1
-@method(NodeRValuePower)
+@method(RValuePower)
def get(self, context):
value0 = self.children[0].get_float(context)
value1 = self.children[1].get_float(context)
return value0 ** value1
-@method(NodeRValueSign)
+@method(RValueSign)
def get(self, context):
value = self.children[0].get_float(context)
return self.sign * value
-@method(NodeRValueNot)
+@method(RValueNot)
def get(self, context):
value = self.children[0].get_float(context)
return float(value == 0.)
-@method(NodeRValueIntLiteral)
+@method(RValueIntLiteral)
def get(self, context):
return float(self.children[0].int_value)
-@method(NodeRValueFloatLiteral)
+@method(RValueFloatLiteral)
def get(self, context):
return self.children[0].float_value
-@method(NodeRValueStrLiteral)
+@method(RValueStrLiteral)
def get(self, context):
return self.children[0].text[0]
-@method(NodeRValueVariable)
+@method(RValueVariable)
def get(self, context):
name = self.children[0].str_value
return context.find_variable(name).value
-@method(NodeRValueStrDollar)
+@method(RValueStrDollar)
def get(self, context):
value = self.children[0].get_float(context)
return data_types.str_dollar(value)
-@method(NodeRValueVal)
+@method(RValueVal)
def get(self, context):
value = self.children[0].get_str(context)
return data_types.val(value)
del get
-@method(NodeRValue)
+@method(RValue)
def get_float(self, context):
value = self.get(context)
if not isinstance(value, float):
return value
del get_float
-@method(NodeRValue)
+@method(RValue)
def get_str(self, context):
value = self.get(context)
if not isinstance(value, str):
program
:
- | program %space (?E{t_def.NodeLine}INT_LITERAL statement_list) '\n'
+ | program %space (?E{t_def.Line}INT_LITERAL statement_list) '\n'
| error '\n' {
yyerror('Syntax error\n')
yyerrok()
statement_opt
:
- | %space (?E{t_def.NodeStatementLet}VARIABLE_NAME '=' expression)
- | %space (?E{t_def.NodeStatementLet}KEYWORD_LET VARIABLE_NAME '=' expression)
- | %space (?E{t_def.NodeStatementPrint, semicolon = False}KEYWORD_PRINT print_expression_list0)
- | %space (?E{t_def.NodeStatementPrint, semicolon = True}KEYWORD_PRINT print_expression_list1)
- | %space (?E{t_def.NodeStatementGoto}KEYWORD_GOTO INT_LITERAL)
- | %space (?E{t_def.NodeStatementIf}KEYWORD_IF expression KEYWORD_THEN) statement_opt
- | %space (?E{t_def.NodeStatementIf}KEYWORD_IF expression KEYWORD_THEN) %space (?E{t_def.NodeStatementGoto}INT_LITERAL)
- | %space (?E{t_def.NodeStatementEnd}KEYWORD_END)
- | %space (?E{t_def.NodeStatementGosub}KEYWORD_GOSUB INT_LITERAL)
- | %space (?E{t_def.NodeStatementReturn}KEYWORD_RETURN)
- | %space (?E{t_def.NodeStatementFor}KEYWORD_FOR VARIABLE_NAME '=' expression KEYWORD_TO expression)
- | %space (?E{t_def.NodeStatementFor}KEYWORD_FOR VARIABLE_NAME '=' expression KEYWORD_TO expression KEYWORD_STEP expression)
- | %space (?E{t_def.NodeStatementNext}KEYWORD_NEXT)
- | %space (?E{t_def.NodeStatementNext}KEYWORD_NEXT VARIABLE_NAME)
- | %space (?E{t_def.NodeStatementRead}KEYWORD_READ VARIABLE_NAME)
- | %space (?E{t_def.NodeStatementRestore}KEYWORD_RESTORE INT_LITERAL)
- | %space (?E{t_def.NodeStatementData}KEYWORD_DATA data_item_list)
- | %space (?E{t_def.NodeStatementHome}KEYWORD_HOME)
- | %space (?E{t_def.NodeStatementNormal}KEYWORD_NORMAL)
- | %space (?E{t_def.NodeStatementInverse}KEYWORD_INVERSE)
- | %space (?E{t_def.NodeStatementFlash}KEYWORD_FLASH)
- | %space (?E{t_def.NodeStatementHTab}KEYWORD_HTAB expression)
- | %space (?E{t_def.NodeStatementVTab}KEYWORD_VTAB expression)
- | %space (?E{t_def.NodeStatementGet}KEYWORD_GET VARIABLE_NAME)
- | %space (?E{t_def.NodeStatementInput}KEYWORD_INPUT VARIABLE_NAME)
- | %space (?E{t_def.NodeStatementInput}KEYWORD_INPUT STR_LITERAL ';' VARIABLE_NAME)
+ | %space (?E{t_def.StatementLet}VARIABLE_NAME '=' expression)
+ | %space (?E{t_def.StatementLet}KEYWORD_LET VARIABLE_NAME '=' expression)
+ | %space (?E{t_def.StatementPrint, semicolon = False}KEYWORD_PRINT print_expression_list0)
+ | %space (?E{t_def.StatementPrint, semicolon = True}KEYWORD_PRINT print_expression_list1)
+ | %space (?E{t_def.StatementGoto}KEYWORD_GOTO INT_LITERAL)
+ | %space (?E{t_def.StatementIf}KEYWORD_IF expression KEYWORD_THEN) statement_opt
+ | %space (?E{t_def.StatementIf}KEYWORD_IF expression KEYWORD_THEN) %space (?E{t_def.StatementGoto}INT_LITERAL)
+ | %space (?E{t_def.StatementEnd}KEYWORD_END)
+ | %space (?E{t_def.StatementGosub}KEYWORD_GOSUB INT_LITERAL)
+ | %space (?E{t_def.StatementReturn}KEYWORD_RETURN)
+ | %space (?E{t_def.StatementFor}KEYWORD_FOR VARIABLE_NAME '=' expression KEYWORD_TO expression)
+ | %space (?E{t_def.StatementFor}KEYWORD_FOR VARIABLE_NAME '=' expression KEYWORD_TO expression KEYWORD_STEP expression)
+ | %space (?E{t_def.StatementNext}KEYWORD_NEXT)
+ | %space (?E{t_def.StatementNext}KEYWORD_NEXT VARIABLE_NAME)
+ | %space (?E{t_def.StatementRead}KEYWORD_READ VARIABLE_NAME)
+ | %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)
+ | %space (?E{t_def.StatementNormal}KEYWORD_NORMAL)
+ | %space (?E{t_def.StatementInverse}KEYWORD_INVERSE)
+ | %space (?E{t_def.StatementFlash}KEYWORD_FLASH)
+ | %space (?E{t_def.StatementHTab}KEYWORD_HTAB expression)
+ | %space (?E{t_def.StatementVTab}KEYWORD_VTAB expression)
+ | %space (?E{t_def.StatementGet}KEYWORD_GET VARIABLE_NAME)
+ | %space (?E{t_def.StatementInput}KEYWORD_INPUT VARIABLE_NAME)
+ | %space (?E{t_def.StatementInput}KEYWORD_INPUT STR_LITERAL ';' VARIABLE_NAME)
;
print_expression_list0
;
expression
- : %space (?E{t_def.NodeRValueOr}expression KEYWORD_OR expression)
- | %space (?E{t_def.NodeRValueAnd}expression KEYWORD_AND expression)
- | %space (?E{t_def.NodeRValueLT}expression '<' expression)
- | %space (?E{t_def.NodeRValueEqual}expression '=' expression)
- | %space (?E{t_def.NodeRValueGT}expression '>' expression)
- | %space (?E{t_def.NodeRValueGE}expression OPERATOR_GE expression)
- | %space (?E{t_def.NodeRValueLE}expression OPERATOR_LE expression)
- | %space (?E{t_def.NodeRValueNE}expression OPERATOR_NE expression)
- | %space (?E{t_def.NodeRValueAdd}expression '+' expression)
- | %space (?E{t_def.NodeRValueSubtract}expression '-' expression)
- | %space (?E{t_def.NodeRValueMultiply}expression '*' expression)
- | %space (?E{t_def.NodeRValueDivide}expression '/' expression)
- | %space (?E{t_def.NodeRValuePower}expression '^' expression)
- | %space (?E{t_def.NodeRValueSign, sign = -1}'-' expression) %prec UNARY
- | %space (?E{t_def.NodeRValueSign, sign = 1}'+' expression) %prec UNARY
- | %space (?E{t_def.NodeRValueNot}KEYWORD_NOT expression)
+ : %space (?E{t_def.RValueOr}expression KEYWORD_OR expression)
+ | %space (?E{t_def.RValueAnd}expression KEYWORD_AND expression)
+ | %space (?E{t_def.RValueLT}expression '<' expression)
+ | %space (?E{t_def.RValueEqual}expression '=' expression)
+ | %space (?E{t_def.RValueGT}expression '>' expression)
+ | %space (?E{t_def.RValueGE}expression OPERATOR_GE expression)
+ | %space (?E{t_def.RValueLE}expression OPERATOR_LE expression)
+ | %space (?E{t_def.RValueNE}expression OPERATOR_NE expression)
+ | %space (?E{t_def.RValueAdd}expression '+' expression)
+ | %space (?E{t_def.RValueSubtract}expression '-' expression)
+ | %space (?E{t_def.RValueMultiply}expression '*' expression)
+ | %space (?E{t_def.RValueDivide}expression '/' expression)
+ | %space (?E{t_def.RValuePower}expression '^' expression)
+ | %space (?E{t_def.RValueSign, sign = -1}'-' expression) %prec UNARY
+ | %space (?E{t_def.RValueSign, sign = 1}'+' expression) %prec UNARY
+ | %space (?E{t_def.RValueNot}KEYWORD_NOT expression)
| '(' expression ')'
- | %space (?E{t_def.NodeRValueIntLiteral}INT_LITERAL)
- | %space (?E{t_def.NodeRValueFloatLiteral}FLOAT_LITERAL)
- | %space (?E{t_def.NodeRValueStrLiteral}STR_LITERAL)
- | %space (?E{t_def.NodeRValueVariable}VARIABLE_NAME)
- | %space (?E{t_def.NodeRValueStrDollar}KEYWORD_STR_DOLLAR '(' expression ')')
- | %space (?E{t_def.NodeRValueVal}KEYWORD_VAL '(' expression ')')
+ | %space (?E{t_def.RValueIntLiteral}INT_LITERAL)
+ | %space (?E{t_def.RValueFloatLiteral}FLOAT_LITERAL)
+ | %space (?E{t_def.RValueStrLiteral}STR_LITERAL)
+ | %space (?E{t_def.RValueVariable}VARIABLE_NAME)
+ | %space (?E{t_def.RValueStrDollar}KEYWORD_STR_DOLLAR '(' expression ')')
+ | %space (?E{t_def.RValueVal}KEYWORD_VAL '(' expression ')')
;
%%