106 lines
3.1 KiB
C++
106 lines
3.1 KiB
C++
#pragma once
|
|
|
|
#include "nasal_new_err.h"
|
|
#include "nasal_new_builtin.h"
|
|
#include "nasal_new_opcode.h"
|
|
#include "nasal_new_ast.h"
|
|
#include "ast_visitor.h"
|
|
#include "symbol_finder.h"
|
|
#include "nasal_new_parse.h"
|
|
#include "nasal_new_import.h"
|
|
|
|
#include <iomanip>
|
|
#include <list>
|
|
#include <stack>
|
|
#include <unordered_map>
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma warning (disable:4244)
|
|
#pragma warning (disable:4267)
|
|
#endif
|
|
|
|
class codegen {
|
|
private:
|
|
u16 fileindex;
|
|
error& err;
|
|
const std::string* file;
|
|
std::stack<u32> in_iterloop;
|
|
std::unordered_map<f64,u32> num_table;
|
|
std::unordered_map<std::string,u32> str_table;
|
|
std::vector<f64> num_res;
|
|
std::vector<std::string> str_res;
|
|
std::vector<opcode> code;
|
|
std::list<std::vector<i32>> continue_ptr;
|
|
std::list<std::vector<i32>> break_ptr;
|
|
|
|
// symbol table
|
|
// global : max STACK_DEPTH-1 values
|
|
std::unordered_map<std::string,i32> global;
|
|
// local : max 32768 upvalues 65536 values
|
|
// but in fact local scope also has less than STACK_DEPTH value
|
|
std::list<std::unordered_map<std::string,i32>> local;
|
|
|
|
bool check_memory_reachable(call_expr*);
|
|
void check_id_exist(identifier*);
|
|
|
|
void die(const std::string& info, const span& loc) {
|
|
err.err("code", loc, info);
|
|
}
|
|
|
|
void regist_num(const f64);
|
|
void regist_str(const std::string&);
|
|
void find_symbol(code_block*);
|
|
void add_sym(const std::string&);
|
|
i32 local_find(const std::string&);
|
|
i32 global_find(const std::string&);
|
|
i32 upvalue_find(const std::string&);
|
|
|
|
void gen(u8, u32, u32);
|
|
|
|
void num_gen(number_literal*);
|
|
void str_gen(string_literal*);
|
|
void bool_gen(bool_literal*);
|
|
void vec_gen(vector_expr*);
|
|
void hash_gen(hash_expr*);
|
|
void func_gen(function*);
|
|
void call_gen(call_expr*);
|
|
void call_id(identifier*);
|
|
void call_hash_gen(call_hash*);
|
|
void call_vec(call_vector*);
|
|
void call_func(call_function*);
|
|
void mcall(call_expr*);
|
|
void mcall_id(identifier*);
|
|
void mcall_vec(call_vector*);
|
|
void mcall_hash(call_hash*);
|
|
void multi_def(definition_expr*);
|
|
void single_def(definition_expr*);
|
|
void def_gen(definition_expr*);
|
|
void assignment_gen(assignment_expr*);
|
|
void assign_statement(assignment_expr*);
|
|
void multi_assign_gen(multi_assign*);
|
|
void cond_gen(condition_expr*);
|
|
void loop_gen(expr*);
|
|
void load_continue_break(i32, i32);
|
|
void while_gen(while_expr*);
|
|
void for_gen(for_expr*);
|
|
void expr_gen(expr*);
|
|
void forindex_gen(forei_expr*);
|
|
void foreach_gen(forei_expr*);
|
|
void or_gen(binary_operator*);
|
|
void and_gen(binary_operator*);
|
|
void unary_gen(unary_operator*);
|
|
void binary_gen(binary_operator*);
|
|
void trino_gen(ternary_operator*);
|
|
void calc_gen(expr*);
|
|
void block_gen(code_block*);
|
|
void ret_gen(return_expr*);
|
|
|
|
public:
|
|
codegen(error& e): fileindex(0), err(e), file(nullptr) {}
|
|
const error& compile(parse&, linker&);
|
|
void print();
|
|
const std::vector<std::string>& strs() const {return str_res;}
|
|
const std::vector<f64>& nums() const {return num_res;}
|
|
const std::vector<opcode>& codes() const {return code;}
|
|
};
|