owl-basic 0.6.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- owl_basic/__init__.py +3 -0
- owl_basic/algorithms.py +29 -0
- owl_basic/ast_utils.py +204 -0
- owl_basic/basic_visitor.py +55 -0
- owl_basic/cfg_vertex.py +65 -0
- owl_basic/codegen/__init__.py +0 -0
- owl_basic/codegen/clr/__init__.py +0 -0
- owl_basic/codegen/clr/cil_visitor.py +1296 -0
- owl_basic/codegen/clr/cts.py +56 -0
- owl_basic/codegen/clr/emitters.py +94 -0
- owl_basic/codegen/clr/generate.py +539 -0
- owl_basic/correlation_visitor.py +119 -0
- owl_basic/data_visitor.py +62 -0
- owl_basic/decoder.py +339 -0
- owl_basic/errors.py +22 -0
- owl_basic/flow/__init__.py +17 -0
- owl_basic/flow/basic_block.py +34 -0
- owl_basic/flow/basic_block_identifier.py +66 -0
- owl_basic/flow/basic_block_orderer.py +29 -0
- owl_basic/flow/connectors.py +19 -0
- owl_basic/flow/convert_sub_visitor.py +28 -0
- owl_basic/flow/entry_point_locator.py +55 -0
- owl_basic/flow/entry_point_visitor.py +48 -0
- owl_basic/flow/flow_analysis.py +56 -0
- owl_basic/flow/flow_graph_creator.py +14 -0
- owl_basic/flow/flowgraph_visitor.py +178 -0
- owl_basic/flow/longjump_converter.py +20 -0
- owl_basic/flow/longjump_visitor.py +53 -0
- owl_basic/flow/subroutine_converter.py +38 -0
- owl_basic/flow/traversal.py +110 -0
- owl_basic/gml_visitor.py +151 -0
- owl_basic/line_mapper.py +43 -0
- owl_basic/line_number_visitor.py +65 -0
- owl_basic/main.py +381 -0
- owl_basic/node.py +21 -0
- owl_basic/options.py +22 -0
- owl_basic/owltyping/__init__.py +1 -0
- owl_basic/owltyping/function_type_inferer.py +50 -0
- owl_basic/owltyping/hindley_milner.py +524 -0
- owl_basic/owltyping/set_function_type_visitor.py +25 -0
- owl_basic/owltyping/type_system.py +220 -0
- owl_basic/owltyping/typecheck.py +60 -0
- owl_basic/owltyping/typecheck_visitor.py +471 -0
- owl_basic/parent_visitor.py +37 -0
- owl_basic/process.py +36 -0
- owl_basic/separation_visitor.py +98 -0
- owl_basic/sigil.py +30 -0
- owl_basic/simplify_visitor.py +204 -0
- owl_basic/singleton.py +127 -0
- owl_basic/source_debugging.py +124 -0
- owl_basic/symbol_table_visitor.py +220 -0
- owl_basic/symbol_tables.py +195 -0
- owl_basic/syntax/__init__.py +0 -0
- owl_basic/syntax/ast.py +1081 -0
- owl_basic/syntax/ast_meta.py +228 -0
- owl_basic/syntax/grammar.py +1972 -0
- owl_basic/syntax/lexer.py +943 -0
- owl_basic/syntax/parser.py +77 -0
- owl_basic/utility.py +26 -0
- owl_basic/visitor.py +43 -0
- owl_basic/xml_blocks.py +137 -0
- owl_basic/xml_visitor.py +101 -0
- owl_basic-0.6.0.dist-info/METADATA +37 -0
- owl_basic-0.6.0.dist-info/RECORD +69 -0
- owl_basic-0.6.0.dist-info/WHEEL +5 -0
- owl_basic-0.6.0.dist-info/entry_points.txt +2 -0
- owl_basic-0.6.0.dist-info/licenses/LICENSE +21 -0
- owl_basic-0.6.0.dist-info/licenses/THIRD-PARTY-NOTICES.md +57 -0
- owl_basic-0.6.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,1972 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
import ply.yacc as yacc
|
|
4
|
+
|
|
5
|
+
# Get the token map from the lexer. This is required.
|
|
6
|
+
from .lexer import tokens
|
|
7
|
+
from .ast import *
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def setDebuggingPositions(p):
|
|
11
|
+
if p is not None and p[0] is not None:
|
|
12
|
+
# If it hasn't already been set by more specialised code
|
|
13
|
+
if p[0].startLine is None:
|
|
14
|
+
#print "Assigning line numbers"
|
|
15
|
+
p[0].startLine, p[0].endLine = p.linespan(1)
|
|
16
|
+
# Note: endPos here will be *before* the last token - it can be refined later
|
|
17
|
+
p[0].startPos, p[0].endPos = p.lexspan(1)
|
|
18
|
+
#print p[0].startLine, p[0].endLine, p[0].startPos, p[0].endPos
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger('bbc_grammar')
|
|
21
|
+
|
|
22
|
+
# Precedence table for the above operators
|
|
23
|
+
precedence = (
|
|
24
|
+
('right', 'UEQUAL'),
|
|
25
|
+
('left', 'EOR', 'OR'),
|
|
26
|
+
('left', 'AND'),
|
|
27
|
+
('nonassoc', 'EQ', 'NE', 'LTE', 'GTE', 'LT', 'GT', 'SHIFT_LEFT', 'SHIFT_RIGHT', 'SHIFT_RIGHT_UNSIGNED'),
|
|
28
|
+
('left', 'PLUS', 'MINUS'),
|
|
29
|
+
('left', 'TIMES', 'DIVIDE', 'MOD', 'DIV'),
|
|
30
|
+
('left', 'CARET'),
|
|
31
|
+
('left', 'PLING', 'QUERY'), # Binary indirection operators
|
|
32
|
+
('right', 'FUNCTION', 'NOT', 'UPLUS', 'UMINUS', 'UPLING', 'UQUERY', 'UPIPE', 'UDOLLAR', 'UHASH'), # Unary operators
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
def p_program(p):
|
|
36
|
+
'program : statement_list'
|
|
37
|
+
p[0] = Program(statements = p[1])
|
|
38
|
+
|
|
39
|
+
def p_statement_list(p):
|
|
40
|
+
'''statement_list : compound_statement
|
|
41
|
+
| statement_list compound_statement'''
|
|
42
|
+
if len(p) == 2:
|
|
43
|
+
p[0] = StatementList()
|
|
44
|
+
p[0].extend(p[1])
|
|
45
|
+
elif len(p) == 3:
|
|
46
|
+
p[1].extend(p[2])
|
|
47
|
+
p[0] = p[1]
|
|
48
|
+
|
|
49
|
+
# A single line statement list - use in single-line IF THEN ELSE construct
|
|
50
|
+
def p_compound_statement(p):
|
|
51
|
+
'''compound_statement : lone_stmt_body stmt_terminator
|
|
52
|
+
| multi_statement stmt_terminator'''
|
|
53
|
+
p[0] = p[1]
|
|
54
|
+
|
|
55
|
+
def p_multi_statement(p):
|
|
56
|
+
'''multi_statement : statement statements_tail'''
|
|
57
|
+
p[2].prepend(p[1])
|
|
58
|
+
p[0] = p[2]
|
|
59
|
+
|
|
60
|
+
def p_statements_tail(p):
|
|
61
|
+
'''statements_tail : statement_separator statement statements_tail
|
|
62
|
+
| empty'''
|
|
63
|
+
if len(p) == 4:
|
|
64
|
+
p[3].prepend(p[2])
|
|
65
|
+
p[0] = p[3]
|
|
66
|
+
elif len(p) == 2:
|
|
67
|
+
p[0] = StatementList()
|
|
68
|
+
|
|
69
|
+
def p_statement_separator(p):
|
|
70
|
+
'statement_separator : COLON'
|
|
71
|
+
p[0] = p[1]
|
|
72
|
+
|
|
73
|
+
def p_stmt_terminator(p):
|
|
74
|
+
'stmt_terminator : EOL'
|
|
75
|
+
p[0] = p[1]
|
|
76
|
+
|
|
77
|
+
def p_statement(p):
|
|
78
|
+
'''statement : stmt_body
|
|
79
|
+
| empty'''
|
|
80
|
+
p[0] = p[1]
|
|
81
|
+
setDebuggingPositions(p)
|
|
82
|
+
|
|
83
|
+
#=============================================================================#
|
|
84
|
+
# STATEMENTS
|
|
85
|
+
|
|
86
|
+
# TODO: Statements to be implemented
|
|
87
|
+
'''stmt_body : chain_stmt
|
|
88
|
+
| local_stmt
|
|
89
|
+
| on_error_stmt
|
|
90
|
+
| restore_stmt PAGE 69 BBCBASIC.PDF - RESTORE +offset???
|
|
91
|
+
| trace_stmt'''
|
|
92
|
+
|
|
93
|
+
# Statements which must appear alone on
|
|
94
|
+
# their own line
|
|
95
|
+
def p_lone_stmt_body(p):
|
|
96
|
+
'''lone_stmt_body : case_stmt
|
|
97
|
+
| star_command'''
|
|
98
|
+
p[0] = StatementList()
|
|
99
|
+
p[0].append(p[1])
|
|
100
|
+
|
|
101
|
+
def p_star_command(p):
|
|
102
|
+
'''star_command : STAR_FX
|
|
103
|
+
| STAR_CAT'''
|
|
104
|
+
p[0] = StarCommand(command = p[1])
|
|
105
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
106
|
+
setDebuggingPositions(p)
|
|
107
|
+
|
|
108
|
+
# Statements which can appear alone,
|
|
109
|
+
# or in compound statements on one line
|
|
110
|
+
def p_stmt_body(p):
|
|
111
|
+
'''stmt_body : beats_stmt
|
|
112
|
+
| bput_stmt
|
|
113
|
+
| call_stmt
|
|
114
|
+
| circle_stmt
|
|
115
|
+
| clear_stmt
|
|
116
|
+
| clg_stmt
|
|
117
|
+
| cls_stmt
|
|
118
|
+
| close_stmt
|
|
119
|
+
| colour_stmt
|
|
120
|
+
| data_stmt
|
|
121
|
+
| def_stmt
|
|
122
|
+
| dim_stmt
|
|
123
|
+
| draw_stmt
|
|
124
|
+
| ellipse_stmt
|
|
125
|
+
| end_stmt
|
|
126
|
+
| end_fn_stmt
|
|
127
|
+
| endproc_stmt
|
|
128
|
+
| envelope_stmt
|
|
129
|
+
| error_stmt
|
|
130
|
+
| fill_stmt
|
|
131
|
+
| gcol_stmt
|
|
132
|
+
| goto_stmt
|
|
133
|
+
| on_goto_stmt
|
|
134
|
+
| gosub_stmt
|
|
135
|
+
| input_stmt
|
|
136
|
+
| install_stmt
|
|
137
|
+
| if_stmt
|
|
138
|
+
| for_stmt
|
|
139
|
+
| line_stmt
|
|
140
|
+
| library_stmt
|
|
141
|
+
| let_stmt
|
|
142
|
+
| local_stmt
|
|
143
|
+
| mandel_stmt
|
|
144
|
+
| mode_stmt
|
|
145
|
+
| mouse_stmt
|
|
146
|
+
| move_stmt
|
|
147
|
+
| off_stmt
|
|
148
|
+
| on_stmt
|
|
149
|
+
| origin_stmt
|
|
150
|
+
| oscli_stmt
|
|
151
|
+
| next_stmt
|
|
152
|
+
| plot_stmt
|
|
153
|
+
| point_stmt
|
|
154
|
+
| print_stmt
|
|
155
|
+
| private_stmt
|
|
156
|
+
| proc_stmt
|
|
157
|
+
| quit_stmt
|
|
158
|
+
| read_stmt
|
|
159
|
+
| rectangle_stmt
|
|
160
|
+
| rem_stmt
|
|
161
|
+
| repeat_stmt
|
|
162
|
+
| report_stmt
|
|
163
|
+
| restore_stmt
|
|
164
|
+
| return_stmt
|
|
165
|
+
| sound_stmt
|
|
166
|
+
| stop_stmt
|
|
167
|
+
| stereo_stmt
|
|
168
|
+
| swap_stmt
|
|
169
|
+
| sys_stmt
|
|
170
|
+
| tempo_stmt
|
|
171
|
+
| tint_stmt
|
|
172
|
+
| until_stmt
|
|
173
|
+
| vdu_stmt
|
|
174
|
+
| voices_stmt
|
|
175
|
+
| while_stmt
|
|
176
|
+
| width_stmt
|
|
177
|
+
| wait_stmt
|
|
178
|
+
| endwhile_stmt
|
|
179
|
+
| run_stmt'''
|
|
180
|
+
p[0] = p[1]
|
|
181
|
+
|
|
182
|
+
def p_bput_stmt(p):
|
|
183
|
+
'''bput_stmt : BPUT channel COMMA expr
|
|
184
|
+
| BPUT channel COMMA expr SEMICOLON'''
|
|
185
|
+
if len(p) == 5:
|
|
186
|
+
p[0] = Bput(channel = p[2], data = p[4], newline=True)
|
|
187
|
+
elif len(p) == 6:
|
|
188
|
+
p[0] = Bput(channel = p[2], data = p[4], newline=False)
|
|
189
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
190
|
+
|
|
191
|
+
def p_call_stmt(p):
|
|
192
|
+
'''call_stmt : CALL expr
|
|
193
|
+
| CALL expr COMMA writable_list'''
|
|
194
|
+
if len(p) == 3:
|
|
195
|
+
p[0] = Call(address = p[2])
|
|
196
|
+
elif len(p) == 5:
|
|
197
|
+
p[0] = Call(address = p[2], parameters = p[4])
|
|
198
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
199
|
+
|
|
200
|
+
# TODO CASE stmt
|
|
201
|
+
# Not that WHEN clauses which follow the OTHERWISE clause
|
|
202
|
+
# a legal, but cannot be executed.
|
|
203
|
+
# TODO : Put this into a special class of statements which
|
|
204
|
+
# must begin on a new line.
|
|
205
|
+
def p_case_stmt(p):
|
|
206
|
+
'''case_stmt : CASE expr OF stmt_terminator when_clause_list ENDCASE'''
|
|
207
|
+
p[0] = Case(condition = p[2], whenClauses = p[5])
|
|
208
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
209
|
+
setDebuggingPositions(p)
|
|
210
|
+
|
|
211
|
+
def p_when_clause_list(p):
|
|
212
|
+
'''when_clause_list : when_clause
|
|
213
|
+
| when_clause_list when_clause'''
|
|
214
|
+
if len(p) == 2:
|
|
215
|
+
p[0] = WhenClauseList()
|
|
216
|
+
p[0].append(p[1])
|
|
217
|
+
elif len(p) == 3:
|
|
218
|
+
p[1].append(p[2])
|
|
219
|
+
p[0] = p[1]
|
|
220
|
+
|
|
221
|
+
def p_when_clause(p):
|
|
222
|
+
'''when_clause : WHEN expr_list COLON statement_list
|
|
223
|
+
| OTHERWISE statement_list'''
|
|
224
|
+
if len(p) == 5:
|
|
225
|
+
p[0] = WhenClause(matches = p[2], statements = p[4])
|
|
226
|
+
elif len(p) == 3:
|
|
227
|
+
p[0] = OtherwiseClause(statements = p[2])
|
|
228
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
229
|
+
|
|
230
|
+
def p_beats_stmt(p):
|
|
231
|
+
'''beats_stmt : BEATS expr'''
|
|
232
|
+
p[0] = Beats(counter = p[2])
|
|
233
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
234
|
+
|
|
235
|
+
def p_circle_stmt(p):
|
|
236
|
+
'''circle_stmt : CIRCLE expr COMMA expr COMMA expr
|
|
237
|
+
| CIRCLE FILL expr COMMA expr COMMA expr'''
|
|
238
|
+
if len(p) == 7:
|
|
239
|
+
p[0] = Circle(xCoord = p[2], yCoord = p[4], radius = p[6])
|
|
240
|
+
elif len(p) == 8:
|
|
241
|
+
p[0] = Circle(xCoord = p[3], yCoord = p[5], radius = p[7], fill=True)
|
|
242
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
243
|
+
|
|
244
|
+
def p_clear_stmt(p):
|
|
245
|
+
'clear_stmt : CLEAR'
|
|
246
|
+
p[0] = Clear()
|
|
247
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
248
|
+
|
|
249
|
+
def p_close_stmt(p):
|
|
250
|
+
'close_stmt : CLOSE channel'
|
|
251
|
+
p[0] = Close(channel = p[2])
|
|
252
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
253
|
+
|
|
254
|
+
def p_clg_stmt(p):
|
|
255
|
+
'clg_stmt : CLG'
|
|
256
|
+
p[0] = Clg()
|
|
257
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
258
|
+
|
|
259
|
+
def p_cls_stmt(p):
|
|
260
|
+
'cls_stmt : CLS'
|
|
261
|
+
p[0] = Cls()
|
|
262
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
263
|
+
|
|
264
|
+
def p_colour_stmt(p):
|
|
265
|
+
'''colour_stmt : COLOUR expr
|
|
266
|
+
| COLOUR expr COMMA expr
|
|
267
|
+
| COLOUR expr TINT expr
|
|
268
|
+
| COLOUR expr COMMA expr COMMA expr COMMA expr'''
|
|
269
|
+
if len(p) == 3:
|
|
270
|
+
p[0] = Colour(colour = p[2])
|
|
271
|
+
elif len(p) == 5:
|
|
272
|
+
if p[3] == "TINT":
|
|
273
|
+
p[0] = Colour(colour = p[2], tint = p[4])
|
|
274
|
+
else:
|
|
275
|
+
p[0] = Palette(logicalColour = p[2], physicalColour = p[4])
|
|
276
|
+
elif len(p) == 9:
|
|
277
|
+
p[0] = Palette(logicalColour = p[2], red = p[4], green = p[6], blue = p[8])
|
|
278
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
# DATA
|
|
282
|
+
def p_data_statement(p):
|
|
283
|
+
'data_stmt : DATA'
|
|
284
|
+
p[0] = Data(data = p[1])
|
|
285
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
286
|
+
|
|
287
|
+
# REM
|
|
288
|
+
def p_rem_statement(p):
|
|
289
|
+
'rem_stmt : COMMENT'
|
|
290
|
+
p[0] = Rem(data = p[1])
|
|
291
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
292
|
+
|
|
293
|
+
def p_def_stmt(p):
|
|
294
|
+
'''def_stmt : def_fn_stmt
|
|
295
|
+
| def_proc_stmt'''
|
|
296
|
+
p[0] = p[1]
|
|
297
|
+
|
|
298
|
+
# The statement list needs to be modified so there can be more
|
|
299
|
+
# than one point of return form functions
|
|
300
|
+
def p_def_fn_stmt(p):
|
|
301
|
+
'''def_fn_stmt : DEF FN_ID statement
|
|
302
|
+
| DEF FN_ID LPAREN formal_arg_list RPAREN statement'''
|
|
303
|
+
|
|
304
|
+
if len(p) == 4:
|
|
305
|
+
p[0] = DefineFunction(name = p[2], followingStatement = p[3])
|
|
306
|
+
end_pos = p.lexpos(2)
|
|
307
|
+
elif len(p) == 7:
|
|
308
|
+
p[0] = DefineFunction(name = p[2], formalParameters = p[4], followingStatement = p[6])
|
|
309
|
+
end_pos = p.lexpos(5)
|
|
310
|
+
|
|
311
|
+
#print "Assigning DEF PROC line numbers"
|
|
312
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
313
|
+
p[0].startLine = p.lineno(1)
|
|
314
|
+
p[0].endLine = p.lineno(1)
|
|
315
|
+
p[0].startPos = p.lexpos(1)
|
|
316
|
+
assert end_pos is not None
|
|
317
|
+
p[0].endPos = end_pos
|
|
318
|
+
|
|
319
|
+
def p_end_fn_stmt(p):
|
|
320
|
+
'''end_fn_stmt : EQ expr %prec UEQUAL'''
|
|
321
|
+
p[0] = ReturnFromFunction(returnValue = p[2])
|
|
322
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
323
|
+
|
|
324
|
+
def p_def_proc_stmt(p):
|
|
325
|
+
'''def_proc_stmt : DEF PROC_ID statement
|
|
326
|
+
| DEF PROC_ID LPAREN formal_arg_list RPAREN statement'''
|
|
327
|
+
if len(p) == 4:
|
|
328
|
+
p[0] = DefineProcedure(name = p[2], followingStatement = p[3])
|
|
329
|
+
end_pos = p.lexpos(2)
|
|
330
|
+
elif len(p) == 7:
|
|
331
|
+
p[0] = DefineProcedure(name = p[2], formalParameters = p[4], followingStatement = p[6])
|
|
332
|
+
end_pos = p.lexpos(5)
|
|
333
|
+
|
|
334
|
+
#print "Assigning DEF PROC line numbers"
|
|
335
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
336
|
+
p[0].startLine = p.lineno(1)
|
|
337
|
+
p[0].endLine = p.lineno(1)
|
|
338
|
+
p[0].startPos = p.lexpos(1)
|
|
339
|
+
assert end_pos is not None
|
|
340
|
+
p[0].endPos = end_pos
|
|
341
|
+
|
|
342
|
+
def p_endproc_stmt(p):
|
|
343
|
+
'''endproc_stmt : ENDPROC'''
|
|
344
|
+
p[0] = ReturnFromProcedure()
|
|
345
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
346
|
+
|
|
347
|
+
def p_proc_stmt(p):
|
|
348
|
+
'''proc_stmt : PROC_ID
|
|
349
|
+
| PROC_ID LPAREN actual_arg_list RPAREN'''
|
|
350
|
+
if len(p) == 2:
|
|
351
|
+
p[0] = CallProcedure(name = p[1], actualParameters = ActualArgList())
|
|
352
|
+
elif len(p) == 5:
|
|
353
|
+
p[0] = CallProcedure(name = p[1], actualParameters = p[3])
|
|
354
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
355
|
+
|
|
356
|
+
def p_dim_statement(p):
|
|
357
|
+
'''dim_stmt : DIM dim_list'''
|
|
358
|
+
p[0] = Dim(items = p[2])
|
|
359
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
360
|
+
|
|
361
|
+
def p_dim_list(p):
|
|
362
|
+
'''dim_list : dim_item
|
|
363
|
+
| dim_list COMMA dim_item'''
|
|
364
|
+
if len(p) == 2:
|
|
365
|
+
p[0] = DimList()
|
|
366
|
+
p[0].append(p[1])
|
|
367
|
+
elif len(p) == 4:
|
|
368
|
+
p[1].append(p[3])
|
|
369
|
+
p[0] = p[1]
|
|
370
|
+
|
|
371
|
+
def p_dim_item(p):
|
|
372
|
+
# TODO: BB4W structures would be added here
|
|
373
|
+
'''dim_item : indexer
|
|
374
|
+
| variable expr'''
|
|
375
|
+
if len(p) == 2:
|
|
376
|
+
p[0] = AllocateArray(identifier = p[1].identifier, dimensions = p[1].indices)
|
|
377
|
+
elif len(p) == 3:
|
|
378
|
+
p[0] = AllocateBlock(identifier = p[1], size = p[2])
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
def p_draw_stmt(p):
|
|
382
|
+
'''draw_stmt : DRAW expr COMMA expr
|
|
383
|
+
| DRAW BY expr COMMA expr'''
|
|
384
|
+
if len(p) == 5:
|
|
385
|
+
p[0] = Draw(xCoord = p[2], yCoord = p[4])
|
|
386
|
+
elif len(p) == 6:
|
|
387
|
+
p[0] = Draw(xCoord = p[3], yCoord = p[5], relative=True)
|
|
388
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
389
|
+
|
|
390
|
+
def p_end_stmt(p):
|
|
391
|
+
'''end_stmt : END'''
|
|
392
|
+
p[0] = End()
|
|
393
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
394
|
+
|
|
395
|
+
def p_ellipse_stmt(p): # BBC BASIC V also supports rotation of an ellipse
|
|
396
|
+
'''ellipse_stmt : ELLIPSE expr COMMA expr COMMA expr COMMA expr
|
|
397
|
+
| ELLIPSE FILL expr COMMA expr COMMA expr COMMA expr
|
|
398
|
+
| ELLIPSE expr COMMA expr COMMA expr COMMA expr COMMA expr
|
|
399
|
+
| ELLIPSE FILL expr COMMA expr COMMA expr COMMA expr COMMA expr'''
|
|
400
|
+
|
|
401
|
+
if len(p) == 9:
|
|
402
|
+
p[0] = Ellipse(xCoord = p[2], yCoord = p[4], semiMajor = p[6], semiMinor = p[8])
|
|
403
|
+
elif len(p) == 10:
|
|
404
|
+
p[0] = Ellipse(xCoord = p[3], yCoord = p[5], semiMajor = p[7], semiMinor = p[9], fill=True)
|
|
405
|
+
elif len(p) == 11:
|
|
406
|
+
p[0] = Ellipse(xCoord = p[2], yCoord = p[4], semiMajor = p[6], semiMinor = p[8], radians = p[10])
|
|
407
|
+
elif len(p) == 12:
|
|
408
|
+
p[0] = Ellipse(xCoord = p[3], yCoord = p[5], semiMajor = p[7], semiMinor = p[9], radians = p[11], fill=True)
|
|
409
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
def p_error_stmt(p):
|
|
413
|
+
'''error_stmt : ERROR expr COMMA expr
|
|
414
|
+
| ERROR EXT expr COMMA expr'''
|
|
415
|
+
# TODO: Needs to handle the EXT keyword for returning an external error code
|
|
416
|
+
# ERROR EXT ERR, REPORT$ : REM pass on the error
|
|
417
|
+
if len(p) == 5:
|
|
418
|
+
p[0] = GenerateError(number = p[2], description = p[4])
|
|
419
|
+
elif len(p) == 6:
|
|
420
|
+
p[0] = ReturnError(number = p[2], description = p[4])
|
|
421
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
422
|
+
|
|
423
|
+
def p_envelope_stmt(p):
|
|
424
|
+
'''envelope_stmt : ENVELOPE expr COMMA expr COMMA expr COMMA expr COMMA expr COMMA expr COMMA expr COMMA expr COMMA expr COMMA expr COMMA expr COMMA expr COMMA expr COMMA expr'''
|
|
425
|
+
p[0] = Envelope(n = p[2], t = p[4], pitch1 = p[6], pitch2 = p[8], pitch3 = p[10],
|
|
426
|
+
numSteps1 = p[12], numSteps2 = p[14], numSteps3 = p[16],
|
|
427
|
+
amplitudeAttack = p[18], amplitudeDecay = p[20], amplitudeSustain = p[22],
|
|
428
|
+
amplitudeRelease = p[24], targetAttack = p[26], targetDecay = p[28] )
|
|
429
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
430
|
+
|
|
431
|
+
def p_fill_stmt(p):
|
|
432
|
+
'''fill_stmt : FILL expr COMMA expr
|
|
433
|
+
| FILL BY expr COMMA expr'''
|
|
434
|
+
if len(p) == 5:
|
|
435
|
+
p[0] = Fill(xCoord = p[2], yCoord = p[4])
|
|
436
|
+
elif len(p) == 6:
|
|
437
|
+
p[0] = Fill(xCoord = p[3], yCoord = p[5], relative=True)
|
|
438
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
439
|
+
|
|
440
|
+
def p_gcol_stmt(p):
|
|
441
|
+
'''gcol_stmt : GCOL expr
|
|
442
|
+
| GCOL expr COMMA expr
|
|
443
|
+
| GCOL expr TINT expr
|
|
444
|
+
| GCOL expr COMMA expr TINT expr'''
|
|
445
|
+
if len(p) == 3:
|
|
446
|
+
p[0] = Gcol(mode = LiteralInteger(value = 0), logicalColour = p[2])
|
|
447
|
+
elif len(p) == 5:
|
|
448
|
+
if p[3] == 'TINT':
|
|
449
|
+
p[0] = Gcol(mode = LiteralInteger(value = 0), logicalColour = p[2], tint = p[4])
|
|
450
|
+
else:
|
|
451
|
+
p[0] = Gcol(mode = p[2], logicalColour = p[4])
|
|
452
|
+
elif len(p) == 7:
|
|
453
|
+
p[0] = Gcol(mode = p[2], logicalColour = p[4], tint = p[6])
|
|
454
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
455
|
+
|
|
456
|
+
def p_input_stmt(p):
|
|
457
|
+
'''input_stmt : INPUT
|
|
458
|
+
| INPUT input_list
|
|
459
|
+
| LINE INPUT
|
|
460
|
+
| LINE INPUT input_list
|
|
461
|
+
| INPUT LINE
|
|
462
|
+
| INPUT LINE input_list
|
|
463
|
+
| INPUT channel COMMA variable_list'''
|
|
464
|
+
# TODO: All other syntax of input to replace the second line above - see PRINT
|
|
465
|
+
if len(p) == 2:
|
|
466
|
+
#INPUT
|
|
467
|
+
p[0] = Input()
|
|
468
|
+
elif len(p) == 3:
|
|
469
|
+
if p[1] == "LINE":
|
|
470
|
+
#LINE INPUT
|
|
471
|
+
p[0] = Input(inputLine = True)
|
|
472
|
+
elif p[2] == "LINE":
|
|
473
|
+
#INPUT LINE
|
|
474
|
+
p[0] = Input(inputLine = True)
|
|
475
|
+
else:
|
|
476
|
+
#INPUT input_list
|
|
477
|
+
p[0] = Input(inputList = p[2])
|
|
478
|
+
elif len(p) == 4:
|
|
479
|
+
if p[1] == "LINE":
|
|
480
|
+
#LINE INPUT input_list
|
|
481
|
+
p[0] = Input(inputLine = True, inputList = p[3])
|
|
482
|
+
elif p[2] == "LINE":
|
|
483
|
+
#INPUT LINE input_list
|
|
484
|
+
p[0] = Input(inputLine = True, inputList = p[3])
|
|
485
|
+
elif len(p) == 5:
|
|
486
|
+
p[0] = InputFile(channel = p[2], items = p[4])
|
|
487
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
488
|
+
|
|
489
|
+
def p_input_list(p):
|
|
490
|
+
'''input_list : input_item
|
|
491
|
+
| input_list input_item'''
|
|
492
|
+
if len(p) == 2:
|
|
493
|
+
p[0] = InputList()
|
|
494
|
+
p[0].append(p[1])
|
|
495
|
+
elif len(p) == 3:
|
|
496
|
+
p[1].append(p[2])
|
|
497
|
+
p[0] = p[1]
|
|
498
|
+
|
|
499
|
+
def p_input_item(p):
|
|
500
|
+
'''input_item : literal_string
|
|
501
|
+
| tab
|
|
502
|
+
| spc
|
|
503
|
+
| input_manipulator
|
|
504
|
+
| writable'''
|
|
505
|
+
p[0] = InputItem(item = p[1])
|
|
506
|
+
|
|
507
|
+
def p_input_manipulator(p):
|
|
508
|
+
'''input_manipulator : APOSTROPHE
|
|
509
|
+
| COMMA
|
|
510
|
+
| SEMICOLON'''
|
|
511
|
+
p[0] = InputManipulator(manipulator = p[1])
|
|
512
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
def p_install_stmt(p):
|
|
519
|
+
'''install_stmt : INSTALL expr'''
|
|
520
|
+
if len(p) == 3:
|
|
521
|
+
p[0] = Install(filename = p[2])
|
|
522
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
523
|
+
|
|
524
|
+
# GOTO statement
|
|
525
|
+
def p_goto_stmt(p):
|
|
526
|
+
'''goto_stmt : GOTO factor'''
|
|
527
|
+
p[0] = Goto(targetLogicalLine = p[2])
|
|
528
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
529
|
+
|
|
530
|
+
def p_on_goto_stmt(p):
|
|
531
|
+
'''on_goto_stmt : ON expr GOTO expr_list
|
|
532
|
+
| ON expr GOTO expr_list ELSE multi_statement'''
|
|
533
|
+
# TODO ELSE clause
|
|
534
|
+
if len(p) == 5:
|
|
535
|
+
p[0] = OnGoto(switch = p[2], targetLogicalLines = p[4])
|
|
536
|
+
elif len(p) == 7:
|
|
537
|
+
p[0] = OnGoto(switch = p[2], targetLogicalLines = p[4], outOfRangeClause = p[6])
|
|
538
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
539
|
+
|
|
540
|
+
# GOSUB statement
|
|
541
|
+
def p_gosub(p):
|
|
542
|
+
'''gosub_stmt : GOSUB factor'''
|
|
543
|
+
p[0] = Gosub(targetLogicalLine = p[2])
|
|
544
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
545
|
+
|
|
546
|
+
def p_return_stmt(p):
|
|
547
|
+
'''return_stmt : RETURN'''
|
|
548
|
+
p[0] = Return()
|
|
549
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
550
|
+
|
|
551
|
+
def p_if_stmt(p):
|
|
552
|
+
#'''if_stmt : if_single_stmt'''
|
|
553
|
+
'''if_stmt : if_single_stmt
|
|
554
|
+
| if_multi_stmt'''
|
|
555
|
+
p[0] = p[1]
|
|
556
|
+
|
|
557
|
+
def p_if_single_stmt(p):
|
|
558
|
+
'''if_single_stmt : IF expr clause
|
|
559
|
+
| IF expr THEN clause
|
|
560
|
+
| IF expr clause ELSE clause
|
|
561
|
+
| IF expr THEN clause ELSE clause'''
|
|
562
|
+
|
|
563
|
+
# Specialised debugging lexer positions set in here
|
|
564
|
+
if len(p) == 4:
|
|
565
|
+
p[0] = If(condition = p[2], trueClause = p[3])
|
|
566
|
+
end_pos = p.lexpos(3)
|
|
567
|
+
elif len(p) == 5:
|
|
568
|
+
p[0] = If(condition = p[2], trueClause = p[4])
|
|
569
|
+
end_pos = p.lexpos(4)
|
|
570
|
+
elif len(p) == 6:
|
|
571
|
+
p[0] = If(condition = p[2], trueClause = p[3], falseClause = p[5])
|
|
572
|
+
end_pos = p.lexpos(3)
|
|
573
|
+
elif len(p) == 7:
|
|
574
|
+
p[0] = If(condition = p[2], trueClause = p[4], falseClause = p[6])
|
|
575
|
+
end_pos = p.lexpos(4)
|
|
576
|
+
|
|
577
|
+
#print "Assigning IF line numbers"
|
|
578
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
579
|
+
p[0].startLine = p.lineno(1)
|
|
580
|
+
p[0].endLine = p.lineno(1)
|
|
581
|
+
p[0].startPos = p.lexpos(1)
|
|
582
|
+
assert end_pos is not None
|
|
583
|
+
p[0].endPos = end_pos
|
|
584
|
+
|
|
585
|
+
# The clause is only used with IF statements and
|
|
586
|
+
# possible ON statements when the result of an expression
|
|
587
|
+
# is interpreted as a line number to GOTO
|
|
588
|
+
def p_clause(p):
|
|
589
|
+
'''clause : multi_statement
|
|
590
|
+
| implicit_goto'''
|
|
591
|
+
p[0] = p[1]
|
|
592
|
+
|
|
593
|
+
def p_implicit_goto(p):
|
|
594
|
+
'''implicit_goto : factor'''
|
|
595
|
+
stmt_list = StatementList()
|
|
596
|
+
goto = Goto(targetLogicalLine = p[1])
|
|
597
|
+
goto.lineNum = p.lineno(1) - 1
|
|
598
|
+
goto.startLine = p.lineno(1)
|
|
599
|
+
goto.endLine = p.lineno(1)
|
|
600
|
+
goto.startPos = p.lexpos(1)
|
|
601
|
+
goto.endPos = p.lexpos(1)
|
|
602
|
+
stmt_list.append(goto)
|
|
603
|
+
p[0] = stmt_list
|
|
604
|
+
|
|
605
|
+
def p_if_multi_stmt(p):
|
|
606
|
+
'''if_multi_stmt : IF expr THEN statement_list ENDIF
|
|
607
|
+
| IF expr THEN statement_list ELSE statement_list ENDIF'''
|
|
608
|
+
if len(p) == 6:
|
|
609
|
+
p[0] = If(condition = p[2], trueClause = p[4])
|
|
610
|
+
elif len(p) == 8:
|
|
611
|
+
p[0] = If(condition = p[2], trueClause = p[4], falseClause = p[6])
|
|
612
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
613
|
+
|
|
614
|
+
# The syntax rules for FOR..NEXT loops are not implemented by the
|
|
615
|
+
# grammar owing to the fact that NEXT is treated as a statement,
|
|
616
|
+
# rather than as a loop terminator. A later analysis of the parse
|
|
617
|
+
# tree will attempt to match each NEXT with its corresponding FOR
|
|
618
|
+
def p_for_stmt(p):
|
|
619
|
+
'''for_stmt : FOR writable EQ expr TO expr
|
|
620
|
+
| FOR writable EQ expr TO expr STEP expr'''
|
|
621
|
+
if len(p) == 7:
|
|
622
|
+
p[0] = ForToStep(identifier = p[2], first = p[4], last = p[6], step = LiteralInteger(value = 1))
|
|
623
|
+
elif len(p) == 9:
|
|
624
|
+
p[0] = ForToStep(identifier = p[2], first = p[4], last = p[6], step = p[8])
|
|
625
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
626
|
+
|
|
627
|
+
# Rule for dealing with unmatched NEXT statements
|
|
628
|
+
def p_next_stmt(p):
|
|
629
|
+
'''next_stmt : NEXT nullable_variable_list'''
|
|
630
|
+
p[0] = Next(identifiers = p[2])
|
|
631
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
632
|
+
|
|
633
|
+
def p_library_stmt(p):
|
|
634
|
+
'''library_stmt : LIBRARY expr'''
|
|
635
|
+
p[0] = LoadLibrary(filename = p[2])
|
|
636
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
637
|
+
|
|
638
|
+
def p_line_stmt(p):
|
|
639
|
+
'''line_stmt : LINE expr COMMA expr COMMA expr COMMA expr'''
|
|
640
|
+
|
|
641
|
+
# TODO: Sort this lot out!
|
|
642
|
+
p[0] = Line(x1Coord = p[2], y1Coord = p[4], x2Coord = p[6], y2Coord = p[8])
|
|
643
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
644
|
+
|
|
645
|
+
def p_let_stmt(p):
|
|
646
|
+
'''let_stmt : let_assignment
|
|
647
|
+
| increment
|
|
648
|
+
| decrement'''
|
|
649
|
+
p[0] = p[1]
|
|
650
|
+
|
|
651
|
+
def p_let_assignment(p):
|
|
652
|
+
'''let_assignment : LET assignment
|
|
653
|
+
| assignment'''
|
|
654
|
+
if len(p) == 3:
|
|
655
|
+
p[0] = p[2]
|
|
656
|
+
elif len(p) == 2:
|
|
657
|
+
p[0] = p[1]
|
|
658
|
+
|
|
659
|
+
def p_assignment(p):
|
|
660
|
+
'''assignment : scalar_assignment
|
|
661
|
+
| array_assignment'''
|
|
662
|
+
p[0] = p[1]
|
|
663
|
+
|
|
664
|
+
def p_scalar_assignment(p):
|
|
665
|
+
'''scalar_assignment : lvalue EQ expr'''
|
|
666
|
+
p[0] = ScalarAssignment(lValue = p[1], rValue = p[3])
|
|
667
|
+
p[0].lineNum = p.lineno(2) - 1
|
|
668
|
+
|
|
669
|
+
def p_array_assignment(p):
|
|
670
|
+
'''array_assignment : array EQ expr_list'''
|
|
671
|
+
p[0] = ArrayAssignment(lValue = p[1], rValue = p[3])
|
|
672
|
+
p[0].lineNum = p.lineno(2) - 1
|
|
673
|
+
|
|
674
|
+
def p_increment(p):
|
|
675
|
+
'''increment : lvalue PLUS_ASSIGN expr
|
|
676
|
+
| array PLUS_ASSIGN expr'''
|
|
677
|
+
if len(p) == 4:
|
|
678
|
+
p[0] = Increment(lValue = p[1], rValue = p[3])
|
|
679
|
+
p[0].lineNum = p.lineno(2) - 1
|
|
680
|
+
|
|
681
|
+
def p_decrement(p):
|
|
682
|
+
'''decrement : lvalue MINUS_ASSIGN expr
|
|
683
|
+
| array MINUS_ASSIGN expr'''
|
|
684
|
+
if len(p) == 4:
|
|
685
|
+
p[0] = Decrement(lValue = p[1], rValue = p[3])
|
|
686
|
+
p[0].lineNum = p.lineno(2) - 1
|
|
687
|
+
|
|
688
|
+
# LOCAL statement
|
|
689
|
+
def p_local_stmt(p):
|
|
690
|
+
'''local_stmt : LOCAL variable_list'''
|
|
691
|
+
p[0] = Local(variables = p[2])
|
|
692
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
693
|
+
|
|
694
|
+
# MANDEL statement
|
|
695
|
+
def p_mandel_stmt(p):
|
|
696
|
+
'''mandel_stmt : MANDEL expr COMMA expr'''
|
|
697
|
+
p[0] = Mandel(iCoord = p[2], jCoord = p[4])
|
|
698
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
699
|
+
|
|
700
|
+
# MOVE statement
|
|
701
|
+
def p_move_stmt(p):
|
|
702
|
+
'''move_stmt : MOVE expr COMMA expr
|
|
703
|
+
| MOVE BY expr COMMA expr'''
|
|
704
|
+
if len(p) == 5:
|
|
705
|
+
p[0] = Move(xCoord = p[2], yCoord = p[4])
|
|
706
|
+
elif len(p) == 6:
|
|
707
|
+
p[0] = Move(xCoord = p[3], yCoord = p[5], relative=True)
|
|
708
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
709
|
+
|
|
710
|
+
def p_mode_stmt(p):
|
|
711
|
+
'''mode_stmt : MODE expr
|
|
712
|
+
| MODE expr COMMA expr COMMA expr
|
|
713
|
+
| MODE expr COMMA expr COMMA expr COMMA expr'''
|
|
714
|
+
if len(p) == 3:
|
|
715
|
+
p[0] = Mode(number = p[2])
|
|
716
|
+
elif len(p) == 7:
|
|
717
|
+
p[0] = Mode(width = p[2], height = p[4], bitsPerPixel = p[6])
|
|
718
|
+
elif len(p) == 9:
|
|
719
|
+
p[0] = Mode(width = p[2], height = p[4], bitsPerPixel = p[6], frameRate = p[8])
|
|
720
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
721
|
+
|
|
722
|
+
|
|
723
|
+
def p_mouse_stmt(p):
|
|
724
|
+
'''mouse_stmt : MOUSE writable COMMA writable COMMA writable
|
|
725
|
+
| MOUSE writable COMMA writable COMMA writable COMMA writable
|
|
726
|
+
| MOUSE ON
|
|
727
|
+
| MOUSE ON expr
|
|
728
|
+
| MOUSE OFF
|
|
729
|
+
| MOUSE TO expr COMMA expr
|
|
730
|
+
| MOUSE RECTANGLE expr COMMA expr COMMA expr COMMA expr
|
|
731
|
+
| MOUSE RECTANGLE OFF
|
|
732
|
+
| MOUSE STEP expr
|
|
733
|
+
| MOUSE STEP expr COMMA expr
|
|
734
|
+
| MOUSE COLOUR expr COMMA expr COMMA expr COMMA expr'''
|
|
735
|
+
#nested IF is to see that the p[2] contains
|
|
736
|
+
if str(p[2]) == 'ON':
|
|
737
|
+
if len(p) == 3:
|
|
738
|
+
#MOUSE ON
|
|
739
|
+
p[0] = MousePointer(shape =LiteralInteger(value = 0))
|
|
740
|
+
elif len(p) == 4:
|
|
741
|
+
#MOUSE ON expr
|
|
742
|
+
p[0] = MousePointer(shape =p[3])
|
|
743
|
+
elif str(p[2]) == 'OFF':
|
|
744
|
+
#MOUSE OFF
|
|
745
|
+
p[0] = MousePointer(shape =None)
|
|
746
|
+
elif str(p[2]) == 'TO':
|
|
747
|
+
#MOUSE TO
|
|
748
|
+
p[0] = MousePosition(xCoord = p[3], yCoord = p[5])
|
|
749
|
+
elif str(p[2]) == 'RECTANGLE':
|
|
750
|
+
if len(p) == 10:
|
|
751
|
+
#MOUSE RECTANGLE
|
|
752
|
+
p[0] = MouseRectangleOn(left = p[3], bottom = p[5], right = p[7], top = p[9])
|
|
753
|
+
elif len(p) == 4:
|
|
754
|
+
#MOUSE RECTANGLE OFF
|
|
755
|
+
p[0] = MouseRectangleOff()
|
|
756
|
+
elif str(p[2]) == 'STEP':
|
|
757
|
+
if len(p) == 4:
|
|
758
|
+
#MOUSE STEP expr
|
|
759
|
+
p[0] = MouseStep(xCoeff = p[3])
|
|
760
|
+
if len(p) == 6:
|
|
761
|
+
#MOUSE STEP expr COMMA expr
|
|
762
|
+
p[0] = MouseStep(xCoeff = p[3], yCoeff = p[5])
|
|
763
|
+
elif str(p[2]) == 'COLOUR': #Not sure if i need to check for COLOR
|
|
764
|
+
#MOUSE COLOUR expr COMMA expr COMMA expr COMMA expr
|
|
765
|
+
p[0] = MouseColour(logicalColour = p[3], red = p[5], green = p[7], blue = p[9])
|
|
766
|
+
else:
|
|
767
|
+
if len(p) == 7:
|
|
768
|
+
#MOUSE variable COMMA variable COMMA variable
|
|
769
|
+
p[0] = Mouse(xCoord = p[2], yCoord = p[4], buttons = p[6])
|
|
770
|
+
elif len(p) == 9:
|
|
771
|
+
#MOUSE variable COMMA variable COMMA variable COMMA variable
|
|
772
|
+
p[0] = Mouse(xCoord = p[2], yCoord = p[4], buttons = p[6], time = p[8])
|
|
773
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
774
|
+
|
|
775
|
+
|
|
776
|
+
def p_on_stmt(p):
|
|
777
|
+
'''on_stmt : ON'''
|
|
778
|
+
p[0] = On()
|
|
779
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
780
|
+
|
|
781
|
+
def p_off_stmt(p):
|
|
782
|
+
'''off_stmt : OFF'''
|
|
783
|
+
p[0] = Off()
|
|
784
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
785
|
+
|
|
786
|
+
def p_origin_stmt(p):
|
|
787
|
+
'''origin_stmt : ORIGIN expr COMMA expr'''
|
|
788
|
+
p[0] = Origin(xCoord = p[2], yCoord = p[4])
|
|
789
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
790
|
+
|
|
791
|
+
def p_oscli_stmt(p):
|
|
792
|
+
'''oscli_stmt : OSCLI expr'''
|
|
793
|
+
p[0] = Oscli(command = p[2])
|
|
794
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
795
|
+
|
|
796
|
+
def p_plot_stmt(p):
|
|
797
|
+
'''plot_stmt : PLOT expr COMMA expr
|
|
798
|
+
| PLOT expr COMMA expr COMMA expr
|
|
799
|
+
| PLOT BY expr COMMA expr'''
|
|
800
|
+
if len(p) == 5:
|
|
801
|
+
p[0] = Plot(mode = LiteralInteger(value=65), xCoord = p[2], yCoord = p[4])
|
|
802
|
+
elif len(p) == 6:
|
|
803
|
+
p[0] = Plot(mode = LiteralInteger(value=65), xCoord = p[3], yCoord = p[5], relative=True)
|
|
804
|
+
elif len(p) == 7:
|
|
805
|
+
p[0] = Plot(mode = p[4], xCoord = p[6], yCoord = p[2])
|
|
806
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
807
|
+
|
|
808
|
+
def p_point_stmt(p):
|
|
809
|
+
'''point_stmt : POINT expr COMMA expr
|
|
810
|
+
| POINT BY expr COMMA expr
|
|
811
|
+
| POINT TO expr COMMA expr'''
|
|
812
|
+
if len(p) == 5:
|
|
813
|
+
p[0] = Point(xCoord = p[2], yCoord = p[4])
|
|
814
|
+
elif len(p) == 6:
|
|
815
|
+
if str(p[2]) == 'BY':
|
|
816
|
+
p[0] = Point(xCoord = p[3], yCoord = p[5], relative=True)
|
|
817
|
+
else:
|
|
818
|
+
p[0] = MousePosition(xCoord = p[3], yCoord = p[5], moveMouse=False, movePointer = True)
|
|
819
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
820
|
+
|
|
821
|
+
def p_print_stmt(p):
|
|
822
|
+
'''print_stmt : PRINT
|
|
823
|
+
| PRINT print_list
|
|
824
|
+
| PRINT channel COMMA actual_arg_list'''
|
|
825
|
+
if len(p) == 2:
|
|
826
|
+
p[0] = Print()
|
|
827
|
+
elif len(p) == 3:
|
|
828
|
+
p[0] = Print(printList = p[2])
|
|
829
|
+
elif len(p) == 4:
|
|
830
|
+
p[0] = PrintFile(channel = p[2], items = p[3])
|
|
831
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
832
|
+
|
|
833
|
+
def p_print_list(p):
|
|
834
|
+
'''print_list : print_item
|
|
835
|
+
| print_list print_item'''
|
|
836
|
+
if len(p) == 2:
|
|
837
|
+
p[0] = PrintList()
|
|
838
|
+
p[0].append(p[1])
|
|
839
|
+
elif len(p) == 3:
|
|
840
|
+
p[1].append(p[2])
|
|
841
|
+
p[0] = p[1]
|
|
842
|
+
|
|
843
|
+
def p_print_item(p):
|
|
844
|
+
'''print_item : expr
|
|
845
|
+
| tab
|
|
846
|
+
| spc
|
|
847
|
+
| format_manipulator'''
|
|
848
|
+
p[0] = PrintItem(item = p[1])
|
|
849
|
+
|
|
850
|
+
def p_format_manipulator(p):
|
|
851
|
+
'''format_manipulator : TILDE
|
|
852
|
+
| APOSTROPHE
|
|
853
|
+
| COMMA
|
|
854
|
+
| SEMICOLON'''
|
|
855
|
+
p[0] = FormatManipulator(manipulator = p[1])
|
|
856
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
857
|
+
|
|
858
|
+
# PRIVATE statement
|
|
859
|
+
def p_private_stmt(p):
|
|
860
|
+
'''private_stmt : PRIVATE variable_list'''
|
|
861
|
+
p[0] = Private(variables = p[2])
|
|
862
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
863
|
+
|
|
864
|
+
def p_quit_stmt(p):
|
|
865
|
+
# TODO: BBC BASIC on the Iyonix supports a parameter to QUIT
|
|
866
|
+
'''quit_stmt : QUIT'''
|
|
867
|
+
p[0] = Quit()
|
|
868
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
869
|
+
|
|
870
|
+
def p_read(p):
|
|
871
|
+
'''read_stmt : READ
|
|
872
|
+
| READ writable_list'''
|
|
873
|
+
if len(p) == 2:
|
|
874
|
+
p[0] = Read()
|
|
875
|
+
elif len(p) == 3:
|
|
876
|
+
p[0] = Read(writables = p[2])
|
|
877
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
878
|
+
|
|
879
|
+
def p_rectangle_stmt(p):
|
|
880
|
+
'''rectangle_stmt : RECTANGLE expr COMMA expr COMMA expr
|
|
881
|
+
| RECTANGLE expr COMMA expr COMMA expr COMMA expr
|
|
882
|
+
| RECTANGLE expr COMMA expr COMMA expr TO expr COMMA expr
|
|
883
|
+
| RECTANGLE expr COMMA expr COMMA expr COMMA expr TO expr COMMA expr
|
|
884
|
+
| RECTANGLE FILL expr COMMA expr COMMA expr
|
|
885
|
+
| RECTANGLE FILL expr COMMA expr COMMA expr COMMA expr
|
|
886
|
+
| RECTANGLE FILL expr COMMA expr COMMA expr TO expr COMMA expr
|
|
887
|
+
| RECTANGLE FILL expr COMMA expr COMMA expr COMMA expr TO expr COMMA expr
|
|
888
|
+
| RECTANGLE SWAP expr COMMA expr COMMA expr TO expr COMMA expr
|
|
889
|
+
| RECTANGLE SWAP expr COMMA expr COMMA expr COMMA expr TO expr COMMA expr'''
|
|
890
|
+
|
|
891
|
+
# TODO: Sort this lot out!
|
|
892
|
+
if len(p) == 7:
|
|
893
|
+
# RECTANGLE expr COMMA expr COMMA expr
|
|
894
|
+
p[0] = Rectangle(xCoord = p[2], yCoord = p[4], width = p[6])
|
|
895
|
+
elif len(p) == 9:
|
|
896
|
+
# RECTANGLE expr COMMA expr COMMA expr COMMA expr
|
|
897
|
+
p[0] = Rectangle(xCoord = p[2], yCoord = p[4], width = p[6], height = p[8])
|
|
898
|
+
elif len(p) == 11:
|
|
899
|
+
# RECTANGLE expr COMMA expr COMMA expr TO expr COMMA expr
|
|
900
|
+
p[0] = CopyRectangle(xCoordSource = p[2], yCoordSource = p[4], width = p[6], xCoordTarget = p[8], yCoordTarget = p[10])
|
|
901
|
+
elif len(p) == 13:
|
|
902
|
+
# RECTANGLE expr COMMA expr COMMA expr COMMA expr TO expr COMMA expr
|
|
903
|
+
p[0] = CopyRectangle(xCoordSource = p[2], yCoordSource = p[4], width = p[6], height = p[8], xCoordTarget = p[10], yCoordTarget = p[12])
|
|
904
|
+
elif len(p) == 8:
|
|
905
|
+
# RECTANGLE FILL expr COMMA expr COMMA expr
|
|
906
|
+
p[0] = Rectangle(xCoord = p[3], yCoord = p[5], width = p[7], fill=True)
|
|
907
|
+
elif len(p) == 10:
|
|
908
|
+
# RECTANGLE FILL expr COMMA expr COMMA expr COMMA expr
|
|
909
|
+
p[0] = Rectangle(xCoord = p[3], yCoord = p[5], width = p[7], height = p[9], fill=True)
|
|
910
|
+
elif len(p) == 12:
|
|
911
|
+
if str(p[2]) == "FILL":
|
|
912
|
+
# RECTANGLE FILL expr COMMA expr COMMA expr TO expr COMMA expr
|
|
913
|
+
p[0] = MoveRectangle(xCoordSource = p[3], yCoordSource = p[5], width = p[7], xCoordTarget = p[9], yCoordTarget = p[11])
|
|
914
|
+
elif str(p[2]) == "SWAP":
|
|
915
|
+
# RECTANGLE SWAP expr COMMA expr COMMA expr TO expr COMMA expr
|
|
916
|
+
p[0] = SwapRectangle(xCoordSource = p[3], yCoordSource = p[5], width = p[7], xCoordTarget = p[9], yCoordTarget = p[11])
|
|
917
|
+
elif len(p) == 14:
|
|
918
|
+
if str(p[2]) == "FILL":
|
|
919
|
+
# RECTANGLE FILL expr COMMA expr COMMA expr COMMA expr TO expr COMMA expr
|
|
920
|
+
p[0] = MoveRectangle(xCoordSource = p[3], yCoordSource = p[5], width = p[7], height = p[9], xCoordTarget = p[11], yCoordTarget = p[13])
|
|
921
|
+
elif str(p[2]) == "SWAP":
|
|
922
|
+
# RECTANGLE SWAP expr COMMA expr COMMA expr COMMA expr TO expr COMMA expr
|
|
923
|
+
p[0] = SwapRectangle(xCoordSource = p[3], yCoordSource = p[5], width = p[7], height = p[9], xCoordTarget = p[11], yCoordTarget = p[13])
|
|
924
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
925
|
+
|
|
926
|
+
def p_report_stmt(p):
|
|
927
|
+
'''report_stmt : REPORT'''
|
|
928
|
+
p[0] = Report()
|
|
929
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
930
|
+
|
|
931
|
+
def p_repeat_stmt(p):
|
|
932
|
+
'''repeat_stmt : REPEAT statement'''
|
|
933
|
+
p[0] = Repeat(followingStatement = p[2])
|
|
934
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
935
|
+
|
|
936
|
+
def p_restore_stmt(p):
|
|
937
|
+
'''restore_stmt : RESTORE
|
|
938
|
+
| RESTORE expr'''
|
|
939
|
+
# TODO restore data
|
|
940
|
+
# TODO restore + expr
|
|
941
|
+
if len(p) == 2:
|
|
942
|
+
p[0] = Restore()
|
|
943
|
+
elif len(p) == 3:
|
|
944
|
+
p[0] = Restore(targetLogicalLine = p[2])
|
|
945
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
946
|
+
|
|
947
|
+
|
|
948
|
+
def p_sound_stmt(p):
|
|
949
|
+
'''sound_stmt : SOUND expr COMMA expr COMMA expr COMMA expr
|
|
950
|
+
| SOUND ON
|
|
951
|
+
| SOUND OFF'''
|
|
952
|
+
if len(p) == 9:
|
|
953
|
+
p[0] = Sound(channel = p[2], amplitude = p[4], pitch = p[6], duration = p[8])
|
|
954
|
+
elif len(p) == 3:
|
|
955
|
+
if str(p[2]) == 'OFF':
|
|
956
|
+
p[0] = Mute(mute=True)
|
|
957
|
+
else:
|
|
958
|
+
p[0] = Mute(mute=False)
|
|
959
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
960
|
+
|
|
961
|
+
def p_stereo_stmt(p):
|
|
962
|
+
'''stereo_stmt : STEREO expr COMMA expr'''
|
|
963
|
+
p[0] = Stereo(channel = p[2], position = p[4])
|
|
964
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
965
|
+
|
|
966
|
+
def p_swap_stmt(p):
|
|
967
|
+
'''swap_stmt : SWAP writable COMMA writable
|
|
968
|
+
| SWAP array COMMA array'''
|
|
969
|
+
#SWAP var1 COMMA var2
|
|
970
|
+
#SWAP array1 COMMA array2
|
|
971
|
+
p[0] = Swap(identifier1 = p[2], identifier2 = p[4])
|
|
972
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
973
|
+
|
|
974
|
+
def p_sys_stmt(p):
|
|
975
|
+
'''sys_stmt : SYS expr
|
|
976
|
+
| SYS expr SEMICOLON writable
|
|
977
|
+
| SYS expr TO nullable_writable_list
|
|
978
|
+
| SYS expr COMMA nullable_expr_list
|
|
979
|
+
| SYS expr TO nullable_writable_list SEMICOLON writable
|
|
980
|
+
| SYS expr COMMA nullable_expr_list SEMICOLON writable
|
|
981
|
+
| SYS expr COMMA nullable_expr_list TO nullable_writable_list
|
|
982
|
+
| SYS expr COMMA nullable_expr_list TO nullable_writable_list SEMICOLON writable'''
|
|
983
|
+
if len(p) == 3:
|
|
984
|
+
p[0] = Sys(routine = p[2])
|
|
985
|
+
elif len(p) == 5:
|
|
986
|
+
if str(p[3]) == ';': # TODO D.R.Y. Get this from the token somehow
|
|
987
|
+
p[0] = Sys(routine = p[2], flags = p[4])
|
|
988
|
+
elif str(p[3]) == "TO":
|
|
989
|
+
p[0] = Sys(routine = p[2], returnValues = p[4])
|
|
990
|
+
elif str(p[3]) == ',':
|
|
991
|
+
p[0] = Sys(routine = p[2], actualParameters = p[4])
|
|
992
|
+
elif len(p) == 7:
|
|
993
|
+
if str(p[3]) == "TO":
|
|
994
|
+
p[0] = Sys(routine = p[2], returnValues = p[4], flags = p[6])
|
|
995
|
+
elif str(p[3]) == ',':
|
|
996
|
+
if str(p[5]) == ';':
|
|
997
|
+
p[0] = Sys(routine = p[2], actualParameters = p[4], flags = p[6])
|
|
998
|
+
elif str(p[5]) == "TO":
|
|
999
|
+
p[0] = Sys(routine = p[2], actualParameters = p[4], returnValues = p[6])
|
|
1000
|
+
elif len(p) == 9:
|
|
1001
|
+
p[0] = Sys(routine = p[2], actualParameters = p[4], returnValues = p[6], flags = p[8])
|
|
1002
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1003
|
+
|
|
1004
|
+
def p_tab(p):
|
|
1005
|
+
'''tab : TAB_LPAREN expr RPAREN
|
|
1006
|
+
| TAB_LPAREN expr COMMA expr RPAREN'''
|
|
1007
|
+
if len(p) == 4:
|
|
1008
|
+
p[0] = TabH(xCoord = p[2])
|
|
1009
|
+
elif len(p) == 6:
|
|
1010
|
+
p[0] = TabXY(xCoord = p[2], yCoord = p[4])
|
|
1011
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1012
|
+
|
|
1013
|
+
def p_tempo_stmt(p):
|
|
1014
|
+
'''tempo_stmt : TEMPO expr'''
|
|
1015
|
+
if len(p) == 3:
|
|
1016
|
+
#TEMPO expression
|
|
1017
|
+
p[0] = Tempo(rate = p[2])
|
|
1018
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1019
|
+
|
|
1020
|
+
def p_tint_stmt(p):
|
|
1021
|
+
'''tint_stmt : TINT expr COMMA expr'''
|
|
1022
|
+
p[0] = Tint(option = p[3], tint = p[5])
|
|
1023
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1024
|
+
|
|
1025
|
+
def p_stop_stmt(p):
|
|
1026
|
+
'''stop_stmt : STOP'''
|
|
1027
|
+
p[0] = Stop()
|
|
1028
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1029
|
+
|
|
1030
|
+
def p_spc(p):
|
|
1031
|
+
'''spc : SPC expr'''
|
|
1032
|
+
p[0] = Spc(spaces = p[2])
|
|
1033
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1034
|
+
|
|
1035
|
+
def p_until_stmt(p):
|
|
1036
|
+
'''until_stmt : UNTIL expr'''
|
|
1037
|
+
p[0] = Until(condition = p[2])
|
|
1038
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1039
|
+
|
|
1040
|
+
# VDU
|
|
1041
|
+
def p_vdu_stmt(p):
|
|
1042
|
+
'''vdu_stmt : VDU
|
|
1043
|
+
| VDU vdu_list'''
|
|
1044
|
+
if len(p) == 2:
|
|
1045
|
+
p[0] = Vdu()
|
|
1046
|
+
elif len(p) == 3:
|
|
1047
|
+
p[0] = Vdu(bytes = p[2])
|
|
1048
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1049
|
+
|
|
1050
|
+
def p_vdu_list(p):
|
|
1051
|
+
'''vdu_list : vdu_item
|
|
1052
|
+
| vdu_list vdu_item'''
|
|
1053
|
+
if len(p) == 2:
|
|
1054
|
+
p[0] = VduList()
|
|
1055
|
+
p[0].append(p[1])
|
|
1056
|
+
elif len(p) == 3:
|
|
1057
|
+
p[1].append(p[2])
|
|
1058
|
+
p[0] = p[1]
|
|
1059
|
+
|
|
1060
|
+
def p_vdu_item(p):
|
|
1061
|
+
'''vdu_item : expr vdu_separator
|
|
1062
|
+
| expr'''
|
|
1063
|
+
if len(p) == 2:
|
|
1064
|
+
p[0] = VduItem(item = p[1])
|
|
1065
|
+
elif len(p) == 3:
|
|
1066
|
+
p[0] = VduItem(item = p[1], length = p[2])
|
|
1067
|
+
|
|
1068
|
+
def p_vdu_separator(p):
|
|
1069
|
+
'''vdu_separator : COMMA
|
|
1070
|
+
| SEMICOLON
|
|
1071
|
+
| PIPE'''
|
|
1072
|
+
if p[1] == ',':
|
|
1073
|
+
p[0] = 1
|
|
1074
|
+
elif p[1] == ';':
|
|
1075
|
+
p[0] = 2
|
|
1076
|
+
elif p[1] == '|':
|
|
1077
|
+
p[0] = 9
|
|
1078
|
+
|
|
1079
|
+
def p_voices_stmt(p):
|
|
1080
|
+
'''voices_stmt : VOICES expr'''
|
|
1081
|
+
#VOICES expression
|
|
1082
|
+
p[0] = Voices(numberOfVoices = p[2])
|
|
1083
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1084
|
+
|
|
1085
|
+
def p_while_stmt(p):
|
|
1086
|
+
'''while_stmt : WHILE expr'''
|
|
1087
|
+
p[0] = While(condition = p[2])
|
|
1088
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1089
|
+
|
|
1090
|
+
def p_endwhile_stmt(p):
|
|
1091
|
+
'''endwhile_stmt : ENDWHILE'''
|
|
1092
|
+
p[0] = Endwhile()
|
|
1093
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1094
|
+
|
|
1095
|
+
def p_width_stmt(p):
|
|
1096
|
+
'''width_stmt : WIDTH expr'''
|
|
1097
|
+
p[0] = Width(lineWidth = p[2])
|
|
1098
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1099
|
+
|
|
1100
|
+
def p_wait_stmt(p):
|
|
1101
|
+
'''wait_stmt : WAIT
|
|
1102
|
+
| WAIT expr'''
|
|
1103
|
+
if len(p) == 2:
|
|
1104
|
+
#WAIT
|
|
1105
|
+
p[0] = Wait()
|
|
1106
|
+
elif len(p) == 3:
|
|
1107
|
+
#WAIT expr
|
|
1108
|
+
p[0] = Wait(centiseconds = p[2])
|
|
1109
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1110
|
+
|
|
1111
|
+
def p_run_stmt(p):
|
|
1112
|
+
'''run_stmt : RUN'''
|
|
1113
|
+
p[0] = Run()
|
|
1114
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1115
|
+
|
|
1116
|
+
#=============================================================================#
|
|
1117
|
+
# ARGUMENTS
|
|
1118
|
+
#
|
|
1119
|
+
|
|
1120
|
+
def p_actual_arg_list(p):
|
|
1121
|
+
'''actual_arg_list : actual_arg
|
|
1122
|
+
| actual_arg_list COMMA actual_arg'''
|
|
1123
|
+
if len(p) == 2:
|
|
1124
|
+
p[0] = ActualArgList()
|
|
1125
|
+
p[0].append(p[1])
|
|
1126
|
+
if len(p) == 4:
|
|
1127
|
+
p[1].append(p[3])
|
|
1128
|
+
p[0] = p[1]
|
|
1129
|
+
p[0].lineNum = p.lineno(2) - 1
|
|
1130
|
+
|
|
1131
|
+
def p_actual_arg(p):
|
|
1132
|
+
'''actual_arg : expr'''
|
|
1133
|
+
p[0] = p[1]
|
|
1134
|
+
|
|
1135
|
+
def p_formal_arg_list(p):
|
|
1136
|
+
'''formal_arg_list : formal_arg
|
|
1137
|
+
| formal_arg_list COMMA formal_arg'''
|
|
1138
|
+
if len(p) == 2:
|
|
1139
|
+
p[0] = FormalArgList()
|
|
1140
|
+
p[0].append(p[1])
|
|
1141
|
+
if len(p) == 4:
|
|
1142
|
+
p[1].append(p[3])
|
|
1143
|
+
p[0] = p[1]
|
|
1144
|
+
|
|
1145
|
+
def p_formal_arg(p):
|
|
1146
|
+
'''formal_arg : variable
|
|
1147
|
+
| array
|
|
1148
|
+
| RETURN variable
|
|
1149
|
+
| RETURN array'''
|
|
1150
|
+
if len(p) == 2:
|
|
1151
|
+
p[0] = FormalArgument(argument = p[1])
|
|
1152
|
+
elif len(p) == 3:
|
|
1153
|
+
p[0] = FormalReferenceArgument(argument = p[2])
|
|
1154
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1155
|
+
|
|
1156
|
+
#=============================================================================#
|
|
1157
|
+
# FACTORS and EXPRESSIONS
|
|
1158
|
+
#
|
|
1159
|
+
|
|
1160
|
+
# TODO: Removed indexer from factor temporarily
|
|
1161
|
+
def p_factor(p):
|
|
1162
|
+
'''factor : literal
|
|
1163
|
+
| variable
|
|
1164
|
+
| pseudovariable
|
|
1165
|
+
| array
|
|
1166
|
+
| expr_group
|
|
1167
|
+
| expr_function
|
|
1168
|
+
| indexer
|
|
1169
|
+
| PLUS factor %prec UPLUS
|
|
1170
|
+
| MINUS factor %prec UMINUS'''
|
|
1171
|
+
if len(p) == 2:
|
|
1172
|
+
p[0] = p[1]
|
|
1173
|
+
elif len(p) == 3:
|
|
1174
|
+
if p[1] == '+':
|
|
1175
|
+
p[0] = UnaryPlus(factor = p[2])
|
|
1176
|
+
elif p[1] == '-':
|
|
1177
|
+
p[0] = UnaryMinus(factor = p[2])
|
|
1178
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1179
|
+
|
|
1180
|
+
def p_unary_indirection(p):
|
|
1181
|
+
'''unary_indirection : QUERY factor %prec UQUERY
|
|
1182
|
+
| PLING factor %prec UPLING
|
|
1183
|
+
| PIPE factor %prec UPIPE
|
|
1184
|
+
| DOLLAR factor %prec UDOLLAR'''
|
|
1185
|
+
if p[1] == '?':
|
|
1186
|
+
p[0] = UnaryByteIndirection(expression = p[2])
|
|
1187
|
+
elif p[1] == '!':
|
|
1188
|
+
p[0] = UnaryIntegerIndirection(expression = p[2])
|
|
1189
|
+
elif p[1] == '$':
|
|
1190
|
+
p[0] = UnaryStringIndirection(expression = p[2])
|
|
1191
|
+
elif p[1] == '|':
|
|
1192
|
+
p[0] = UnaryFloatIndirection(expression = p[2])
|
|
1193
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1194
|
+
|
|
1195
|
+
def p_expr_list(p):
|
|
1196
|
+
'''expr_list : expr
|
|
1197
|
+
| expr_list COMMA expr'''
|
|
1198
|
+
if len(p) == 2:
|
|
1199
|
+
p[0] = ExpressionList()
|
|
1200
|
+
p[0].append(p[1])
|
|
1201
|
+
elif len(p) == 4:
|
|
1202
|
+
p[1].append(p[3])
|
|
1203
|
+
p[0] = p[1]
|
|
1204
|
+
|
|
1205
|
+
def p_nullable_expr(p):
|
|
1206
|
+
'''nullable_expr : expr
|
|
1207
|
+
| empty'''
|
|
1208
|
+
p[0] = p[1]
|
|
1209
|
+
|
|
1210
|
+
def p_nullable_expr_list(p):
|
|
1211
|
+
'''nullable_expr_list : nullable_expr
|
|
1212
|
+
| nullable_expr_list COMMA nullable_expr'''
|
|
1213
|
+
if len(p) == 2:
|
|
1214
|
+
p[0] = ExpressionList()
|
|
1215
|
+
p[0].append(p[1])
|
|
1216
|
+
elif len(p) == 4:
|
|
1217
|
+
p[1].append(p[3])
|
|
1218
|
+
p[0] = p[1]
|
|
1219
|
+
|
|
1220
|
+
# TODO : Should any of these expressions take factors rather than expr as operands
|
|
1221
|
+
def p_expr(p):
|
|
1222
|
+
'''expr : factor
|
|
1223
|
+
| expr PLUS expr
|
|
1224
|
+
| expr MINUS expr
|
|
1225
|
+
| expr TIMES expr
|
|
1226
|
+
| expr DIVIDE expr
|
|
1227
|
+
| expr MOD expr
|
|
1228
|
+
| expr DIV expr
|
|
1229
|
+
| expr DOT expr
|
|
1230
|
+
| expr CARET expr
|
|
1231
|
+
| expr EQ expr
|
|
1232
|
+
| expr NE expr
|
|
1233
|
+
| expr LTE expr
|
|
1234
|
+
| expr GTE expr
|
|
1235
|
+
| expr LT expr
|
|
1236
|
+
| expr GT expr
|
|
1237
|
+
| expr SHIFT_LEFT expr
|
|
1238
|
+
| expr SHIFT_RIGHT expr
|
|
1239
|
+
| expr SHIFT_RIGHT_UNSIGNED expr
|
|
1240
|
+
| expr AND expr
|
|
1241
|
+
| expr OR expr
|
|
1242
|
+
| expr EOR expr
|
|
1243
|
+
| dyadic_indirection'''
|
|
1244
|
+
if len(p) == 2:
|
|
1245
|
+
p[0] = p[1]
|
|
1246
|
+
elif len(p) == 4:
|
|
1247
|
+
if p[2] == '+':
|
|
1248
|
+
p[0] = Plus(lhs = p[1], rhs = p[3])
|
|
1249
|
+
elif p[2] == '-':
|
|
1250
|
+
p[0] = Minus(lhs = p[1], rhs = p[3])
|
|
1251
|
+
elif p[2] == '*':
|
|
1252
|
+
p[0] = Multiply(lhs = p[1], rhs = p[3])
|
|
1253
|
+
elif p[2] == '/':
|
|
1254
|
+
p[0] = Divide(lhs = p[1], rhs = p[3])
|
|
1255
|
+
elif p[2] == 'DIV':
|
|
1256
|
+
p[0] = IntegerDivide(lhs = p[1], rhs = p[3])
|
|
1257
|
+
elif p[2] == 'MOD':
|
|
1258
|
+
p[0] = IntegerModulus(lhs = p[1], rhs = p[3])
|
|
1259
|
+
elif p[2] == '.':
|
|
1260
|
+
p[0] = MatrixMultiply(lhs = p[1], rhs = p[3])
|
|
1261
|
+
elif p[2] == '^':
|
|
1262
|
+
p[0] = Power(lhs = p[1], rhs = p[3])
|
|
1263
|
+
elif p[2] == '=':
|
|
1264
|
+
p[0] = Equal(lhs = p[1], rhs = p[3])
|
|
1265
|
+
elif p[2] == '<>':
|
|
1266
|
+
p[0] = NotEqual(lhs = p[1], rhs = p[3])
|
|
1267
|
+
elif p[2] == '<':
|
|
1268
|
+
p[0] = LessThan(lhs = p[1], rhs = p[3])
|
|
1269
|
+
elif p[2] == '<=':
|
|
1270
|
+
p[0] = LessThanEqual(lhs = p[1], rhs = p[3])
|
|
1271
|
+
elif p[2] == '>':
|
|
1272
|
+
p[0] = GreaterThan(lhs = p[1], rhs = p[3])
|
|
1273
|
+
elif p[2] == '>=':
|
|
1274
|
+
p[0] = GreaterThanEqual(lhs = p[1], rhs = p[3])
|
|
1275
|
+
elif p[2] == '<<':
|
|
1276
|
+
p[0] = ShiftLeft(lhs = p[1], rhs = p[3])
|
|
1277
|
+
elif p[2] == '>>':
|
|
1278
|
+
p[0] = ShiftRight(lhs = p[1], rhs = p[3])
|
|
1279
|
+
elif p[2] == '>>>':
|
|
1280
|
+
p[0] = ShiftRightUnsigned(lhs = p[1], rhs = p[3])
|
|
1281
|
+
elif p[2] == 'AND':
|
|
1282
|
+
p[0] = And(lhs = p[1], rhs = p[3])
|
|
1283
|
+
elif p[2] == 'OR':
|
|
1284
|
+
p[0] = Or(lhs = p[1], rhs = p[3])
|
|
1285
|
+
elif p[2] == 'EOR':
|
|
1286
|
+
p[0] = Eor(lhs = p[1], rhs = p[3])
|
|
1287
|
+
p[0].lineNum = p.lineno(2) - 1
|
|
1288
|
+
p[0].isLValue = False
|
|
1289
|
+
|
|
1290
|
+
def p_dyadic_indirection(p):
|
|
1291
|
+
"""dyadic_indirection : variable QUERY factor
|
|
1292
|
+
| variable PLING factor"""
|
|
1293
|
+
if p[2] == '?':
|
|
1294
|
+
# TODO: Ideally we would want to require that the LHS
|
|
1295
|
+
# of the dyadic indirection operators is a simple
|
|
1296
|
+
# variable. Doesn't work yet, though.
|
|
1297
|
+
p[0] = DyadicByteIndirection(base = p[1], offset = p[3])
|
|
1298
|
+
elif p[2] == '!':
|
|
1299
|
+
p[0] = DyadicIntegerIndirection(base = p[1], offset = p[3])
|
|
1300
|
+
p[0].lineNum = p.lineno(2) - 1
|
|
1301
|
+
|
|
1302
|
+
def p_expr_group(p):
|
|
1303
|
+
'expr_group : LPAREN expr RPAREN'
|
|
1304
|
+
p[0] = p[2]
|
|
1305
|
+
|
|
1306
|
+
|
|
1307
|
+
#=============================================================================#
|
|
1308
|
+
# VALUES
|
|
1309
|
+
#
|
|
1310
|
+
|
|
1311
|
+
# This contains all of the lvalues which can occur on the
|
|
1312
|
+
# left-hand-side on an assignment operator (without the LET).
|
|
1313
|
+
def p_lvalue(p):
|
|
1314
|
+
'''lvalue : writable
|
|
1315
|
+
| pseudovariable
|
|
1316
|
+
| mid_str_lvalue
|
|
1317
|
+
| right_str_lvalue
|
|
1318
|
+
| left_str_lvalue'''
|
|
1319
|
+
p[0] = p[1]
|
|
1320
|
+
p[0].isLValue = True
|
|
1321
|
+
|
|
1322
|
+
# This contains values which can be written or assigned to in
|
|
1323
|
+
# for example FOR and READ
|
|
1324
|
+
def p_writable(p):
|
|
1325
|
+
'''writable : variable
|
|
1326
|
+
| indexer
|
|
1327
|
+
| unary_indirection
|
|
1328
|
+
| dyadic_indirection'''
|
|
1329
|
+
p[0] = p[1]
|
|
1330
|
+
p[0].isLValue = True
|
|
1331
|
+
|
|
1332
|
+
def p_writable_list(p):
|
|
1333
|
+
'''writable_list : writable
|
|
1334
|
+
| writable_list COMMA writable'''
|
|
1335
|
+
if len(p) == 2:
|
|
1336
|
+
p[0] = WritableList()
|
|
1337
|
+
p[0].append(p[1])
|
|
1338
|
+
elif len(p) == 4:
|
|
1339
|
+
p[1].append(p[3])
|
|
1340
|
+
p[0] = p[1]
|
|
1341
|
+
|
|
1342
|
+
def p_mid_str_lvalue(p):
|
|
1343
|
+
'''mid_str_lvalue : MID_STR_LPAREN variable COMMA expr RPAREN
|
|
1344
|
+
| MID_STR_LPAREN variable COMMA expr COMMA expr RPAREN'''
|
|
1345
|
+
if len(p) == 6:
|
|
1346
|
+
p[0] = MidStrLValue(target = p[2], position = p[4])
|
|
1347
|
+
elif len(p) == 8:
|
|
1348
|
+
p[0] = MidStrLValue(target = p[2], position = p[4], length = p[6])
|
|
1349
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1350
|
+
|
|
1351
|
+
def p_right_str_lvalue(p):
|
|
1352
|
+
'''right_str_lvalue : RIGHT_STR_LPAREN variable RPAREN
|
|
1353
|
+
| RIGHT_STR_LPAREN variable COMMA expr RPAREN'''
|
|
1354
|
+
if len(p) == 4:
|
|
1355
|
+
p[0] = RightStrLValue(target = p[2])
|
|
1356
|
+
elif len(p) == 6:
|
|
1357
|
+
p[0] = RightStrLValue(target = p[2], length = p[4])
|
|
1358
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1359
|
+
|
|
1360
|
+
def p_left_str_lvalue(p):
|
|
1361
|
+
'''left_str_lvalue : LEFT_STR_LPAREN variable RPAREN
|
|
1362
|
+
| LEFT_STR_LPAREN variable COMMA expr RPAREN'''
|
|
1363
|
+
if len(p) == 4:
|
|
1364
|
+
p[0] = LeftStrLValue(target = p[2])
|
|
1365
|
+
elif len(p) == 6:
|
|
1366
|
+
p[0] = LeftStrLValue(target = p[2], length = p[4])
|
|
1367
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1368
|
+
|
|
1369
|
+
#=============================================================================#
|
|
1370
|
+
# PSEUDOVARIABLES
|
|
1371
|
+
#
|
|
1372
|
+
|
|
1373
|
+
def p_pseudovariable(p):
|
|
1374
|
+
'''pseudovariable : end_value
|
|
1375
|
+
| ext_value
|
|
1376
|
+
| himem_value
|
|
1377
|
+
| lomem_value
|
|
1378
|
+
| ptr_value
|
|
1379
|
+
| time_value
|
|
1380
|
+
| time_str_value
|
|
1381
|
+
| page_value'''
|
|
1382
|
+
p[0] = p[1]
|
|
1383
|
+
|
|
1384
|
+
# END is not officially a pseudovariable, although it can be used like one,
|
|
1385
|
+
# although it may also be used as a statement
|
|
1386
|
+
def p_end_value(p):
|
|
1387
|
+
'end_value : END'
|
|
1388
|
+
p[0] = EndValue()
|
|
1389
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1390
|
+
|
|
1391
|
+
def p_ext(p):
|
|
1392
|
+
'''ext_value : EXT channel'''
|
|
1393
|
+
p[0] = ExtValue(channel = p[2])
|
|
1394
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1395
|
+
|
|
1396
|
+
def p_himem_value(p):
|
|
1397
|
+
'himem_value : HIMEM'
|
|
1398
|
+
p[0] = HimemValue()
|
|
1399
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1400
|
+
|
|
1401
|
+
def p_lomem_value(p):
|
|
1402
|
+
'lomem_value : LOMEM'
|
|
1403
|
+
p[0] = LomemValue()
|
|
1404
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1405
|
+
|
|
1406
|
+
def p_page_value(p):
|
|
1407
|
+
'page_value : PAGE'
|
|
1408
|
+
p[0] = PageValue()
|
|
1409
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1410
|
+
|
|
1411
|
+
def p_ptr_value(p):
|
|
1412
|
+
'ptr_value : PTR channel'
|
|
1413
|
+
p[0] = PtrValue(channel = p[2])
|
|
1414
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1415
|
+
|
|
1416
|
+
def p_time_value(p):
|
|
1417
|
+
'time_value : TIME'
|
|
1418
|
+
p[0] = TimeValue()
|
|
1419
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1420
|
+
|
|
1421
|
+
def p_time_str_value(p):
|
|
1422
|
+
'time_str_value : TIME_STR'
|
|
1423
|
+
p[0] = TimeStrValue()
|
|
1424
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1425
|
+
|
|
1426
|
+
|
|
1427
|
+
#=============================================================================#
|
|
1428
|
+
# FUNCTIONS
|
|
1429
|
+
#
|
|
1430
|
+
|
|
1431
|
+
# TODO: Functions to be implemented
|
|
1432
|
+
''' expr_function :
|
|
1433
|
+
| report_str_func
|
|
1434
|
+
| string_str_func
|
|
1435
|
+
| usr_func'''
|
|
1436
|
+
|
|
1437
|
+
def p_expr_function(p):
|
|
1438
|
+
'''expr_function : user_func
|
|
1439
|
+
| adval_func
|
|
1440
|
+
| abs_func
|
|
1441
|
+
| acs_func
|
|
1442
|
+
| asc_func
|
|
1443
|
+
| asn_func
|
|
1444
|
+
| atn_func
|
|
1445
|
+
| beat_func
|
|
1446
|
+
| beats_func
|
|
1447
|
+
| bget_func
|
|
1448
|
+
| chr_str_func
|
|
1449
|
+
| cos_func
|
|
1450
|
+
| count_func
|
|
1451
|
+
| deg_func
|
|
1452
|
+
| dim_func
|
|
1453
|
+
| err_func
|
|
1454
|
+
| erl_func
|
|
1455
|
+
| exp_func
|
|
1456
|
+
| eof_func
|
|
1457
|
+
| eval_func
|
|
1458
|
+
| false_func
|
|
1459
|
+
| get_func
|
|
1460
|
+
| get_str_func
|
|
1461
|
+
| get_str_file_func
|
|
1462
|
+
| inkey_func
|
|
1463
|
+
| inkey_str_func
|
|
1464
|
+
| instr_func
|
|
1465
|
+
| int_func
|
|
1466
|
+
| left_str_func
|
|
1467
|
+
| len_func
|
|
1468
|
+
| ln_func
|
|
1469
|
+
| log_func
|
|
1470
|
+
| mid_str_func
|
|
1471
|
+
| mod_func
|
|
1472
|
+
| mode_func
|
|
1473
|
+
| not_func
|
|
1474
|
+
| openin_func
|
|
1475
|
+
| openout_func
|
|
1476
|
+
| openup_func
|
|
1477
|
+
| pi_func
|
|
1478
|
+
| pos_func
|
|
1479
|
+
| point_func
|
|
1480
|
+
| quit_func
|
|
1481
|
+
| sin_func
|
|
1482
|
+
| sgn_func
|
|
1483
|
+
| sqr_func
|
|
1484
|
+
| tan_func
|
|
1485
|
+
| rad_func
|
|
1486
|
+
| report_str_func
|
|
1487
|
+
| right_str_func
|
|
1488
|
+
| rnd_func
|
|
1489
|
+
| str_str_func
|
|
1490
|
+
| sum_func
|
|
1491
|
+
| sumlen_func
|
|
1492
|
+
| tempo_func
|
|
1493
|
+
| tint_func
|
|
1494
|
+
| top_func
|
|
1495
|
+
| true_func
|
|
1496
|
+
| val_func
|
|
1497
|
+
| vpos_func
|
|
1498
|
+
| width_func'''
|
|
1499
|
+
p[0] = p[1]
|
|
1500
|
+
|
|
1501
|
+
|
|
1502
|
+
def p_user_func(p):
|
|
1503
|
+
'''user_func : FN_ID
|
|
1504
|
+
| FN_ID LPAREN actual_arg_list RPAREN %prec FUNCTION'''
|
|
1505
|
+
if len(p) == 2:
|
|
1506
|
+
p[0] = UserFunc(name = p[1], actualParameters = ActualArgList())
|
|
1507
|
+
else:
|
|
1508
|
+
p[0] = UserFunc(name = p[1], actualParameters = p[3])
|
|
1509
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1510
|
+
|
|
1511
|
+
def p_abs_func(p):
|
|
1512
|
+
'abs_func : ABS factor %prec FUNCTION'
|
|
1513
|
+
p[0] = AbsFunc(factor = p[2])
|
|
1514
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1515
|
+
|
|
1516
|
+
def p_acs_func(p):
|
|
1517
|
+
'acs_func : ACS factor %prec FUNCTION'
|
|
1518
|
+
p[0] = AcsFunc(factor = p[2])
|
|
1519
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1520
|
+
|
|
1521
|
+
def p_adval_func(p):
|
|
1522
|
+
'adval_func : ADVAL factor %prec FUNCTION'
|
|
1523
|
+
p[0] = AdvalFunc(factor = p[2])
|
|
1524
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1525
|
+
|
|
1526
|
+
def p_asn_func(p):
|
|
1527
|
+
'asn_func : ASN factor %prec FUNCTION'
|
|
1528
|
+
p[0] = AsnFunc(factor = p[2])
|
|
1529
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1530
|
+
|
|
1531
|
+
def p_asc_func(p):
|
|
1532
|
+
'asc_func : ASC factor %prec FUNCTION'
|
|
1533
|
+
p[0] = AscFunc(factor = p[2])
|
|
1534
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1535
|
+
|
|
1536
|
+
def p_atn_func(p):
|
|
1537
|
+
'''atn_func : ATN factor %prec FUNCTION'''
|
|
1538
|
+
p[0] = AtnFunc(factor = p[2] )
|
|
1539
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1540
|
+
|
|
1541
|
+
def p_beat_func(p):
|
|
1542
|
+
'beat_func : BEAT %prec FUNCTION'
|
|
1543
|
+
p[0] = BeatFunc()
|
|
1544
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1545
|
+
|
|
1546
|
+
def p_beats_func(p):
|
|
1547
|
+
'''beats_func : BEATS %prec FUNCTION'''
|
|
1548
|
+
p[0] = BeatsFunc()
|
|
1549
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1550
|
+
|
|
1551
|
+
def p_bget_func(p):
|
|
1552
|
+
'bget_func : BGET channel %prec FUNCTION'
|
|
1553
|
+
p[0] = BgetFunc(channel = p[2])
|
|
1554
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1555
|
+
|
|
1556
|
+
def p_chr_str_func(p):
|
|
1557
|
+
'chr_str_func : CHR_STR expr %prec FUNCTION'
|
|
1558
|
+
p[0] = ChrStrFunc(factor = p[2])
|
|
1559
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1560
|
+
|
|
1561
|
+
def p_cos_func(p):
|
|
1562
|
+
'cos_func : COS expr %prec FUNCTION'
|
|
1563
|
+
p[0] = CosFunc(factor = p[2])
|
|
1564
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1565
|
+
|
|
1566
|
+
def p_count_func(p):
|
|
1567
|
+
'count_func : COUNT %prec FUNCTION'
|
|
1568
|
+
p[0] = CountFunc()
|
|
1569
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1570
|
+
|
|
1571
|
+
def p_deg_func(p):
|
|
1572
|
+
'deg_func : DEG factor %prec FUNCTION'
|
|
1573
|
+
p[0] = DegFunc(factor = p[2])
|
|
1574
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1575
|
+
|
|
1576
|
+
def p_dim_func(p):
|
|
1577
|
+
'''dim_func : DIM_LPAREN array RPAREN
|
|
1578
|
+
| DIM_LPAREN array COMMA expr RPAREN'''
|
|
1579
|
+
if len(p) == 4:
|
|
1580
|
+
p[0] = DimensionsFunc(array = p[2])
|
|
1581
|
+
elif len(p) == 6:
|
|
1582
|
+
p[0] = DimensionSizeFunc(array = p[2], dimension = p[4])
|
|
1583
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1584
|
+
|
|
1585
|
+
def p_erl_func(p):
|
|
1586
|
+
'''erl_func : ERL %prec FUNCTION'''
|
|
1587
|
+
p[0] = ErlFunc()
|
|
1588
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1589
|
+
|
|
1590
|
+
def p_eof(p):
|
|
1591
|
+
'''eof_func : EOF channel'''
|
|
1592
|
+
p[0] = EofFunc(channel = p[2])
|
|
1593
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1594
|
+
|
|
1595
|
+
def p_err_func(p):
|
|
1596
|
+
'''err_func : ERR %prec FUNCTION'''
|
|
1597
|
+
p[0] = ErrFunc()
|
|
1598
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1599
|
+
|
|
1600
|
+
def p_exp_func(p):
|
|
1601
|
+
'''exp_func : EXP factor %prec FUNCTION'''
|
|
1602
|
+
p[0] = ExpFunc(factor = p[2])
|
|
1603
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1604
|
+
|
|
1605
|
+
def p_eval_func(p):
|
|
1606
|
+
'''eval_func : EVAL factor %prec FUNCTION'''
|
|
1607
|
+
p[0] = EvalFunc(factor = p[2])
|
|
1608
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1609
|
+
|
|
1610
|
+
def p_false_func(p):
|
|
1611
|
+
'''false_func : FALSE'''
|
|
1612
|
+
p[0] = FalseFunc()
|
|
1613
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1614
|
+
|
|
1615
|
+
def p_get_func(p):
|
|
1616
|
+
'''get_func : GET %prec FUNCTION'''
|
|
1617
|
+
p[0] = GetFunc()
|
|
1618
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1619
|
+
|
|
1620
|
+
def p_get_str_func(p):
|
|
1621
|
+
'''get_str_func : GET_STR %prec FUNCTION'''
|
|
1622
|
+
p[0] = GetStrFunc()
|
|
1623
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1624
|
+
|
|
1625
|
+
def p_get_str_file_func(p):
|
|
1626
|
+
'''get_str_file_func : GET_STR channel %prec FUNCTION'''
|
|
1627
|
+
p[0] = GetStrFileFunc(channel = p[2])
|
|
1628
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1629
|
+
|
|
1630
|
+
def p_inkey_func(p):
|
|
1631
|
+
'''inkey_func : INKEY factor %prec FUNCTION'''
|
|
1632
|
+
#if factor 0<= then wait for any key and return keycode
|
|
1633
|
+
#if factor 0> then return true or false on that keycode
|
|
1634
|
+
#if factor = -256 return a number for OS version
|
|
1635
|
+
p[0] = InkeyFunc(factor = p[2])
|
|
1636
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1637
|
+
|
|
1638
|
+
def p_inkey_str_func(p):
|
|
1639
|
+
'''inkey_str_func : INKEY_STR factor %prec FUNCTION'''
|
|
1640
|
+
p[0] = InkeyStrFunc(factor = p[2])
|
|
1641
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1642
|
+
|
|
1643
|
+
def p_instr_func(p):
|
|
1644
|
+
'''instr_func : INSTR_LPAREN expr COMMA expr RPAREN
|
|
1645
|
+
| INSTR_LPAREN expr COMMA expr COMMA expr RPAREN'''
|
|
1646
|
+
if len(p) == 6:
|
|
1647
|
+
#INSTR expr COMMA expr
|
|
1648
|
+
p[0] = InstrFunc(source = p[2], subString = p[4] )
|
|
1649
|
+
elif len(p) == 8:
|
|
1650
|
+
#INSTR expr COMMA expr COMMA expr
|
|
1651
|
+
p[0] = InstrFunc(source = p[2], subString = p[4], startPosition = p[6] )
|
|
1652
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1653
|
+
|
|
1654
|
+
def p_int_func(p):
|
|
1655
|
+
'''int_func : INT factor %prec FUNCTION'''
|
|
1656
|
+
p[0] = IntFunc(factor = p[2])
|
|
1657
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1658
|
+
|
|
1659
|
+
def p_left_str_func(p):
|
|
1660
|
+
'''left_str_func : LEFT_STR_LPAREN expr RPAREN
|
|
1661
|
+
| LEFT_STR_LPAREN expr COMMA expr RPAREN'''
|
|
1662
|
+
if len(p) == 4:
|
|
1663
|
+
p[0] = LeftStrFunc(source = p[2])
|
|
1664
|
+
elif len(p) == 6:
|
|
1665
|
+
p[0] = LeftStrFunc(source = p[2], length = p[4])
|
|
1666
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1667
|
+
|
|
1668
|
+
def p_len_func(p):
|
|
1669
|
+
'''len_func : LEN factor %prec FUNCTION'''
|
|
1670
|
+
p[0] = LenFunc(factor = p[2])
|
|
1671
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1672
|
+
|
|
1673
|
+
def p_ln_func(p):
|
|
1674
|
+
'''ln_func : LN factor %prec FUNCTION'''
|
|
1675
|
+
p[0] = LnFunc(factpr = p[2])
|
|
1676
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1677
|
+
|
|
1678
|
+
def p_log_func(p):
|
|
1679
|
+
'''log_func : LOG factor %prec FUNCTION'''
|
|
1680
|
+
p[0] = LogFunc(factor = p[2])
|
|
1681
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1682
|
+
|
|
1683
|
+
def p_mid_str_func(p): # note for rob - is this missing %prec FUNCTION
|
|
1684
|
+
'''mid_str_func : MID_STR_LPAREN expr COMMA expr RPAREN
|
|
1685
|
+
| MID_STR_LPAREN expr COMMA expr COMMA expr RPAREN'''
|
|
1686
|
+
if len(p) == 6:
|
|
1687
|
+
p[0] = MidStrFunc(source = p[2], position = p[4])
|
|
1688
|
+
elif len(p) == 8:
|
|
1689
|
+
p[0] = MidStrFunc(source = p[2], position = p[4], length = p[6])
|
|
1690
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1691
|
+
|
|
1692
|
+
def p_mod_func(p):
|
|
1693
|
+
'mod_func : MOD array %prec FUNCTION'
|
|
1694
|
+
p[0] = ArrayRootMeanSquare(p[2])
|
|
1695
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1696
|
+
|
|
1697
|
+
def p_mode_func(p):
|
|
1698
|
+
'''mode_func : MODE %prec FUNCTION'''
|
|
1699
|
+
p[0] = ModeFunc()
|
|
1700
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1701
|
+
|
|
1702
|
+
def p_not_func(p):
|
|
1703
|
+
'not_func : NOT factor %prec FUNCTION'
|
|
1704
|
+
p[0] = Not(factor = p[2])
|
|
1705
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1706
|
+
|
|
1707
|
+
def p_openin_func(p):
|
|
1708
|
+
'''openin_func : OPENIN factor %prec FUNCTION'''
|
|
1709
|
+
p[0] = OpeninFunc(filename = p[2])
|
|
1710
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1711
|
+
|
|
1712
|
+
def p_openout_func(p):
|
|
1713
|
+
'''openout_func : OPENOUT factor %prec FUNCTION'''
|
|
1714
|
+
p[0] = OpenoutFunc(filename = p[2])
|
|
1715
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1716
|
+
|
|
1717
|
+
def p_openup_func(p):
|
|
1718
|
+
'''openup_func : OPENUP factor %prec FUNCTION'''
|
|
1719
|
+
p[0] = OpenupFunc(filename = p[2])
|
|
1720
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1721
|
+
|
|
1722
|
+
def p_pos_func(p):
|
|
1723
|
+
'''pos_func : POS %prec FUNCTION'''
|
|
1724
|
+
p[0] = PosFunc()
|
|
1725
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1726
|
+
|
|
1727
|
+
def p_pi_func(p):
|
|
1728
|
+
'''pi_func : PI %prec FUNCTION'''
|
|
1729
|
+
p[0] = PiFunc()
|
|
1730
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1731
|
+
|
|
1732
|
+
def p_point_func(p):
|
|
1733
|
+
'''point_func : POINT_LPAREN expr COMMA expr RPAREN %prec FUNCTION'''
|
|
1734
|
+
p[0] = PointFunc(xCoord = p[2] , yCoord = p[4])
|
|
1735
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1736
|
+
|
|
1737
|
+
def p_quit_func(p):
|
|
1738
|
+
'''quit_func : QUIT %prec FUNCTION'''
|
|
1739
|
+
p[0] = QuitFunc()
|
|
1740
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1741
|
+
|
|
1742
|
+
def p_rad_func(p):
|
|
1743
|
+
'rad_func : RAD factor %prec FUNCTION'
|
|
1744
|
+
p[0] = RadFunc(factor = p[2])
|
|
1745
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1746
|
+
|
|
1747
|
+
def p_report_str_func(p):
|
|
1748
|
+
'report_str_func : REPORT_STR %prec FUNCTION'
|
|
1749
|
+
p[0] = ReportStrFunc()
|
|
1750
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1751
|
+
|
|
1752
|
+
def p_right_str_func(p):
|
|
1753
|
+
'''right_str_func : RIGHT_STR_LPAREN expr RPAREN
|
|
1754
|
+
| RIGHT_STR_LPAREN expr COMMA expr RPAREN'''
|
|
1755
|
+
if len(p) == 4:
|
|
1756
|
+
p[0] = RightStrFunc(source = p[2])
|
|
1757
|
+
elif len(p) == 6:
|
|
1758
|
+
p[0] = RightStrFunc(source = p[2], length = p[4])
|
|
1759
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1760
|
+
|
|
1761
|
+
def p_rnd_func(p):
|
|
1762
|
+
'''rnd_func : RND %prec FUNCTION
|
|
1763
|
+
| RND_LPAREN expr RPAREN %prec FUNCTION'''
|
|
1764
|
+
if len(p) == 2:
|
|
1765
|
+
#RND
|
|
1766
|
+
p[0] = RndFunc(option=None)
|
|
1767
|
+
elif len(p) == 4:
|
|
1768
|
+
#RND expression
|
|
1769
|
+
p[0] = RndFunc(option = p[2])
|
|
1770
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1771
|
+
|
|
1772
|
+
def p_sin_func(p):
|
|
1773
|
+
'sin_func : SIN factor %prec FUNCTION'
|
|
1774
|
+
p[0] = SinFunc(factor = p[2])
|
|
1775
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1776
|
+
|
|
1777
|
+
def p_sgn_func(p):
|
|
1778
|
+
'sgn_func : SGN factor %prec FUNCTION'
|
|
1779
|
+
p[0] = SgnFunc(factor = p[2])
|
|
1780
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1781
|
+
|
|
1782
|
+
def p_sqr_func(p):
|
|
1783
|
+
'sqr_func : SQR factor %prec FUNCTION'
|
|
1784
|
+
p[0] = SqrFunc(factor = p[2])
|
|
1785
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1786
|
+
|
|
1787
|
+
def p_str_str_func(p):
|
|
1788
|
+
'''str_str_func : str_str_dec_func
|
|
1789
|
+
| str_str_hex_func'''
|
|
1790
|
+
p[0] = p[1]
|
|
1791
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1792
|
+
|
|
1793
|
+
def p_str_str_dec_func(p):
|
|
1794
|
+
'str_str_dec_func : STR_STR expr %prec FUNCTION'
|
|
1795
|
+
p[0] = StrStringFunc(factor = p[2], base = 10)
|
|
1796
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1797
|
+
|
|
1798
|
+
def p_str_str_hex_func(p):
|
|
1799
|
+
'str_str_hex_func : STR_STR TILDE expr %prec FUNCTION'
|
|
1800
|
+
p[0] = StrStringFunc(factor = p[2], base = 16)
|
|
1801
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1802
|
+
|
|
1803
|
+
def p_sum_func(p):
|
|
1804
|
+
'sum_func : SUM array %prec FUNCTION'
|
|
1805
|
+
# TODO: Accept factor and type check for array
|
|
1806
|
+
p[0] = Sum(array = p[2])
|
|
1807
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1808
|
+
|
|
1809
|
+
def p_sumlen_func(p):
|
|
1810
|
+
'sumlen_func : SUMLEN array %prec FUNCTION'
|
|
1811
|
+
# TODO: Accept factor and type check for array
|
|
1812
|
+
p[0] = SumLenFunc(array = p[2])
|
|
1813
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1814
|
+
|
|
1815
|
+
def p_tan_func(p):
|
|
1816
|
+
'tan_func : TAN factor %prec FUNCTION'
|
|
1817
|
+
p[0] = TanFunc(factor = p[2])
|
|
1818
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1819
|
+
|
|
1820
|
+
def p_tempo_func(p):
|
|
1821
|
+
'''tempo_func : TEMPO %prec FUNCTION'''
|
|
1822
|
+
p[0] = TempoFunc()
|
|
1823
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1824
|
+
|
|
1825
|
+
def p_tint_func(p):
|
|
1826
|
+
# TODO: The first of these is a statement
|
|
1827
|
+
'''tint_func : TINT LPAREN expr COMMA expr RPAREN %prec FUNCTION'''
|
|
1828
|
+
#TINT ( x, y )
|
|
1829
|
+
p[0] = TintFunc(xCoord = p[3] ,yCoord = p[5])
|
|
1830
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1831
|
+
|
|
1832
|
+
def p_top_func(p):
|
|
1833
|
+
'''top_func : TOP'''
|
|
1834
|
+
p[0] = TopFunc()
|
|
1835
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1836
|
+
|
|
1837
|
+
def p_true_func(p):
|
|
1838
|
+
'''true_func : TRUE'''
|
|
1839
|
+
p[0] = TrueFunc()
|
|
1840
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1841
|
+
|
|
1842
|
+
def p_val_func(p):
|
|
1843
|
+
'''val_func : VAL expr %prec FUNCTION'''
|
|
1844
|
+
p[0] = ValFunc(factor = p[2])
|
|
1845
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1846
|
+
|
|
1847
|
+
def p_vpos_func(p):
|
|
1848
|
+
'''vpos_func : VPOS %prec FUNCTION'''
|
|
1849
|
+
p[0] = VposFunc()
|
|
1850
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1851
|
+
|
|
1852
|
+
def p_width_func(p):
|
|
1853
|
+
'width_func : WIDTH %prec FUNCTION'
|
|
1854
|
+
p[0] = WidthFunc()
|
|
1855
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1856
|
+
|
|
1857
|
+
#=============================================================================#
|
|
1858
|
+
# CHANNEL
|
|
1859
|
+
#
|
|
1860
|
+
|
|
1861
|
+
# Channels
|
|
1862
|
+
def p_channel(p):
|
|
1863
|
+
'''channel : HASH factor %prec UHASH'''
|
|
1864
|
+
p[0] = Channel(channel = p[2])
|
|
1865
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1866
|
+
|
|
1867
|
+
|
|
1868
|
+
#=============================================================================#
|
|
1869
|
+
# VARIABLE
|
|
1870
|
+
|
|
1871
|
+
def p_variable(p):
|
|
1872
|
+
'variable : ID'
|
|
1873
|
+
p[0] = Variable(identifier = p[1])
|
|
1874
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1875
|
+
|
|
1876
|
+
def p_variable_list(p):
|
|
1877
|
+
'''variable_list : variable
|
|
1878
|
+
| variable_list COMMA variable'''
|
|
1879
|
+
if len(p) == 2:
|
|
1880
|
+
p[0] = VariableList()
|
|
1881
|
+
p[0].append(p[1])
|
|
1882
|
+
elif len(p) == 4:
|
|
1883
|
+
p[1].append(p[3])
|
|
1884
|
+
p[0] = p[1]
|
|
1885
|
+
|
|
1886
|
+
def p_nullable_variable(p):
|
|
1887
|
+
'''nullable_variable : variable
|
|
1888
|
+
| empty'''
|
|
1889
|
+
p[0] = p[1]
|
|
1890
|
+
|
|
1891
|
+
def p_nullable_variable_list(p):
|
|
1892
|
+
'''nullable_variable_list : nullable_variable
|
|
1893
|
+
| nullable_variable_list COMMA nullable_variable'''
|
|
1894
|
+
if len(p) == 2:
|
|
1895
|
+
p[0] = VariableList()
|
|
1896
|
+
p[0].append(p[1])
|
|
1897
|
+
elif len(p) == 4:
|
|
1898
|
+
p[1].append(p[3])
|
|
1899
|
+
p[0] = p[1]
|
|
1900
|
+
|
|
1901
|
+
def p_nullable_writable(p):
|
|
1902
|
+
'''nullable_writable : writable
|
|
1903
|
+
| empty'''
|
|
1904
|
+
p[0] = p[1]
|
|
1905
|
+
|
|
1906
|
+
def p_nullable_writable_list(p):
|
|
1907
|
+
'''nullable_writable_list : nullable_writable
|
|
1908
|
+
| nullable_writable_list COMMA nullable_writable'''
|
|
1909
|
+
if len(p) == 2:
|
|
1910
|
+
p[0] = WritableList()
|
|
1911
|
+
p[0].append(p[1])
|
|
1912
|
+
elif len(p) == 4:
|
|
1913
|
+
p[1].append(p[3])
|
|
1914
|
+
p[0] = p[1]
|
|
1915
|
+
#=============================================================================#
|
|
1916
|
+
# ARRAYS
|
|
1917
|
+
|
|
1918
|
+
# Array support
|
|
1919
|
+
def p_array(p):
|
|
1920
|
+
'array : ARRAYID_LPAREN RPAREN'
|
|
1921
|
+
p[0] = Array(identifier = p[1])
|
|
1922
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1923
|
+
|
|
1924
|
+
def p_indexer(p):
|
|
1925
|
+
'indexer : ARRAYID_LPAREN expr_list RPAREN'
|
|
1926
|
+
p[0] = Indexer(identifier = p[1], indices = p[2])
|
|
1927
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1928
|
+
|
|
1929
|
+
#=============================================================================#
|
|
1930
|
+
# LITERALS
|
|
1931
|
+
|
|
1932
|
+
def p_literal(p):
|
|
1933
|
+
'''literal : literal_string
|
|
1934
|
+
| literal_integer
|
|
1935
|
+
| literal_float'''
|
|
1936
|
+
p[0] = p[1]
|
|
1937
|
+
|
|
1938
|
+
def p_literal_string(p):
|
|
1939
|
+
'literal_string : LITERAL_STRING'
|
|
1940
|
+
p[0] = LiteralString(value = p[1])
|
|
1941
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1942
|
+
|
|
1943
|
+
def p_literal_integer(p):
|
|
1944
|
+
'literal_integer : LITERAL_INTEGER'
|
|
1945
|
+
p[0] = LiteralInteger(value = p[1])
|
|
1946
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1947
|
+
|
|
1948
|
+
def p_literal_float(p):
|
|
1949
|
+
'literal_float : LITERAL_FLOAT'
|
|
1950
|
+
p[0] = LiteralFloat(value = p[1])
|
|
1951
|
+
p[0].lineNum = p.lineno(1) - 1
|
|
1952
|
+
|
|
1953
|
+
#=============================================================================#
|
|
1954
|
+
# STAR COMMANDS
|
|
1955
|
+
|
|
1956
|
+
|
|
1957
|
+
#=============================================================================#
|
|
1958
|
+
# EMPTY PRODUCTION
|
|
1959
|
+
|
|
1960
|
+
def p_empty(p):
|
|
1961
|
+
'empty :'
|
|
1962
|
+
p[0] = None
|
|
1963
|
+
|
|
1964
|
+
#=============================================================================#
|
|
1965
|
+
# ERRORS
|
|
1966
|
+
|
|
1967
|
+
# Error rule for syntax errors
|
|
1968
|
+
def p_error(p):
|
|
1969
|
+
if p is None:
|
|
1970
|
+
logging.error("Syntax error at end of input (unexpected EOF)")
|
|
1971
|
+
else:
|
|
1972
|
+
logging.error("Syntax error at %r (physical line %s)", p.value, p.lineno)
|