158 lines
3.6 KiB
C++
158 lines
3.6 KiB
C++
#include <bits/types/FILE.h>
|
|
#include <cstddef>
|
|
#include <cstdio>
|
|
#include <iostream>
|
|
#include <iomanip>
|
|
#include <fstream>
|
|
#include <map>
|
|
#include <list>
|
|
#include <stack>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <assert.h>
|
|
|
|
struct token {
|
|
enum type {
|
|
TOK_ID,
|
|
TOK_NUM,
|
|
TOK_OP,
|
|
TOK_ASSIGN,
|
|
TOK_DO,
|
|
TOK_WHILE,
|
|
TOK_IF,
|
|
TOK_END,
|
|
TOK_LPAREN,
|
|
TOK_RPAREN,
|
|
TOK_COMMA,
|
|
TOK_SEMI,
|
|
TOK_EQ,
|
|
STM_ASSIGN,
|
|
STM_COMPOUND,
|
|
STM_CJUMP,
|
|
STM_BLOCK,
|
|
EXP_NUMBER,
|
|
EXP_ID,
|
|
EXP_OPERATION,
|
|
EXP_COMPARE,
|
|
BASIC_BLOCK,
|
|
CJUMP,
|
|
IR_SET,
|
|
IR_ADD,
|
|
IR_STORE,
|
|
IR_CJUMP
|
|
};
|
|
type tok_type;
|
|
std::string value;
|
|
struct token *lvalue = nullptr;
|
|
struct token *rvalue = nullptr;
|
|
struct token *tvalue = nullptr;
|
|
};
|
|
|
|
/*
|
|
struct ir {
|
|
enum type {
|
|
|
|
};
|
|
type tok_type;
|
|
};*/
|
|
|
|
void print_tokens(std::vector<struct token*> tokens);
|
|
bool leaf(struct token *tok);
|
|
void free_tree(struct token *head);
|
|
std::string str_token(struct token tok);
|
|
|
|
class interpreter {
|
|
|
|
public:
|
|
void evalSTM(struct token stm);
|
|
int evalEXP(struct token exp);
|
|
|
|
private:
|
|
std::map<std::string, int> table;
|
|
};
|
|
|
|
class lexer {
|
|
public:
|
|
std::vector<struct token*> lex_file(std::string filename);
|
|
~lexer();
|
|
private:
|
|
std::vector<struct token*> _tokens;
|
|
void add_token(token::type, std::string value);
|
|
bool id = false;
|
|
bool num = false;
|
|
bool cond = false;
|
|
};
|
|
|
|
class parser {
|
|
public:
|
|
parser(std::vector<struct token*> tokens);
|
|
struct token *parse_tokens();
|
|
~parser();
|
|
private:
|
|
void reduce();
|
|
void reduce_blck();
|
|
void reduce_num(struct token *num);
|
|
void reduce_id(struct token *id);
|
|
void reduce_stm(struct token *stm);
|
|
void reduce_exp(struct token *exp);
|
|
void statement(); //pops an statement into stack
|
|
void expression(); //pops an expression into stack
|
|
void conditional();
|
|
void err();
|
|
|
|
struct token *parse_until_tok_end();
|
|
|
|
struct token *pop();
|
|
void push(struct token *tok);
|
|
std::vector<struct token*> _tokens;
|
|
std::stack<struct token*> _stack;
|
|
size_t pos;
|
|
};
|
|
|
|
class scope {
|
|
public:
|
|
enum symbol_type{
|
|
NOT_FOUND,
|
|
VALUE,
|
|
FUNCTION,
|
|
};
|
|
scope();
|
|
void add(std::string key, symbol_type type);
|
|
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);
|
|
private:
|
|
struct node {
|
|
std::string key;
|
|
symbol_type type;
|
|
size_t pos;
|
|
struct node *next = nullptr;
|
|
};
|
|
struct node *head;
|
|
size_t _var_in_use = 0;
|
|
size_t _initial_position = 240;
|
|
};
|
|
|
|
class translator {
|
|
/*
|
|
Translate should take a parse tree and
|
|
produce an intermediary representation
|
|
to be later consumed by a code generator
|
|
*/
|
|
public:
|
|
size_t translate(struct token *head);
|
|
private:
|
|
size_t translate_assign(struct token *stm, scope *scope);
|
|
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;
|
|
}; |