int generateBLOCK(unsigned char * program, int pc, treenode * root) { treenode * child = firstchild(root); while (child != NULL) { pc = generate_statement(program, pc, child); child = nextchild(root, child); } return pc; }
void statement_code_generator::visit(while_tree const &statement) { temporary condition_variable( m_frame, 1 ); auto const at_condition_check = m_emitter.get_current_jump_address(); loop loop(m_frame, m_emitter, at_condition_check); { rvalue_generator condition( m_function_generator, m_emitter, m_frame, condition_variable.address() ); statement.condition().accept(condition); } auto const at_skip_body = m_emitter.get_current_jump_address(); m_emitter.jump_if_not( -1, condition_variable.address().local_address() ); generate_statement( statement.body(), m_function_generator, m_emitter, m_frame ); m_emitter.jump(at_condition_check); auto const at_after_loop = m_emitter.get_current_jump_address(); m_emitter.update_jump_destination( at_skip_body, at_after_loop); loop.finish(at_after_loop); }
void statement_code_generator::visit(block_tree const &statement) { local_frame block_symbols(m_frame); for (auto s = begin(statement.body()); s != end(statement.body()); ++s) { try { generate_statement( **s, m_function_generator, m_emitter, block_symbols ); } catch (compiler_error const &e) { m_function_generator.handle_error(e); } } }
void statement_code_generator::visit(if_tree const &statement) { //TODO: only create a variable if needed temporary const condition_variable( m_frame, 1 ); { rvalue_generator condition( m_function_generator, m_emitter, m_frame, condition_variable.address() ); statement.condition().accept(condition); } auto const jump_if_address = m_emitter.get_current_jump_address(); m_emitter.jump_if_not( -1, condition_variable.address().local_address() ); generate_statement( statement.on_true(), m_function_generator, m_emitter, m_frame ); auto const * const on_false = statement.on_false(); auto const skip_else_address = m_emitter.get_current_jump_address(); if (on_false) { m_emitter.jump( -1 ); } m_emitter.update_jump_destination( jump_if_address, m_emitter.get_current_jump_address() ); if (on_false) { generate_statement( *on_false, m_function_generator, m_emitter, m_frame ); m_emitter.update_jump_destination( skip_else_address, m_emitter.get_current_jump_address() ); } }