Franck Pommereau

added source filename:lineno in output

* cparse.py: add lineno to nodes
* cttc.py & cx86.py: output lineno as comments
General:
* make a cleaner parser
* use preprocessor
TTC:
* make stdlib
* load extern symbols from stdlib (declared in .h)
x86:
......
......@@ -20,9 +20,16 @@ class Node:
self.colno = colno
self.filename = filename
def loc (self) :
return "%s:%s:%s" % (self.filename, self.lineno, self.colno)
def loc (self, col=False) :
if col :
return "%s:%s:%s" % (self.filename, self.lineno, self.colno)
else :
return "%s:%s" % (self.filename, self.lineno)
def getpos (self) :
return {"lineno" : self.lineno,
"colno" : self.colno,
"filename" : self.filename}
def is_null(self):
"""Returns whether the node represents a null node."""
......
......@@ -250,11 +250,11 @@ def t_WHITESPACE(t):
def t_NEWLINE(t):
r'\n+'
t.lineno += len(t.value)
t.lexer.lineno += len(t.value)
def t_COMMENT(t):
r'/\*[\w\W]*?\*/'
t.lineno += t.value.count('\n')
t.lexer.lineno += t.value.count('\n')
pass
# ---------------------------------------------------------------
......
......@@ -8,6 +8,7 @@
# $Id: cparse.py,v 1.2 2004/05/27 16:25:08 varmaa Exp $
# ---------------------------------------------------------------
import ply.lex
import ply.yacc as yacc
from .clex import tokens # needed by yacc.yacc()
......@@ -26,6 +27,21 @@ def _get_calculated(node):
else:
return node
inputfile = None
def _get_pos(prod) :
for p in prod.slice[1:] :
if isinstance(p, Node) and p.lineno :
return p.getpos()
elif isinstance(p, yacc.YaccSymbol) :
for child in [p.type, p.value] :
if isinstance(child, Node) and child.lineno :
return child.getpos()
line_start = prod.lexer.lexdata.rfind('\n', 0, prod.lexpos(1)) + 1
return {"lineno" : prod.lineno(1),
"colno" : prod.lexpos(1) - line_start + 1,
"filename" : inputfile}
# ---------------------------------------------------------------
# PARSER GRAMMAR / AST CONSTRUCTION
#
......@@ -46,7 +62,7 @@ class ParseError(Exception):
def p_translation_unit_01(t):
'''translation_unit : external_declaration'''
t[0] = TranslationUnit(t[1])
t[0] = TranslationUnit(t[1], **_get_pos(t))
def p_translation_unit_02(t):
'''translation_unit : translation_unit external_declaration'''
......@@ -61,13 +77,13 @@ def p_external_declaration(t):
def p_function_definition_01(t):
'''function_definition : type_specifier declarator compound_statement'''
t[2].set_base_type(t[1])
t[0] = FunctionDefn(t[2], t[3])
t[0] = FunctionDefn(t[2], t[3], **_get_pos(t))
def p_function_definition_02(t):
'''function_definition : STATIC type_specifier declarator compound_statement'''
t[3].static = 1
t[3].set_base_type(t[2])
t[0] = FunctionDefn(t[3], t[4])
t[0] = FunctionDefn(t[3], t[4], **_get_pos(t))
def p_declaration_01(t):
'''declaration : type_specifier declarator SEMICOLON'''
......@@ -84,7 +100,7 @@ def p_declaration_02(t):
def p_declaration_list_opt_01(t):
'''declaration_list_opt : empty'''
t[0] = NullNode()
t[0] = NullNode(**_get_pos(t))
def p_declaration_list_opt_02(t):
'''declaration_list_opt : declaration_list'''
......@@ -92,7 +108,7 @@ def p_declaration_list_opt_02(t):
def p_declaration_list_02(t):
'''declaration_list : declaration'''
t[0] = DeclarationList(t[1])
t[0] = DeclarationList(t[1], **_get_pos(t))
def p_declaration_list_03(t):
'''declaration_list : declaration_list declaration'''
......@@ -102,7 +118,7 @@ def p_declaration_list_03(t):
def p_type_specifier(t):
'''type_specifier : INT
| CHAR'''
t[0] = BaseType(t[1])
t[0] = BaseType(t[1], **_get_pos(t))
def p_declarator_01(t):
'''declarator : direct_declarator'''
......@@ -115,16 +131,16 @@ def p_declarator_02(t):
def p_direct_declarator_01(t):
'''direct_declarator : ID'''
t[0] = Declaration(t[1])
t[0] = Declaration(t[1], **_get_pos(t))
def p_direct_declarator_02(t):
'''direct_declarator : direct_declarator LPAREN parameter_type_list RPAREN'''
t[1].add_type(FunctionType(t[3]))
t[1].add_type(FunctionType(t[3], **_get_pos(t)))
t[0] = t[1]
def p_direct_declarator_03(t):
'''direct_declarator : direct_declarator LPAREN RPAREN'''
t[1].add_type(FunctionType(ParamList()))
t[1].add_type(FunctionType(ParamList(**_get_pos(t)), **_get_pos(t)))
t[0] = t[1]
def p_parameter_type_list_01(t):
......@@ -138,7 +154,7 @@ def p_parameter_type_list_02(t):
def p_parameter_list_01(t):
'''parameter_list : parameter_declaration'''
t[0] = ParamList(t[1])
t[0] = ParamList(t[1], **_get_pos(t))
def p_parameter_list_02(t):
'''parameter_list : parameter_list COMMA parameter_declaration'''
......@@ -152,11 +168,11 @@ def p_parameter_declaration(t):
def p_compound_statement_01(t):
'''compound_statement : LBRACE declaration_list_opt statement_list RBRACE'''
t[0] = CompoundStatement(t[2], t[3])
t[0] = CompoundStatement(t[2], t[3], **_get_pos(t))
def p_compound_statement_02(t):
'''compound_statement : LBRACE declaration_list_opt RBRACE'''
t[0] = CompoundStatement(t[2], NullNode())
t[0] = CompoundStatement(t[2], NullNode(**_get_pos(t)), **_get_pos(t))
def p_expression_statement(t):
'''expression_statement : expression SEMICOLON'''
......@@ -170,7 +186,7 @@ def p_expression_02(t):
'''expression : equality_expression ASSIGN expression
| equality_expression EQ_PLUS expression
| equality_expression EQ_MINUS expression'''
t[0] = Binop(t[1], t[3], t[2])
t[0] = Binop(t[1], t[3], t[2], **_get_pos(t))
def p_equality_expression_01(t):
'''equality_expression : relational_expression'''
......@@ -179,7 +195,7 @@ def p_equality_expression_01(t):
def p_equality_expression_02(t):
'''equality_expression : equality_expression EQ relational_expression
| equality_expression NOT_EQ relational_expression'''
t[0] = _get_calculated(Binop(t[1], t[3], t[2]))
t[0] = _get_calculated(Binop(t[1], t[3], t[2], **_get_pos(t)))
def p_relational_expression_01(t):
'''relational_expression : additive_expression'''
......@@ -190,7 +206,7 @@ def p_relational_expression_02(t):
| relational_expression GREATER additive_expression
| relational_expression LESS_EQ additive_expression
| relational_expression GREATER_EQ additive_expression'''
t[0] = _get_calculated(Binop(t[1], t[3], t[2]))
t[0] = _get_calculated(Binop(t[1], t[3], t[2], **_get_pos(t)))
def p_postfix_expression_01(t):
'''postfix_expression : primary_expression'''
......@@ -198,20 +214,20 @@ def p_postfix_expression_01(t):
def p_postfix_expression_02(t):
'''postfix_expression : postfix_expression LPAREN argument_expression_list RPAREN'''
t[0] = FunctionExpression(t[1], t[3])
t[0] = FunctionExpression(t[1], t[3], **_get_pos(t))
pass
def p_postfix_expression_03(t):
'''postfix_expression : postfix_expression LPAREN RPAREN'''
t[0] = FunctionExpression(t[1], ArgumentList())
t[0] = FunctionExpression(t[1], ArgumentList(**_get_pos(t)), **_get_pos(t))
def p_postfix_expression_04(t):
'''postfix_expression : postfix_expression LBRACKET expression RBRACKET'''
t[0] = ArrayExpression(t[1], t[3])
t[0] = ArrayExpression(t[1], t[3], **_get_pos(t))
def p_argument_expression_list_01(t):
'''argument_expression_list : expression'''
t[0] = ArgumentList(t[1])
t[0] = ArgumentList(t[1], **_get_pos(t))
def p_argument_expression_list_02(t):
'''argument_expression_list : argument_expression_list COMMA expression'''
......@@ -224,7 +240,7 @@ def p_unary_expression_01(t):
def p_unary_expression_02(t):
'''unary_expression : MINUS unary_expression'''
t[0] = _get_calculated(Negative(t[2]))
t[0] = _get_calculated(Negative(t[2], **_get_pos(t)))
def p_unary_expression_03(t):
'''unary_expression : PLUS unary_expression'''
......@@ -234,15 +250,15 @@ def p_unary_expression_03(t):
'''unary_expression : EXCLAMATION unary_expression'''
# horrible hack for the '!' operator... Just insert an
# (expr == 0) into the AST.
t[0] = _get_calculated(Binop(t[2], Const(0, BaseType('int')), '=='))
t[0] = _get_calculated(Binop(t[2], Const(0, BaseType('int')), '==', **_get_pos(t)))
def p_unary_expression_04(t):
'''unary_expression : ASTERISK unary_expression'''
t[0] = Pointer(t[2])
t[0] = Pointer(t[2], **_get_pos(t))
def p_unary_expression_05(t):
'''unary_expression : AMPERSAND unary_expression'''
t[0] = AddrOf(t[2])
t[0] = AddrOf(t[2], **_get_pos(t))
def p_mult_expression_01(t):
'''mult_expression : unary_expression'''
......@@ -252,7 +268,7 @@ def p_mult_expression_02(t):
'''mult_expression : mult_expression ASTERISK unary_expression
| mult_expression DIV unary_expression
| mult_expression MODULO unary_expression'''
t[0] = _get_calculated(Binop(t[1], t[3], t[2]))
t[0] = _get_calculated(Binop(t[1], t[3], t[2], **_get_pos(t)))
def p_additive_expression_01(t):
'''additive_expression : mult_expression'''
......@@ -261,23 +277,23 @@ def p_additive_expression_01(t):
def p_additive_expression_02(t):
'''additive_expression : additive_expression PLUS mult_expression
| additive_expression MINUS mult_expression'''
t[0] = _get_calculated(Binop(t[1], t[3], t[2]))
t[0] = _get_calculated(Binop(t[1], t[3], t[2], **_get_pos(t)))
def p_primary_expression_01(t):
'''primary_expression : ID'''
t[0] = Id(t[1], t.lineno(1))
t[0] = Id(t[1], **_get_pos(t))
def p_primary_expression_02(t):
'''primary_expression : INUMBER'''
t[0] = Const(int(t[1]), BaseType('int'))
t[0] = Const(int(t[1]), BaseType('int', **_get_pos(t)), **_get_pos(t))
def p_primary_expression_03(t):
'''primary_expression : FNUMBER'''
t[0] = Const(float(t[1]), BaseType('double'))
t[0] = Const(float(t[1]), BaseType('double', **_get_pos(t)), **_get_pos(t))
def p_primary_expression_04(t):
'''primary_expression : CHARACTER'''
t[0] = Const(ord(eval(t[1])), BaseType('char'))
t[0] = Const(ord(eval(t[1])), BaseType('char', **_get_pos(t)), **_get_pos(t))
def p_primary_expression_05(t):
'''primary_expression : string_literal'''
......@@ -289,7 +305,7 @@ def p_primary_expression_06(t):
def p_string_literal_01(t):
'''string_literal : STRING'''
t[0] = StringLiteral(eval(t[1]))
t[0] = StringLiteral(eval(t[1]), **_get_pos(t))
def p_string_literal_02(t):
'''string_literal : string_literal STRING'''
......@@ -306,11 +322,11 @@ def p_statement(t):
def p_jump_statement_01(t):
'''jump_statement : RETURN SEMICOLON'''
t[0] = ReturnStatement(NullNode())
t[0] = ReturnStatement(NullNode(**_get_pos(t)), **_get_pos(t))
def p_jump_statement_02(t):
'''jump_statement : RETURN expression SEMICOLON'''
t[0] = ReturnStatement(t[2])
t[0] = ReturnStatement(t[2], **_get_pos(t))
def p_jump_statement_03(t):
'''jump_statement : BREAK SEMICOLON'''
......@@ -322,23 +338,23 @@ def p_jump_statement_04(t):
def p_iteration_statement_01(t):
'''iteration_statement : WHILE LPAREN expression RPAREN statement'''
t[0] = WhileLoop(t[3], t[5])
t[0] = WhileLoop(t[3], t[5], **_get_pos(t))
def p_iteration_statement_02(t):
'''iteration_statement : FOR LPAREN expression_statement expression_statement expression RPAREN statement'''
t[0] = ForLoop(t[3], t[4], t[5], t[7])
t[0] = ForLoop(t[3], t[4], t[5], t[7], **_get_pos(t))
def p_selection_statement_01(t):
'''selection_statement : IF LPAREN expression RPAREN statement'''
t[0] = IfStatement(t[3], t[5], NullNode())
t[0] = IfStatement(t[3], t[5], NullNode(**_get_pos(t)), **_get_pos(t))
def p_selection_statement_02(t):
'''selection_statement : IF LPAREN expression RPAREN statement ELSE statement'''
t[0] = IfStatement(t[3], t[5], t[7])
t[0] = IfStatement(t[3], t[5], t[7], **_get_pos(t))
def p_statement_list_02(t):
'''statement_list : statement'''
t[0] = StatementList(t[1])
t[0] = StatementList(t[1], **_get_pos(t))
def p_statement_list_03(t):
'''statement_list : statement_list statement'''
......@@ -350,7 +366,7 @@ def p_empty(t):
pass
def p_error(t):
print("[%s] syntax error:" % t.lineno)
print("[%(filename):%(lineno)s:%(colno)s] syntax error:" % _get_pos(t))
start = t.lexer.lexdata.rfind("\n", 0, t.lexpos)
if start == -1 :
start = 0
......
......@@ -142,6 +142,11 @@ class CodeGenVisitor (Visitor) :
def c(self, str, indent_amt=2):
self.curr_str.write("\n # %s\n\n" % str)
def _loc(self, node, comment="") :
if node.lineno != self._last_lineno or comment :
self._last_lineno = node.lineno
self.curr_str.write("# %s %s\n" % (node.loc(), comment))
def vNodeList(self, node):
self._visitList(node.nodes)
......@@ -158,6 +163,7 @@ class CodeGenVisitor (Visitor) :
def vStatementList(self, node):
for n in node.nodes:
self._loc(n)
self._accept_and_empty_stack(n)
def _generate_global_variable_definitions(self, node):
......@@ -169,6 +175,7 @@ class CodeGenVisitor (Visitor) :
return globals_str
def vTranslationUnit(self, node):
self._last_lineno = None
self.curr_str = io.StringIO()
self.globals_str = self._generate_global_variable_definitions(node)
self._visitList(node.nodes)
......@@ -239,6 +246,7 @@ class CodeGenVisitor (Visitor) :
stack_frame_size = self._calc_function_var_addrs(node.symtab, 0)
line = self._fill_line("BEGIN FUNCTION: %s()" % node.name)
self.c("%s\n #\n # Function type: %s" % (line, node.type.get_string()), 0)
self._loc(node, "(enter function)")
self.o("%s:" % node.compile_loc)
self.o(" push BP", "Save old frame pointer")
self.o(" mov SP BP", "Set new frame pointer")
......@@ -255,6 +263,7 @@ class CodeGenVisitor (Visitor) :
self.o(" sub R9 SP SP", "... shift SP")
self.stack.save_callee_saves()
self.curr_str.write(function_str.getvalue())
self._loc(node, "(exit function)")
self.o("%s:" % self.curr_func_end_label)
self.stack.load_callee_saves()
self.o(" mov BP SP", "Deallocate local+temp vars")
......@@ -264,9 +273,11 @@ class CodeGenVisitor (Visitor) :
self.c(line, 0)
def vCompoundStatement(self, node):
self._loc(node)
node.statement_list.accept(self)
def vIfStatement(self, node):
self._loc(node)
done_label = self.new_label() + "_done"
if not node.else_stmt.is_null():
else_label = self.new_label() + "_else"
......@@ -300,6 +311,7 @@ class CodeGenVisitor (Visitor) :
self.continue_labels.pop()
def vWhileLoop(self, node):
self._loc(node)
test_label = self.new_label() + "_test"
done_label = self.new_label() + "_done"
self._push_loop_labels(break_label=done_label,
......@@ -319,6 +331,7 @@ class CodeGenVisitor (Visitor) :
self._pop_loop_labels()
def vForLoop(self, node):
self._loc(node)
test_label = self.new_label() + "_test"
done_label = self.new_label() + "_done"
self._push_loop_labels(break_label=done_label,
......@@ -340,10 +353,12 @@ class CodeGenVisitor (Visitor) :
self._pop_loop_labels()
def vBreakStatement(self, node):
self._loc(node)
self.o(" set R9 @%s" % self.break_labels[-1], "Loop: break statement")
self.o(" jmp R9", "... jump to loop exit")
def vContinueStatement(self, node):
self._loc(node)
self.o(" set R9 @%s" % self.continue_labels[-1], "Loop: continue statement")
self.o(" jmp R9", "... jump to loop start")
......@@ -359,6 +374,7 @@ class CodeGenVisitor (Visitor) :
return label_str
def vStringLiteral(self, node):
self._loc(node)
label_str = self._get_new_str_literal_label(node.get_str())
COMMENT_CHARS = 7
comment_label = node.get_sanitized_str()
......@@ -368,10 +384,12 @@ class CodeGenVisitor (Visitor) :
"Get addr of string literal '%s'" % comment_label)
def vConst(self, node):
self._loc(node)
self.o(" set %s %X" % (self.stack.push(), node.value),
"Load numeric constant %d" % node.value)
def vId(self, node):
self._loc(node)
if node.output_addr:
if isinstance(node.symbol.compile_loc, int) :
self.o(" set R9 %X" % node.symbol.compile_loc,
......@@ -392,6 +410,7 @@ class CodeGenVisitor (Visitor) :
self.o(" ld %s %s" % (reg, reg), "Get value of %s" % node.symbol.name)
def vArrayExpression(self, node):
self._loc(node)
node.expr.accept(self)
node.index.accept(self)
reg_index = self.stack.pop()
......@@ -404,6 +423,7 @@ class CodeGenVisitor (Visitor) :
self.o(" ld %s %s" % (reg_to, reg_to), "Load array value")
def vFunctionExpression(self, node):
self._loc(node)
if self.test and node.function.symbol.name == "TTCTEST" :
call = node.arglist.nodes[0].get_str()
expect = self.test[call]
......@@ -433,6 +453,7 @@ class CodeGenVisitor (Visitor) :
self.c("FUNCTION CALL to %s() - end" % node.function.symbol.name)
def vReturnStatement(self, node):
self._loc(node)
return_reg = self._accept_and_pop(node.expr)
self.o(" mov %s R0" % return_reg, "Set return value")
self.o(" set R9 @%s" % self.curr_func_end_label,
......@@ -526,6 +547,7 @@ class CodeGenVisitor (Visitor) :
raise Exception("unsupported comparison %r" % node.op)
def vBinop(self, node):
self._loc(node)
if node.op in cparse.Binop.ASSIGN_OPS:
self._binop_assign(node)
elif node.op in ['+','-','*']:
......@@ -534,11 +556,13 @@ class CodeGenVisitor (Visitor) :
self._binop_compare(node)
def vNegative(self, node):
self._loc(node)
node.expr.accept(self)
reg = self.stack.peek()
self.o(" neg %s %s" % (reg, reg), "Perform unary negation")
def vPointer(self, node):
self._loc(node)
node.expr.accept(self)
if node.output_addr:
self.o("", "(Getting pointer target addr via '*')")
......@@ -549,6 +573,7 @@ class CodeGenVisitor (Visitor) :
self.stack.done()
def vAddrOf(self, node):
self._loc(node)
node.expr.accept(self)
self.o("", "(Address-of operator '&' used here)")
......@@ -558,6 +583,6 @@ def compile (path) :
def cpp (args, path) :
if args.test :
return ["cpp", "-P", "-D", "TTC", path]
return ["cpp", "-D", "TTC", path]
else :
return ["cpp", "-P", path]
return ["cpp", path]
......
......@@ -478,7 +478,13 @@ class CodeGenVisitor(Visitor):
self.o("\n%s# %s\n" % (indent, str))
def _loc(self, node, comment="") :
if node.lineno != self._last_lineno or comment :
self._last_lineno = node.lineno
self.curr_str.write("# %s %s\n" % (node.loc(), comment))
def vNodeList(self, node):
self._loc(node)
self._visitList(node.nodes)
def _empty_stack(self, node):
......@@ -506,6 +512,7 @@ class CodeGenVisitor(Visitor):
def vStatementList(self, node):
for n in node.nodes:
self._loc(n)
self._accept_and_empty_stack(n)
def _generate_global_variable_definitions(self, node):
......@@ -524,6 +531,7 @@ class CodeGenVisitor(Visitor):
def vTranslationUnit(self, node):
"""Outputs the entire assembly source file."""
self._last_lineno = None
self.curr_str = io.StringIO()
self.globals_str = self._generate_global_variable_definitions(node)
......@@ -665,6 +673,7 @@ class CodeGenVisitor(Visitor):
"# Function type: %s" %
(line, node.type.get_string()), 0)
self._loc(node, "(enter function)")
if not node.static:
self.o(" .global %s" % node.compile_loc)
self.o("%s:" % node.compile_loc)
......@@ -700,6 +709,7 @@ class CodeGenVisitor(Visitor):
# Add the previously-generated assembly code for the function.
self.curr_str.write(function_str.getvalue())
self._loc(node, "(exit function)")
self.o("%s:" % self.curr_func_end_label)
# Restore any callee-save registers that may have been used.
......@@ -712,9 +722,11 @@ class CodeGenVisitor(Visitor):
self.c(line, 0)
def vCompoundStatement(self, node):
self._loc(node)
node.statement_list.accept(self)
def vIfStatement(self, node):
self._loc(node)
done_label = self.new_label() + "_done"
if not node.else_stmt.is_null():
else_label = self.new_label() + "_else"
......@@ -757,6 +769,7 @@ class CodeGenVisitor(Visitor):
self.continue_labels.pop()
def vWhileLoop(self, node):
self._loc(node)
test_label = self.new_label() + "_test"
done_label = self.new_label() + "_done"
......@@ -782,6 +795,7 @@ class CodeGenVisitor(Visitor):
self._pop_loop_labels()
def vForLoop(self, node):
self._loc(node)
test_label = self.new_label() + "_test"
done_label = self.new_label() + "_done"
......@@ -810,10 +824,12 @@ class CodeGenVisitor(Visitor):
self._pop_loop_labels()
def vBreakStatement(self, node):
self._loc(node)
self.o(" jmp %s" % self.break_labels[-1],
"Loop: break statement")
def vContinueStatement(self, node):
self._loc(node)
self.o(" jmp %s" % self.continue_labels[-1],
"Loop: continue statement")
......@@ -833,6 +849,7 @@ class CodeGenVisitor(Visitor):
return label_str
def vStringLiteral(self, node):
self._loc(node)
label_str = self._get_new_str_literal_label(node.get_str())
# Make a little preview of the literal in the annotated
......@@ -847,11 +864,13 @@ class CodeGenVisitor(Visitor):
"Get addr of string literal '%s'" % comment_label)
def vConst(self, node):
self._loc(node)
self.o(" movl $%d, %s" % (node.value,
self.stack.push(node.type)),
"Load numeric constant %d" % node.value)
def vId(self, node):
self._loc(node)
# If we're only supposed to push our address on the stack, not
# our actual value, then do that and exit.
if node.output_addr:
......@@ -869,6 +888,7 @@ class CodeGenVisitor(Visitor):
"Get value of %s" % node.symbol.name)
def vArrayExpression(self, node):
self._loc(node)
node.expr.accept(self)
node.index.accept(self)
reg_index = self.stack.pop(node.index.type)
......@@ -891,6 +911,7 @@ class CodeGenVisitor(Visitor):
def vFunctionExpression(self, node):
"""Generates assembly for calling a function."""
self._loc(node)
self.c("FUNCTION CALL to %s() - begin" %
node.function.symbol.name)
......@@ -936,6 +957,7 @@ class CodeGenVisitor(Visitor):
node.function.symbol.name)
def vReturnStatement(self, node):
self._loc(node)
return_reg = self._accept_and_pop(node.expr)
self.o(" movl %s, %%eax" % return_reg, "Set return value")
self.o(" jmp %s" % self.curr_func_end_label, "Exit function")
......@@ -1051,6 +1073,7 @@ class CodeGenVisitor(Visitor):
"Zero-extend the boolean result")
def vBinop(self, node):
self._loc(node)
if node.op in cparse.Binop.ASSIGN_OPS:
self._binop_assign(node)
elif node.op in ['+','-','*']:
......@@ -1059,11 +1082,13 @@ class CodeGenVisitor(Visitor):
self._binop_compare(node)
def vNegative(self, node):
self._loc(node)
node.expr.accept(self)
self.o(" negl %s" % self.stack.peek(),
"Perform unary negation")
def vPointer(self, node):
self._loc(node)
node.expr.accept(self)
if node.output_addr:
self.o("", "(Getting pointer target addr via '*')")
......@@ -1080,6 +1105,7 @@ class CodeGenVisitor(Visitor):
self.stack.done()
def vAddrOf(self, node):
self._loc(node)
node.expr.accept(self)
self.stack.force_type_change(node.type)
self.o("", "(Address-of operator '&' used here)")
......@@ -1094,6 +1120,6 @@ def compile (path) :
def cpp (args, path) :
if args.test :
return ["cpp", "-P", "-D", "CC", path]
return ["cpp", "-D", "CC", path]
else :
return ["cpp", "-P", path]
return ["cpp", path]
......
......@@ -27,6 +27,7 @@ class Compiler (object) :
self.total_warnings = 0
def _parse (self) :
"Parses the source code."
cparse.inputfile = self.path
self.ast = yacc.parse(self.code)
def _compile_phase (self, visitor) :
"Applies a visitor to the abstract syntax tree."
......@@ -109,8 +110,10 @@ def main (args=None) :
print("Preprocessing %r" % src)
cpp = ARCH[args.arch].cpp(args, src)
print("..$ %s" % " ".join(cpp))
code = subprocess.check_output(cpp).decode()
print("Compiling preprocessed %r (line numbers may have changed)" % src)
code = "\n".join(l.rstrip()
for l in subprocess.check_output(cpp).decode().splitlines()
if not l.startswith("#"))
print("Compiling preprocessed %r" % src)
else :
code = "\n".join(l.rstrip() for l in open(src).readlines())
print("Compiling %r" % src)
......