Exemple #1
0
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()
				);
		}
	}