orga-comp/translator.cpp

142 lines
3.1 KiB
C++

#include "orga-comp.h"
#include <cstddef>
#include <cstdlib>
#include <ios>
#include <iostream>
#include <string>
size_t
translator::translate(struct token *head){
scope *scp = new scope();
size_t size = translate_stm(head, scp);
return size;
}
size_t
translator::translate_block(struct token *head, scope *scope){
size_t size = 0;
switch (head->tok_type) {
case token::STM_COMPOUND:
size += translate_assign(head->lvalue, scope);
size += translate_assign(head->rvalue, scope);
return size;
break;
case token::STM_ASSIGN:
return translate_assign(head, scope);
break;
default: exit(-1);
}
}
size_t
translator::translate_stm(struct token *head, scope *scp){
size_t size = 0;
size_t pos = _mem_pos;
size_t lbl = _label_counter;
scope *tmp_scp;
switch (head->tok_type) {
case token::STM_CJUMP:
size += translate_exp(head->lvalue, scp);
pos += size;
std::cout << "JZ do" << lbl << "\n";
// << std::hex
// << std::setw(2)
// << std::setfill('0')
// << pos++ << '\n';
std::cout << "JMP "
<< "end"
<< lbl << '\n';
std::cout << "do" << lbl << ":\n";
_label_counter++;
tmp_scp = scp->new_scope();
size += translate_stm(head->rvalue, tmp_scp);
std::cout << "end" << lbl << ":\n";
break;
case token::STM_COMPOUND:
size += translate_stm(head->lvalue, scp);
size += translate_stm(head->rvalue, scp);
break;
case token::STM_ASSIGN:
size = translate_assign(head, scp);
break;
default: exit(-1);
}
_mem_pos += size;
return size;
}
size_t
translator::translate_assign(struct token *stm, scope *scope){
size_t size = 0;
struct token *exp = stm->rvalue;
size += translate_exp(exp, scope);
std::cout << "STR [0x"
<< scope->look_pos(stm->value)
<< ']'
<< ", R0\n";
size++;
// scope->print_scope();
_r0_in_use = false;
return size;
}
size_t
translator::translate_exp(struct token *exp, scope *scope){
size_t size = 0;
switch (exp->tok_type) {
case token::EXP_NUMBER:
size = set_tmp(exp->value);
break;
case token::EXP_ID:
size = load_tmp(exp->value, scope);
break;
case token::EXP_OPERATION:
size += translate_exp(exp->rvalue, scope);
size += translate_exp(exp->lvalue, scope);
std::cout << "ADD R0, R1\n";
size++;
break;
case token::EXP_COMPARE:
size += translate_exp(exp->rvalue, scope);
size += translate_exp(exp->lvalue, scope);
std::cout << "CMP R0, R1\n";
size++;
break;
default: exit(-1);
}
return size;
}
size_t
translator::set_tmp(std::string value){
if(!_r0_in_use){
std::cout << "SET R0, 0x"
<< std::hex
<< std::setw(2)
<< std::setfill('0')
<< value << '\n';
_r0_in_use = true;
}else{
std::cout << "SET R1, 0x"
<< std::hex
<< std::setw(2)
<< std::setfill('0')
<< value << '\n';
}
return 1;
}
size_t
translator::load_tmp(std::string value, scope *scope){
if(!_r0_in_use){
std::cout << "LOAD R0, [0x"
<< scope->look_at_pos(value)
<< "]\n";
_r0_in_use = true;
}else{
std::cout << "LOAD R1, [0x"
<< scope->look_at_pos(value)
<< "]\n";
}
return 1;
}