Mercurial > lcfOS
diff python/libasm.py @ 195:37ac6c016e0f
Expanded asm subsystem
author | Windel Bouwman |
---|---|
date | Fri, 31 May 2013 21:06:44 +0200 |
parents | b01429a5d695 |
children | ec2b423cdbea |
line wrap: on
line diff
--- a/python/libasm.py Wed May 29 22:36:37 2013 +0200 +++ b/python/libasm.py Fri May 31 21:06:44 2013 +0200 @@ -78,35 +78,118 @@ def Peak(self): return self.curTok -class Assembler: - def handle_ins(self, id0): - self.ins = id0 - def p_label(self, lname, cn): - self.label = lname +class ANode: + def __eq__(self, other): + return self.__repr__() == other.__repr__() + +class ALabel(ANode): + def __init__(self, name): + self.name = name + def __repr__(self): + return '{0}:'.format(self.name) + +class AInstruction(ANode): + def __init__(self, opcode, operands): + self.opcode = opcode + self.operands = operands + def __repr__(self): + ops = ', '.join(map(str, self.operands)) + return '{0} {1}'.format(self.opcode, ops) + +class AExpression(ANode): + def __add__(self, other): + return ABinop('+', self, other) + def __mul__(self, other): + return ABinop('*', self, other) +class ABinop(AExpression): + def __init__(self, op, arg1, arg2): + self.op = op + self.arg1 = arg1 + self.arg2 = arg2 + def __repr__(self): + return '{0} {1} {2}'.format(self.op, self.arg1, self.arg2) + +class AUnop(AExpression): + def __init__(self, op, arg): + self.op = op + self.arg = arg + def __repr__(self): + return '{0} {1}'.format(self.op, self.arg) + +class ASymbol(AExpression): + def __init__(self, name): + self.name = name + def __repr__(self): + return self.name + +class ANumber(AExpression): + def __init__(self, n): + self.n = n + def __repr__(self): + return '{0}'.format(self.n) + +class Assembler: def __init__(self): + self.output = [] # Construct a parser given a grammar: - g = pyyacc.Grammar(['ID', 'NUMBER', ',', '[', ']', ':', '+', '-', pyyacc.EPS]) - - g.add_production('asmline', ['label', 'instruction', 'operands']) - g.add_production('asmline', ['instruction', 'operands']) + ident = lambda x: x # Identity helper function + g = pyyacc.Grammar(['ID', 'NUMBER', ',', '[', ']', ':', '+', '-', '*', pyyacc.EPS]) + g.add_production('asmline', ['label', 'instruction']) + g.add_production('asmline', ['instruction']) + g.add_production('asmline', ['label']) g.add_production('label', ['ID', ':'], self.p_label) - g.add_production('instruction', ['ID'], self.handle_ins) - g.add_production('operands', ['operand']) - g.add_production('operands', ['operands', ',', 'operand']) - g.add_production('operand', ['expression']) - g.add_production('operand', ['[', 'expression', ']']) - g.add_production('expression', ['term']) - g.add_production('expression', ['expression', 'addop', 'term']) - g.add_production('addop', ['-']) - g.add_production('addop', ['+']) - g.add_production('term', ['factor']) - g.add_production('factor', ['ID']) - g.add_production('factor', ['NUMBER']) - # TODO: expand grammar + g.add_production('instruction', ['opcode', 'operands'], self.p_ins_1) + g.add_production('instruction', ['opcode'], self.p_ins_2) + g.add_production('opcode', ['ID'], ident) + g.add_production('operands', ['operand'], self.p_operands_1) + g.add_production('operands', ['operands', ',', 'operand'], self.p_operands_2) + g.add_production('operand', ['expression'], ident) + g.add_production('operand', ['[', 'expression', ']'], self.p_mem_op) + g.add_production('expression', ['term'], ident) + g.add_production('expression', ['expression', 'addop', 'term'], self.p_binop) + g.add_production('addop', ['-'], ident) + g.add_production('addop', ['+'], ident) + g.add_production('mulop', ['*'], ident) + g.add_production('term', ['factor'], ident) + g.add_production('term', ['term', 'mulop', 'factor'], self.p_binop) + g.add_production('factor', ['ID'], self.p_symbol) + g.add_production('factor', ['NUMBER'], self.p_number) g.start_symbol = 'asmline' + self.p = g.genParser() - self.p = g.genParser() + # Parser handlers: + def p_ins_1(self, opc, ops): + ins = AInstruction(opc, ops) + self.emit(ins) + def p_ins_2(self, opc): + self.p_ins_1(opc, []) + def p_operands_1(self, op1): + return [op1] + def p_operands_2(self, ops, comma, op2): + assert type(ops) is list + ops.append(op2) + return ops + def p_mem_op(self, brace_open, exp, brace_close): + return AUnop('[]', exp) + def handle_ins(self, id0, operands): + ins = AInstruction(id0) + self.emit(ins) + def p_label(self, lname, cn): + lab = ALabel(lname) + self.emit(lab) + def p_binop(self, exp1, op, exp2): + return ABinop(op, exp1, exp2) + def p_symbol(self, name): + return ASymbol(name) + def p_number(self, n): + n = int(n) + return ANumber(n) + + # Top level: + def emit(self, a): + self.output.append(a) + def parse_line(self, line): """ Parse line into asm AST """ tokens = tokenize(line)