BIG COMMIT!! Conditional jumps added, way too much stuff changed for a single commit...

This commit is contained in:
fsan 2021-11-01 19:12:49 -03:00
parent 72106c9b4d
commit c2b02f0f1e
9 changed files with 399 additions and 72 deletions

28
info
View File

@ -10,13 +10,18 @@ exp -> exp op exp (operacion) -> opexp
op -> + (suma) -> plus op -> + (suma) -> plus
op -> - (resta) -> minus op -> - (resta) -> minus
IR: The formal sintax represented above will no longer be
example: used. Conditional jumps will be added.
a = 2 + 2 For this we need the notion of "blocks" Im still thinking
=> on how to best approach this.
a = 4
=> prgm -> stms
MOV a, 0x0004 compound -> block, cjump;
cjump -> if opexp do block end
block -> stm; stm..
op -> = (cmp)
lex -> parse -> semantic -> codgen
a = b + 2 a = b + 2
=> =>
@ -37,3 +42,12 @@ equiv representation
MOV TMP, 0x0002 exp('2') MOV TMP, 0x0002 exp('2')
ADD TMP, [b] exp('b') '+' ADD TMP, [b] exp('b') '+'
MOV a, TMP MOV a, TMP
para la orga small
a = b + 2
=>
SET R1, 0x02
LOAD R2, [b]
ADD R1, R2
STR [a], R1

View File

@ -10,8 +10,6 @@ lexer::lex_file(std::string filename) {
// ; -> semi // ; -> semi
std::ifstream file("tst.cfran", std::ifstream::in); std::ifstream file("tst.cfran", std::ifstream::in);
bool id = false;
bool num = false;
std::string *value = new std::string(); std::string *value = new std::string();
char c; char c;
@ -51,7 +49,11 @@ lexer::lex_file(std::string filename) {
case '=': case '=':
if(id) add_token(token::TOK_ID, *value); if(id) add_token(token::TOK_ID, *value);
if(num) add_token(token::TOK_NUM, *value); if(num) add_token(token::TOK_NUM, *value);
add_token(token::TOK_ASSIGN, ""); if(cond) {
add_token(token::TOK_EQ, "=");
} else {
add_token(token::TOK_ASSIGN, "");
}
id = false; id = false;
num = false; num = false;
delete value; delete value;
@ -67,6 +69,7 @@ lexer::lex_file(std::string filename) {
value = new std::string(); value = new std::string();
//STM END //STM END
break; break;
case '\n':
case ' ': case ' ':
if(id) add_token(token::TOK_ID, *value); if(id) add_token(token::TOK_ID, *value);
if(num) add_token(token::TOK_NUM, *value); if(num) add_token(token::TOK_NUM, *value);
@ -87,6 +90,21 @@ lexer::lex_file(std::string filename) {
void void
lexer::add_token(token::type type, std::string value) { lexer::add_token(token::type type, std::string value) {
struct token *token = new struct token; struct token *token = new struct token;
if(type == token::TOK_ID) {
token->tok_type = type;
token->value = value;
if(value == "if") {
token->tok_type = token::TOK_IF;
cond = true;
}
if(value == "do") {
token->tok_type = token::TOK_DO;
cond = false;
}
if(value == "end") token->tok_type = token::TOK_END;
_tokens.push_back(token);
return;
}
token->tok_type = type; token->tok_type = type;
token->value = value; token->value = value;
_tokens.push_back(token); _tokens.push_back(token);

View File

@ -15,7 +15,7 @@ main(){
std::cout << "\n-----------------------\n"; std::cout << "\n-----------------------\n";
std::cout << "EVALUATING RESULTING TREE:\n"; std::cout << "EVALUATING RESULTING TREE:\n";
std::cout << str_token(*end) << '\n'; std::cout << str_token(*end) << '\n';
inter.evalSTM(*end); //inter.evalSTM(*end); // -> intepreter of parse tree.
tran.translate(end); tran.translate(end);
return 1; return 1;
} }

View File

@ -2,6 +2,7 @@
#include <cstddef> #include <cstddef>
#include <cstdio> #include <cstdio>
#include <iostream> #include <iostream>
#include <iomanip>
#include <fstream> #include <fstream>
#include <map> #include <map>
#include <list> #include <list>
@ -18,21 +19,33 @@ struct token {
TOK_ASSIGN, TOK_ASSIGN,
TOK_DO, TOK_DO,
TOK_WHILE, TOK_WHILE,
TOK_IF,
TOK_END, TOK_END,
TOK_LPAREN, TOK_LPAREN,
TOK_RPAREN, TOK_RPAREN,
TOK_COMMA, TOK_COMMA,
TOK_SEMI, TOK_SEMI,
TOK_EQ,
STM_ASSIGN, STM_ASSIGN,
STM_COMPOUND, STM_COMPOUND,
STM_CJUMP,
STM_BLOCK,
EXP_NUMBER, EXP_NUMBER,
EXP_ID, EXP_ID,
EXP_OPERATION EXP_OPERATION,
EXP_COMPARE,
BASIC_BLOCK,
CJUMP,
IR_SET,
IR_ADD,
IR_STORE,
IR_CJUMP
}; };
type tok_type; type tok_type;
std::string value; std::string value;
struct token *lvalue = nullptr; struct token *lvalue = nullptr;
struct token *rvalue = nullptr; struct token *rvalue = nullptr;
struct token *tvalue = nullptr;
}; };
/* /*
@ -65,6 +78,9 @@ class lexer {
private: private:
std::vector<struct token*> _tokens; std::vector<struct token*> _tokens;
void add_token(token::type, std::string value); void add_token(token::type, std::string value);
bool id = false;
bool num = false;
bool cond = false;
}; };
class parser { class parser {
@ -74,13 +90,17 @@ class parser {
~parser(); ~parser();
private: private:
void reduce(); void reduce();
void reduce_blck();
void reduce_num(struct token *num); void reduce_num(struct token *num);
void reduce_id(struct token *id); void reduce_id(struct token *id);
void reduce_stm(struct token *stm); void reduce_stm(struct token *stm);
void reduce_exp(struct token *exp); void reduce_exp(struct token *exp);
void statement(); //pops an statement into stack void statement(); //pops an statement into stack
void expression(); //pops an expression into stack void expression(); //pops an expression into stack
void conditional();
void err(); void err();
struct token *parse_until_tok_end();
struct token *pop(); struct token *pop();
void push(struct token *tok); void push(struct token *tok);
@ -94,18 +114,26 @@ class scope {
enum symbol_type{ enum symbol_type{
NOT_FOUND, NOT_FOUND,
VALUE, VALUE,
FUNCTION,
}; };
scope(); scope();
void add(std::string key, symbol_type type, size_t pos); void add(std::string key, symbol_type type);
symbol_type look(std::string key); scope* new_scope();
symbol_type look_type(std::string key);
size_t look_pos(std::string key);
size_t look_at_pos(std::string key);
void print_scope();
// scope(scope const &father); // scope(scope const &father);
private: private:
struct node { struct node {
std::string key; std::string key;
symbol_type type; symbol_type type;
size_t pos;
struct node *next = nullptr; struct node *next = nullptr;
}; };
struct node *head; struct node *head;
size_t _var_in_use = 0;
size_t _initial_position = 240;
}; };
class translator { class translator {
@ -115,8 +143,16 @@ class translator {
to be later consumed by a code generator to be later consumed by a code generator
*/ */
public: public:
void translate(struct token *head); size_t translate(struct token *head);
private: private:
void translate_assign(struct token *stm); size_t translate_assign(struct token *stm, scope *scope);
void translate_exp(struct token *exp); size_t translate_exp(struct token *exp, scope *scope);
size_t translate_stm(struct token *head, scope *scope);
size_t translate_block(struct token *head, scope *scope);
size_t set_tmp(std::string value);
size_t load_tmp(std::string value, scope *scope);
struct token *_tree;
bool _r0_in_use = false;
size_t _label_counter = 0;
size_t _mem_pos = 0;
}; };

View File

@ -17,11 +17,18 @@ parser::parse_tokens() {
break; break;
case token::STM_COMPOUND: case token::STM_COMPOUND:
break; break;
case token::TOK_IF:
std::cout << "ENTERING COND REDUCTION";
conditional(); // conditional follows the form of IF EXP DO STM END
break;
case token::TOK_END:
break;
default: default:
std::cout << "ERROR PARSING\n";
err(); err();
break; break;
} }
return parse_tokens(); parse_tokens();
} }
return _stack.top(); return _stack.top();
@ -35,10 +42,10 @@ parser::parser(std::vector<struct token*> tokens) {
void void
parser::reduce() { parser::reduce() {
if(_stack.size() == 1) return; if(_stack.size() <= 1) return;
struct token *tok = pop(); struct token *tok = pop();
// std::cout << str_token(*tok) << " "; std::cout << str_token(*tok) << " ";
switch (tok->tok_type) { switch (tok->tok_type) {
case token::TOK_NUM: case token::TOK_NUM:
// std::cout << "reduzco numero\n"; // std::cout << "reduzco numero\n";
@ -57,8 +64,10 @@ parser::reduce() {
case token::TOK_SEMI: case token::TOK_SEMI:
// reduce(); // reduce();
break; break;
// case token::TOK_ID: case token::STM_CJUMP:
std::cout << "CJUMP 44\n";
reduce_blck();
break;
case token::STM_ASSIGN: case token::STM_ASSIGN:
reduce_stm(tok); reduce_stm(tok);
default: break; default: break;
@ -71,6 +80,7 @@ parser::reduce_stm(struct token *stm) {
struct token *tok = pop(); struct token *tok = pop();
struct token *tmp; struct token *tmp;
switch (tok->tok_type) { switch (tok->tok_type) {
case token::STM_CJUMP:
case token::STM_ASSIGN: case token::STM_ASSIGN:
case token::STM_COMPOUND: case token::STM_COMPOUND:
tmp = new struct token; tmp = new struct token;
@ -80,7 +90,9 @@ parser::reduce_stm(struct token *stm) {
push(tmp); push(tmp);
// std::cout << "CHAD STM REDUCER " << str_token(*tmp); // std::cout << "CHAD STM REDUCER " << str_token(*tmp);
break; break;
default: default:
std::cout << "ERROR REDUCING STM\n";
std::cout << str_token(*tok) << "\n";
err(); err();
break; break;
} }
@ -110,7 +122,7 @@ parser::reduce_exp(struct token *exp) {
struct token *stm; struct token *stm;
switch (modifier->tok_type) { switch (modifier->tok_type) {
case token::TOK_ASSIGN: case token::TOK_ASSIGN:
// std::cout << "assign found\n"; std::cout << "assign found\n";
if(_stack.top()->tok_type != token::TOK_ID) err(); if(_stack.top()->tok_type != token::TOK_ID) err();
// std::cout << str_token(*_stack.top()) << "\n"; // std::cout << str_token(*_stack.top()) << "\n";
stm = new struct token; stm = new struct token;
@ -119,6 +131,22 @@ parser::reduce_exp(struct token *exp) {
stm->value = pop()->value; stm->value = pop()->value;
push(stm); push(stm);
break; break;
case token::TOK_EQ:
std::cout << "CMP_EXP\n";
if(_stack.top()->tok_type == token::TOK_NUM) {
reduce_num(pop());
}
if(_stack.top()->tok_type == token::TOK_ID) {
reduce_id(pop());
}
stm = new struct token;
stm->tok_type = token::EXP_COMPARE;
stm->value = modifier->value;
stm->rvalue = exp;
stm->lvalue = pop();
push(stm);
std::cout << "\n" << str_token(*stm) << '\n';
break;
case token::TOK_OP: case token::TOK_OP:
if(_stack.top()->tok_type == token::TOK_NUM) { if(_stack.top()->tok_type == token::TOK_NUM) {
reduce_num(pop()); reduce_num(pop());
@ -133,8 +161,12 @@ parser::reduce_exp(struct token *exp) {
stm->lvalue = pop(); stm->lvalue = pop();
push(stm); push(stm);
break; break;
default: err(); default:
std::cout << "ERROR REDUCING EXP\n";
err();
} }
std::cout << "\nTOKENS " << pos << '\n';
print_tokens(_tokens);
} }
struct token * struct token *
@ -172,18 +204,72 @@ parser::expression() {
std::cout << "This shouldn't be here...\n"; std::cout << "This shouldn't be here...\n";
err(); err();
break; break;
case token::TOK_EQ:
case token::TOK_OP: case token::TOK_OP:
expression(); expression();
break; break;
case token::TOK_SEMI: case token::TOK_SEMI:
reduce(); reduce();
break; break;
case token::TOK_DO:
std::cout << "Found do\n";
reduce_blck();
break;
default: default:
err(); err();
break;; break;;
} }
} }
void
parser::reduce_blck() {
if(_stack.size() == 1) return;
struct token *tok = pop();
std::cout << "\n--REDUCING BLOCK--\n";
std::cout << str_token(*tok) << "\n";
struct token *tmp;
switch (tok->tok_type) {
case token::STM_CJUMP:
case token::STM_COMPOUND:
case token::STM_ASSIGN:
reduce_stm(tok);
break;
case token::EXP_COMPARE:
assert(_stack.top()->tok_type == token::TOK_IF);
pop();
tmp = new struct token;
tmp->tok_type = token::STM_CJUMP;
tmp->rvalue = parse_until_tok_end();
tmp->lvalue = tok;
std::cout << str_token(*tmp->lvalue) << "\n";
std::cout << str_token(*tmp) << "\n";
std::cout << "CJUMP 5\n";
push(tmp);
break;
case token::TOK_NUM:
reduce_num(tok);
break;
case token::TOK_ID:
reduce_id(tok);
break;
case token::EXP_ID:
case token::EXP_OPERATION:
case token::EXP_NUMBER:
// EL SIGUIENTE ES UN OP O UN ASSIGN
reduce_exp(tok);
break;
default: break;
}
reduce_blck();
}
void
parser::conditional() {
push(_tokens[pos]);
pos++;
expression();
}
void void
parser::err() { parser::err() {
std::cout std::cout
@ -193,6 +279,22 @@ parser::err() {
exit(-1); exit(-1);
} }
parser::~parser(){ struct token*
free_tree(pop()); parser::parse_until_tok_end() {
std::vector<struct token*> tokens;
int depth = 0;
while (depth >= 0) {
tokens.push_back(_tokens[pos]);
if(_tokens[pos]->tok_type == token::TOK_DO) depth++;
if(_tokens[pos]->tok_type == token::TOK_END) depth--;
pos++;
}
tokens.pop_back();
parser pars(tokens);
std::cout << "NESTED PARSING BEGIN \n";
return pars.parse_tokens();
}
parser::~parser() {
// free_tree(pop());
} }

View File

@ -1,5 +1,7 @@
#include "orga-comp.h" #include "orga-comp.h"
#include <cstddef> #include <cstddef>
#include <cstdlib>
#include <iostream>
#include <string> #include <string>
scope::scope(){ scope::scope(){
@ -7,22 +9,66 @@ scope::scope(){
} }
void void
scope::add(std::string key, symbol_type type, size_t pos){ scope::add(std::string key, symbol_type type){
if (head == nullptr){ if (head == nullptr){
head = new node; head = new node;
head->key = key; head->key = key;
head->type = type; head->type = type;
head->pos = _initial_position + _var_in_use;
head->next = nullptr;
}else{ }else{
struct node *tmp = head; struct node *tmp = head;
head = new node; head = new node;
head->key = key; head->key = key;
head->type = type; head->type = type;
head->pos = _initial_position + _var_in_use;
head->next = tmp; head->next = tmp;
} }
_var_in_use++;
}
void
scope::print_scope(){
std::cout << "SCOPE AT : " << this << "\n";
struct node *tmp = head;
while(tmp != nullptr){
std::cout << tmp->key << " @ " << tmp->pos << "\n";
tmp = tmp->next;
}
} }
scope*
scope::new_scope(){
scope *tmp = new scope();
tmp->head = head;
tmp->_var_in_use = _var_in_use;
return tmp;
}
size_t
scope::look_pos(std::string key){
struct node *tmp = head;
while(tmp != nullptr){
if(tmp->key == key) return tmp->pos;
tmp = tmp->next;
}
add(key, symbol_type::VALUE);
return head->pos;
}
size_t
scope::look_at_pos(std::string key){
struct node *tmp = head;
while(tmp != nullptr){
if(tmp->key == key) return tmp->pos;
tmp = tmp->next;
}
std::cout << "\n--ERROR--\n";
std::cout << "ID " << key << " NOT DEFINED\n";
std::exit(-1);
}
scope::symbol_type scope::symbol_type
scope::look(std::string key){ scope::look_type(std::string key){
struct node *tmp = head; struct node *tmp = head;
while(tmp != nullptr){ while(tmp != nullptr){
if(tmp->key == key) return tmp->type; if(tmp->key == key) return tmp->type;

View File

@ -1,50 +1,142 @@
#include "orga-comp.h" #include "orga-comp.h"
#include <cstddef>
#include <cstdlib> #include <cstdlib>
#include <ios> #include <ios>
#include <iostream> #include <iostream>
#include <string>
void size_t
translator::translate(struct token *head){ translator::translate(struct token *head){
switch (head->tok_type) { scope *scp = new scope();
case token::STM_COMPOUND: size_t size = translate_stm(head, scp);
translate(head->lvalue); return size;
translate(head->rvalue);
break;
case token::STM_ASSIGN:
translate_assign(head);
break;
default: exit(-1);
}
} }
void size_t
translator::translate_assign(struct token *stm){ translator::translate_block(struct token *head, scope *scope){
struct token *exp = stm->rvalue; size_t size = 0;
translate_exp(exp); switch (head->tok_type) {
std::cout << "STORE INTO " << stm->value << '\n'; 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);
}
} }
void size_t
translator::translate_exp(struct token *exp){ translator::translate_stm(struct token *head, scope *scp){
switch (exp->tok_type) { size_t size = 0;
case token::EXP_NUMBER: size_t pos = _mem_pos;
std::cout << "LOAD LITERAL 0x" << std::hex << exp->value << '\n'; size_t lbl = _label_counter;
break; scope *tmp_scp;
case token::EXP_ID: switch (head->tok_type) {
std::cout << "LOAD " << exp->value << '\n'; case token::STM_CJUMP:
break; size += translate_exp(head->lvalue, scp);
case token::EXP_OPERATION: pos += size;
translate_exp(exp->rvalue); std::cout << "JZ do" << lbl << "\n";
switch (exp->lvalue->tok_type) { // << std::hex
case token::EXP_NUMBER: // << std::setw(2)
std::cout << "ADD 0x" << std::hex << exp->lvalue->value << '\n'; // << std::setfill('0')
break; // << pos++ << '\n';
case token::EXP_ID: std::cout << "JMP "
std::cout << "ADD [" << std::hex << exp->lvalue->value << "]\n"; << "end"
break; << lbl << '\n';
default: exit(-1); std::cout << "do" << lbl << ":\n";
} _label_counter++;
break; tmp_scp = scp->new_scope();
default: exit(-1); 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 << "AND 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;
} }

View File

@ -1,4 +1,11 @@
a = 3; a = 2;
j = 2 + 1; b = 8;
h = 2 + 1; if a = 3 do
p = a + 1; a = 1;
c = a + 3;
if b = 8 do
a = 4;
end
b = 4;
end
j = 4;

View File

@ -46,14 +46,26 @@ str_token(struct token tok){
return "SEMI "; return "SEMI ";
case token::STM_ASSIGN: case token::STM_ASSIGN:
return "STM_ASSIGN( " + tok.value + ", " + str_token(*tok.rvalue) + ")"; return "STM_ASSIGN( " + tok.value + ", " + str_token(*tok.rvalue) + ")";
case token::STM_CJUMP:
return "STM_CJUMP( " + str_token(*tok.lvalue) + ", " + str_token(*tok.rvalue) + ")";
case token::STM_COMPOUND: case token::STM_COMPOUND:
return "STM_COMPOUND< " + str_token(*tok.lvalue) + ", " + str_token(*tok.rvalue) + ">"; return "STM_COMPOUND< " + str_token(*tok.lvalue) + ", " + str_token(*tok.rvalue) + ">";
case token::EXP_NUMBER: case token::EXP_NUMBER:
return "EXP_NUMBER(" + tok.value + ")"; return "EXP_NUMBER(" + tok.value + ")";
case token::EXP_OPERATION: case token::EXP_OPERATION:
return "EXP_OPERATION( " + str_token(*tok.lvalue) + " " + tok.value + " " + str_token(*tok.rvalue) +")"; return "EXP_OPERATION( " + str_token(*tok.lvalue) + " " + tok.value + " " + str_token(*tok.rvalue) +")";
case token::EXP_COMPARE:
return "EXP_COMPARE( " + str_token(*tok.lvalue) + " " + tok.value + " " + str_token(*tok.rvalue) +")";
case token::EXP_ID: case token::EXP_ID:
return "EXP_ID "; return "EXP_ID ";
case token::TOK_END:
return "END ";
case token::TOK_IF:
return "IF ";
case token::TOK_DO:
return "DO ";
case token::TOK_EQ:
return "EQUAL ";
default: default:
return "SOMETHING"; return "SOMETHING";
} }