micro_asm.py (4508:837161d544c3) micro_asm.py (4512:cfa340f9d12a)
1# Copyright (c) 2003-2005 The Regents of The University of Michigan
2# All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are
6# met: redistributions of source code must retain the above copyright
7# notice, this list of conditions and the following disclaimer;
8# redistributions in binary form must reproduce the above copyright

--- 183 unchanged lines hidden (view full) ---

192 ('asm', 'exclusive'),
193 ('params', 'exclusive'),
194)
195
196reserved_map = { }
197for r in reserved:
198 reserved_map[r.lower()] = r
199
1# Copyright (c) 2003-2005 The Regents of The University of Michigan
2# All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are
6# met: redistributions of source code must retain the above copyright
7# notice, this list of conditions and the following disclaimer;
8# redistributions in binary form must reproduce the above copyright

--- 183 unchanged lines hidden (view full) ---

192 ('asm', 'exclusive'),
193 ('params', 'exclusive'),
194)
195
196reserved_map = { }
197for r in reserved:
198 reserved_map[r.lower()] = r
199
200# Ignore comments
200def t_ANY_COMMENT(t):
201 r'\#[^\n]*(?=\n)'
201def t_ANY_COMMENT(t):
202 r'\#[^\n]*(?=\n)'
202 #print "t_ANY_COMMENT %s" % t.value
203
204def t_ANY_MULTILINECOMMENT(t):
205 r'/\*([^/]|((?<!\*)/))*\*/'
203
204def t_ANY_MULTILINECOMMENT(t):
205 r'/\*([^/]|((?<!\*)/))*\*/'
206 #print "t_ANY_MULTILINECOMMENT %s" % t.value
207
206
207# A colon marks the end of a label. It should follow an ID which will
208# put the lexer in the "params" state. Seeing the colon will put it back
209# in the "asm" state since it knows it saw a label and not a mnemonic.
208def t_params_COLON(t):
209 r':'
210 t.lexer.begin('asm')
210def t_params_COLON(t):
211 r':'
212 t.lexer.begin('asm')
211 #print "t_params_COLON %s" % t.value
212 return t
213
213 return t
214
215# An "ID" in the micro assembler is either a label, directive, or mnemonic
216# If it's either a directive or a mnemonic, it will be optionally followed by
217# parameters. If it's a label, the following colon will make the lexer stop
218# looking for parameters.
214def t_asm_ID(t):
215 r'[A-Za-z_]\w*'
216 t.type = reserved_map.get(t.value, 'ID')
217 t.lexer.begin('params')
219def t_asm_ID(t):
220 r'[A-Za-z_]\w*'
221 t.type = reserved_map.get(t.value, 'ID')
222 t.lexer.begin('params')
218 #print "t_asm_ID %s" % t.value
219 return t
220
223 return t
224
225# If there is a label and you're -not- in the assember (which would be caught
226# above), don't start looking for parameters.
221def t_ANY_ID(t):
222 r'[A-Za-z_]\w*'
223 t.type = reserved_map.get(t.value, 'ID')
227def t_ANY_ID(t):
228 r'[A-Za-z_]\w*'
229 t.type = reserved_map.get(t.value, 'ID')
224 #print "t_ANY_ID %s" % t.value
225 return t
226
230 return t
231
232# Parameters are a string of text which don't contain an unescaped statement
233# statement terminator, ie a newline or semi colon.
227def t_params_PARAMS(t):
228 r'([^\n;]|((?<=\\)[\n;]))+'
229 t.lineno += t.value.count('\n')
230 t.lexer.begin('asm')
234def t_params_PARAMS(t):
235 r'([^\n;]|((?<=\\)[\n;]))+'
236 t.lineno += t.value.count('\n')
237 t.lexer.begin('asm')
231 #print "t_params_PARAMS %s" % t.value
232 return t
233
238 return t
239
240# Braces enter and exit micro assembly
234def t_INITIAL_LBRACE(t):
235 r'\{'
236 t.lexer.begin('asm')
241def t_INITIAL_LBRACE(t):
242 r'\{'
243 t.lexer.begin('asm')
237 #print "t_INITIAL_LBRACE %s" % t.value
238 return t
239
240def t_asm_RBRACE(t):
241 r'\}'
242 t.lexer.begin('INITIAL')
244 return t
245
246def t_asm_RBRACE(t):
247 r'\}'
248 t.lexer.begin('INITIAL')
243 #print "t_asm_RBRACE %s" % t.value
244 return t
245
249 return t
250
251# At the top level, keep track of newlines only for line counting.
246def t_INITIAL_NEWLINE(t):
247 r'\n+'
248 t.lineno += t.value.count('\n')
252def t_INITIAL_NEWLINE(t):
253 r'\n+'
254 t.lineno += t.value.count('\n')
249 #print "t_INITIAL_NEWLINE %s" % t.value
250
255
256# In the micro assembler, do line counting but also return a token. The
257# token is needed by the parser to detect the end of a statement.
251def t_asm_NEWLINE(t):
252 r'\n+'
253 t.lineno += t.value.count('\n')
258def t_asm_NEWLINE(t):
259 r'\n+'
260 t.lineno += t.value.count('\n')
254 #print "t_asm_NEWLINE %s" % t.value
255 return t
256
261 return t
262
263# A newline or semi colon when looking for params signals that the statement
264# is over and the lexer should go back to looking for regular assembly.
257def t_params_NEWLINE(t):
258 r'\n+'
259 t.lineno += t.value.count('\n')
260 t.lexer.begin('asm')
265def t_params_NEWLINE(t):
266 r'\n+'
267 t.lineno += t.value.count('\n')
268 t.lexer.begin('asm')
261 #print "t_params_NEWLINE %s" % t.value
262 return t
263
264def t_params_SEMI(t):
265 r';'
266 t.lexer.begin('asm')
269 return t
270
271def t_params_SEMI(t):
272 r';'
273 t.lexer.begin('asm')
267 #print "t_params_SEMI %s" % t.value
268 return t
269
270# Basic regular expressions to pick out simple tokens
271t_ANY_LPAREN = r'\('
272t_ANY_RPAREN = r'\)'
273t_ANY_SEMI = r';'
274t_ANY_DOT = r'\.'
275

--- 22 unchanged lines hidden (view full) ---

298
299def p_rom_or_macros_0(t):
300 'rom_or_macros : rom_or_macro'
301
302def p_rom_or_macros_1(t):
303 'rom_or_macros : rom_or_macros rom_or_macro'
304
305def p_rom_or_macro_0(t):
274 return t
275
276# Basic regular expressions to pick out simple tokens
277t_ANY_LPAREN = r'\('
278t_ANY_RPAREN = r'\)'
279t_ANY_SEMI = r';'
280t_ANY_DOT = r'\.'
281

--- 22 unchanged lines hidden (view full) ---

304
305def p_rom_or_macros_0(t):
306 'rom_or_macros : rom_or_macro'
307
308def p_rom_or_macros_1(t):
309 'rom_or_macros : rom_or_macros rom_or_macro'
310
311def p_rom_or_macro_0(t):
306 '''rom_or_macro : rom_block'''
312 '''rom_or_macro : rom_block
313 | macroop_def'''
307
314
308def p_rom_or_macro_1(t):
309 '''rom_or_macro : macroop_def'''
310
311# A block of statements
312def p_block(t):
313 'block : LBRACE statements RBRACE'
314 block = Block()
315 block.statements = t[2]
316 t[0] = block
317
318# Defines a section of microcode that should go in the current ROM
319def p_rom_block(t):
320 'rom_block : DEF ROM block SEMI'
321 if not t.parser.rom:
322 print_error("Rom block found, but no Rom object specified.")
323 raise TypeError, "Rom block found, but no Rom object was specified."
324 for statement in t[3].statements:
325 handle_statement(t.parser, t.parser.rom, statement)

--- 16 unchanged lines hidden (view full) ---

342 curop = t.parser.macro_type(t[3])
343 except TypeError:
344 print_error("Error creating macroop object.")
345 raise
346 for statement in t[4].statements:
347 handle_statement(t.parser, curop, statement)
348 t.parser.macroops[t[3]] = curop
349
315# Defines a section of microcode that should go in the current ROM
316def p_rom_block(t):
317 'rom_block : DEF ROM block SEMI'
318 if not t.parser.rom:
319 print_error("Rom block found, but no Rom object specified.")
320 raise TypeError, "Rom block found, but no Rom object was specified."
321 for statement in t[3].statements:
322 handle_statement(t.parser, t.parser.rom, statement)

--- 16 unchanged lines hidden (view full) ---

339 curop = t.parser.macro_type(t[3])
340 except TypeError:
341 print_error("Error creating macroop object.")
342 raise
343 for statement in t[4].statements:
344 handle_statement(t.parser, curop, statement)
345 t.parser.macroops[t[3]] = curop
346
347# A block of statements
348def p_block(t):
349 'block : LBRACE statements RBRACE'
350 block = Block()
351 block.statements = t[2]
352 t[0] = block
353
350def p_statements_0(t):
351 'statements : statement'
352 if t[1]:
353 t[0] = [t[1]]
354 else:
355 t[0] = []
356
357def p_statements_1(t):

--- 7 unchanged lines hidden (view full) ---

365 t[0] = t[1]
366
367# A statement can be a microop or an assembler directive
368def p_content_of_statement_0(t):
369 '''content_of_statement : microop
370 | directive'''
371 t[0] = t[1]
372
354def p_statements_0(t):
355 'statements : statement'
356 if t[1]:
357 t[0] = [t[1]]
358 else:
359 t[0] = []
360
361def p_statements_1(t):

--- 7 unchanged lines hidden (view full) ---

369 t[0] = t[1]
370
371# A statement can be a microop or an assembler directive
372def p_content_of_statement_0(t):
373 '''content_of_statement : microop
374 | directive'''
375 t[0] = t[1]
376
377# Ignore empty statements
373def p_content_of_statement_1(t):
374 'content_of_statement : '
375 pass
376
377# Statements are ended by newlines or a semi colon
378def p_end_of_statement(t):
379 '''end_of_statement : NEWLINE
380 | SEMI'''
381 pass
382
378def p_content_of_statement_1(t):
379 'content_of_statement : '
380 pass
381
382# Statements are ended by newlines or a semi colon
383def p_end_of_statement(t):
384 '''end_of_statement : NEWLINE
385 | SEMI'''
386 pass
387
388# Different flavors of microop to avoid shift/reduce errors
383def p_microop_0(t):
384 'microop : labels ID'
385 microop = Microop()
386 microop.labels = t[1]
387 microop.mnemonic = t[2]
388 t[0] = microop
389
390def p_microop_1(t):

--- 12 unchanged lines hidden (view full) ---

403
404def p_microop_3(t):
405 'microop : ID PARAMS'
406 microop = Microop()
407 microop.mnemonic = t[1]
408 microop.params = t[2]
409 t[0] = microop
410
389def p_microop_0(t):
390 'microop : labels ID'
391 microop = Microop()
392 microop.labels = t[1]
393 microop.mnemonic = t[2]
394 t[0] = microop
395
396def p_microop_1(t):

--- 12 unchanged lines hidden (view full) ---

409
410def p_microop_3(t):
411 'microop : ID PARAMS'
412 microop = Microop()
413 microop.mnemonic = t[1]
414 microop.params = t[2]
415 t[0] = microop
416
417# Labels in the microcode
411def p_labels_0(t):
412 'labels : label'
413 t[0] = [t[1]]
414
415def p_labels_1(t):
416 'labels : labels label'
417 t[1].append(t[2])
418 t[0] = t[1]

--- 7 unchanged lines hidden (view full) ---

426
427def p_label_1(t):
428 'label : EXTERN ID COLON'
429 label = Label()
430 label.is_extern = True
431 label.text = t[2]
432 t[0] = label
433
418def p_labels_0(t):
419 'labels : label'
420 t[0] = [t[1]]
421
422def p_labels_1(t):
423 'labels : labels label'
424 t[1].append(t[2])
425 t[0] = t[1]

--- 7 unchanged lines hidden (view full) ---

433
434def p_label_1(t):
435 'label : EXTERN ID COLON'
436 label = Label()
437 label.is_extern = True
438 label.text = t[2]
439 t[0] = label
440
441# Directives for the macroop
434def p_directive_0(t):
435 'directive : DOT ID'
436 directive = Directive()
437 directive.name = t[2]
438 t[0] = directive
439
440def p_directive_1(t):
441 'directive : DOT ID PARAMS'

--- 35 unchanged lines hidden ---
442def p_directive_0(t):
443 'directive : DOT ID'
444 directive = Directive()
445 directive.name = t[2]
446 t[0] = directive
447
448def p_directive_1(t):
449 'directive : DOT ID PARAMS'

--- 35 unchanged lines hidden ---