area51/Support/ScriptCompiler/xsc_codegen_for_statement.cpp
Andrew Sampson 431f72b93a source
2021-08-27 19:22:41 -07:00

56 lines
1.8 KiB
C++

//==============================================================================
//
// xsc_codegen_for_statement
//
//==============================================================================
#include "xsc_codegen.hpp"
#include "xsc_tokenizer.hpp"
#include "xsc_errors.hpp"
#include "xsc_symbol_table.hpp"
#include "xsc_ast.hpp"
#include "../ScriptVM/xsc_vm_fileformat.hpp"
#include "../ScriptVM/xsc_vm_instructions.hpp"
//==============================================================================
// Defines
//==============================================================================
//==============================================================================
// EmitForStatement
//==============================================================================
void xsc_codegen::EmitForStatement( xsc_ast_node* pStatementNode )
{
ASSERT( pStatementNode->NodeType == ast_for_statement );
ASSERT( pStatementNode->Children.GetCount() == 4 );
// Emit Child0 for setup
EmitExpression( pStatementNode->Children[0] );
// Save code location for top of loop
s32 LoopAddress = m_Methods.GetLength();
// Emit Child1 for test
EmitExpression( pStatementNode->Children[1] );
// Save code location to backpatch the branch
s32 BranchAddress = m_Methods.GetLength();
EmitOpcode ( vm_bf );
EmitOperand( 0 );
// Emit Statement
EmitStatement( pStatementNode->Children[3] );
// Emit Child2 for incrementer
EmitExpression( pStatementNode->Children[2] );
// Emit Branch back to top of loop
EmitOpcode ( vm_ba );
EmitOperand( LoopAddress - (m_Methods.GetLength()+2) );
// Backpatch branch
EmitOperandAt( m_Methods.GetLength() - (BranchAddress+3), BranchAddress+1 );
}
//==============================================================================