Commit d7dae728 authored by 李晓奇's avatar 李晓奇

backup on halfway

parent 2dd8c34b
...@@ -15,8 +15,8 @@ IncludeCategories: ...@@ -15,8 +15,8 @@ IncludeCategories:
Priority: 2 Priority: 2
- Regex: '.*' - Regex: '.*'
Priority: 1 Priority: 1
IndentCaseLabels: false IndentCaseLabels: true
AllowShortCaseLabelsOnASingleLine: true AllowShortCaseLabelsOnASingleLine: false
IndentWidth: 4 IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: false KeepEmptyLinesAtTheStartOfBlocks: false
PenaltyReturnTypeOnItsOwnLine: 200 PenaltyReturnTypeOnItsOwnLine: 200
......
# lab3 实验报告 # lab3 实验报告
学号 姓名
PB20111654 李晓奇
## 实验要求 ## 实验要求
## 实验难点 ## 实验难点
实验中遇到哪些挑战 1. syntax_tree和ast的区别、为什需要ast?
阅读AST的构造函数,`AST(syntax_tree *)`
实际上这部分在上个实验就有看calc_ast的代码,但是印象不深刻。。
2. 访问者模式究竟有什么用?
比如这样一系列函数调用:
```cpp
ASTPrinter::visit(ASTProgram &)
{
//...
for (auto decl : node.declarations) {
decl->accept(*this);
}
//...
}
ASTVarDeclaration::accept(ASTVisitor &)
{
//...
auto var_decl = dynamic_cast<ASTVarDeclaration *>(this);
if (var_decl) {
var_decl->accept(visitor);
return;
}
//...
}
void ASTVarDeclaration::accept(ASTVisitor &visitor)
{ visitor.visit(*this); }
```
假设就是vardeclaration,直接调用(在`ASTPrinter::visit`内)`visit(dynamic_cast<ASTVarDeclaration *>(this))`不是一样的吗?
参考[攻略](https://www.jianshu.com/p/1f1049d0a0f4),接受一点,感觉还是不太明白,但是不影响写实验。因为经过反复的阅读,我已经知道了我们要实现的`CminusfBuilder`是一个访问者类!
3. 无从下手!
从变量开始!
自底向上做自然多了,不然像在摸黑拧魔方。
4. 如何获得返回值?
加入一个全局变量保存语句的返回值。
5. 数组or指针?这个关乎地址的计算、类型转换……
答案在于:中间代码是如何生成的?
按我的理解,
- 在翻译为中间代码时,函数内部声明的只能是数组,计算地址时会得到指针。
- 在传递给函数时,只能传递数组,但是传递为指针。
## 实验设计 ## 实验设计
......
...@@ -2,17 +2,13 @@ ...@@ -2,17 +2,13 @@
#define _SYNTAX_TREE_HPP_ #define _SYNTAX_TREE_HPP_
extern "C" { extern "C" {
#include "syntax_tree.h" #include "syntax_tree.h"
extern syntax_tree *parse(const char *input); extern syntax_tree *parse(const char *input);
} }
#include <vector>
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector>
enum CminusType { enum CminusType { TYPE_INT, TYPE_FLOAT, TYPE_VOID };
TYPE_INT,
TYPE_FLOAT,
TYPE_VOID
};
enum RelOp { enum RelOp {
// <= // <=
...@@ -64,23 +60,24 @@ struct ASTVar; ...@@ -64,23 +60,24 @@ struct ASTVar;
struct ASTAssignExpression; struct ASTAssignExpression;
struct ASTSimpleExpression; struct ASTSimpleExpression;
struct ASTAdditiveExpression; struct ASTAdditiveExpression;
struct ASTTerm ; struct ASTTerm;
struct ASTCall; struct ASTCall;
class ASTVisitor; class ASTVisitor;
class AST { class AST {
public: public:
AST() = delete; AST() = delete;
AST(syntax_tree *); AST(syntax_tree *);
AST(AST &&tree) { AST(AST &&tree) {
root = tree.root; root = tree.root;
tree.root = nullptr; tree.root = nullptr;
}; };
ASTProgram* get_root() { return root.get(); } ASTProgram *get_root() { return root.get(); }
void run_visitor(ASTVisitor& visitor); void run_visitor(ASTVisitor &visitor);
private:
ASTNode* transform_node_iter(syntax_tree_node *); private:
ASTNode *transform_node_iter(syntax_tree_node *);
std::shared_ptr<ASTProgram> root = nullptr; std::shared_ptr<ASTProgram> root = nullptr;
}; };
...@@ -90,21 +87,20 @@ struct ASTNode { ...@@ -90,21 +87,20 @@ struct ASTNode {
struct ASTProgram : ASTNode { struct ASTProgram : ASTNode {
virtual void accept(ASTVisitor &) override final; virtual void accept(ASTVisitor &) override final;
std::vector<std::shared_ptr<ASTDeclaration>> std::vector<std::shared_ptr<ASTDeclaration>> declarations;
declarations;
}; };
struct ASTDeclaration: ASTNode { struct ASTDeclaration : ASTNode {
virtual void accept(ASTVisitor &) override; virtual void accept(ASTVisitor &) override;
CminusType type; CminusType type;
std::string id; std::string id;
}; };
struct ASTFactor: ASTNode { struct ASTFactor : ASTNode {
virtual void accept(ASTVisitor &) override; virtual void accept(ASTVisitor &) override;
}; };
struct ASTNum: ASTFactor { struct ASTNum : ASTFactor {
virtual void accept(ASTVisitor &) override final; virtual void accept(ASTVisitor &) override final;
CminusType type; CminusType type;
union { union {
...@@ -113,19 +109,19 @@ struct ASTNum: ASTFactor { ...@@ -113,19 +109,19 @@ struct ASTNum: ASTFactor {
}; };
}; };
struct ASTVarDeclaration: ASTDeclaration { struct ASTVarDeclaration : ASTDeclaration {
virtual void accept(ASTVisitor &) override final; virtual void accept(ASTVisitor &) override final;
CminusType type; CminusType type;
std::shared_ptr<ASTNum> num; std::shared_ptr<ASTNum> num;
}; };
struct ASTFunDeclaration: ASTDeclaration { struct ASTFunDeclaration : ASTDeclaration {
virtual void accept(ASTVisitor &) override final; virtual void accept(ASTVisitor &) override final;
std::vector<std::shared_ptr<ASTParam>> params; std::vector<std::shared_ptr<ASTParam>> params;
std::shared_ptr<ASTCompoundStmt> compound_stmt; std::shared_ptr<ASTCompoundStmt> compound_stmt;
}; };
struct ASTParam: ASTNode { struct ASTParam : ASTNode {
virtual void accept(ASTVisitor &) override final; virtual void accept(ASTVisitor &) override final;
CminusType type; CminusType type;
std::string id; std::string id;
...@@ -137,62 +133,62 @@ struct ASTStatement : ASTNode { ...@@ -137,62 +133,62 @@ struct ASTStatement : ASTNode {
virtual void accept(ASTVisitor &) override; virtual void accept(ASTVisitor &) override;
}; };
struct ASTCompoundStmt: ASTStatement { struct ASTCompoundStmt : ASTStatement {
virtual void accept(ASTVisitor&) override final; virtual void accept(ASTVisitor &) override final;
std::vector<std::shared_ptr<ASTVarDeclaration>> local_declarations; std::vector<std::shared_ptr<ASTVarDeclaration>> local_declarations;
std::vector<std::shared_ptr<ASTStatement>> statement_list; std::vector<std::shared_ptr<ASTStatement>> statement_list;
}; };
struct ASTExpressionStmt: ASTStatement { struct ASTExpressionStmt : ASTStatement {
virtual void accept(ASTVisitor &) override final; virtual void accept(ASTVisitor &) override final;
std::shared_ptr<ASTExpression> expression; std::shared_ptr<ASTExpression> expression;
}; };
struct ASTSelectionStmt: ASTStatement { struct ASTSelectionStmt : ASTStatement {
virtual void accept(ASTVisitor &) override final; virtual void accept(ASTVisitor &) override final;
std::shared_ptr<ASTExpression> expression; std::shared_ptr<ASTExpression> expression;
std::shared_ptr<ASTStatement> if_statement; std::shared_ptr<ASTStatement> if_statement;
// should be nullptr if no else structure exists // should be nullptr if no else structure exists
std::shared_ptr<ASTStatement> else_statement; std::shared_ptr<ASTStatement> else_statement;
}; };
struct ASTIterationStmt: ASTStatement { struct ASTIterationStmt : ASTStatement {
virtual void accept(ASTVisitor &) override final; virtual void accept(ASTVisitor &) override final;
std::shared_ptr<ASTExpression> expression; std::shared_ptr<ASTExpression> expression;
std::shared_ptr<ASTStatement> statement; std::shared_ptr<ASTStatement> statement;
}; };
struct ASTReturnStmt: ASTStatement { struct ASTReturnStmt : ASTStatement {
virtual void accept(ASTVisitor &) override final; virtual void accept(ASTVisitor &) override final;
// should be nullptr if return void // should be nullptr if return void
std::shared_ptr<ASTExpression> expression; std::shared_ptr<ASTExpression> expression;
}; };
struct ASTExpression: ASTFactor { struct ASTExpression : ASTFactor {
virtual void accept(ASTVisitor &) override; virtual void accept(ASTVisitor &) override;
}; };
struct ASTAssignExpression: ASTExpression { struct ASTAssignExpression : ASTExpression {
virtual void accept(ASTVisitor &) override final; virtual void accept(ASTVisitor &) override final;
std::shared_ptr<ASTVar> var; std::shared_ptr<ASTVar> var;
std::shared_ptr<ASTExpression> expression; std::shared_ptr<ASTExpression> expression;
}; };
struct ASTSimpleExpression: ASTExpression { struct ASTSimpleExpression : ASTExpression {
virtual void accept(ASTVisitor &) override final; virtual void accept(ASTVisitor &) override final;
std::shared_ptr<ASTAdditiveExpression> additive_expression_l; std::shared_ptr<ASTAdditiveExpression> additive_expression_l;
std::shared_ptr<ASTAdditiveExpression> additive_expression_r; std::shared_ptr<ASTAdditiveExpression> additive_expression_r;
RelOp op; RelOp op;
}; };
struct ASTVar: ASTFactor { struct ASTVar : ASTFactor {
virtual void accept(ASTVisitor &) override final; virtual void accept(ASTVisitor &) override final;
std::string id; std::string id;
// nullptr if var is of int type // nullptr if var is of int type
std::shared_ptr<ASTExpression> expression; std::shared_ptr<ASTExpression> expression;
}; };
struct ASTAdditiveExpression: ASTNode { struct ASTAdditiveExpression : ASTNode {
virtual void accept(ASTVisitor &) override final; virtual void accept(ASTVisitor &) override final;
std::shared_ptr<ASTAdditiveExpression> additive_expression; std::shared_ptr<ASTAdditiveExpression> additive_expression;
AddOp op; AddOp op;
...@@ -206,14 +202,14 @@ struct ASTTerm : ASTNode { ...@@ -206,14 +202,14 @@ struct ASTTerm : ASTNode {
std::shared_ptr<ASTFactor> factor; std::shared_ptr<ASTFactor> factor;
}; };
struct ASTCall: ASTFactor { struct ASTCall : ASTFactor {
virtual void accept(ASTVisitor &) override final; virtual void accept(ASTVisitor &) override final;
std::string id; std::string id;
std::vector<std::shared_ptr<ASTExpression>> args; std::vector<std::shared_ptr<ASTExpression>> args;
}; };
class ASTVisitor { class ASTVisitor {
public: public:
virtual void visit(ASTProgram &) = 0; virtual void visit(ASTProgram &) = 0;
virtual void visit(ASTNum &) = 0; virtual void visit(ASTNum &) = 0;
virtual void visit(ASTVarDeclaration &) = 0; virtual void visit(ASTVarDeclaration &) = 0;
...@@ -233,7 +229,7 @@ public: ...@@ -233,7 +229,7 @@ public:
}; };
class ASTPrinter : public ASTVisitor { class ASTPrinter : public ASTVisitor {
public: public:
virtual void visit(ASTProgram &) override final; virtual void visit(ASTProgram &) override final;
virtual void visit(ASTNum &) override final; virtual void visit(ASTNum &) override final;
virtual void visit(ASTVarDeclaration &) override final; virtual void visit(ASTVarDeclaration &) override final;
...@@ -252,8 +248,8 @@ public: ...@@ -252,8 +248,8 @@ public:
virtual void visit(ASTCall &) override final; virtual void visit(ASTCall &) override final;
void add_depth() { depth += 2; } void add_depth() { depth += 2; }
void remove_depth() { depth -= 2; } void remove_depth() { depth -= 2; }
private:
private:
int depth = 0; int depth = 0;
}; };
#endif #endif
...@@ -96,6 +96,8 @@ class CminusfBuilder : public ASTVisitor { ...@@ -96,6 +96,8 @@ class CminusfBuilder : public ASTVisitor {
virtual void visit(ASTTerm &) override final; virtual void visit(ASTTerm &) override final;
virtual void visit(ASTCall &) override final; virtual void visit(ASTCall &) override final;
bool type_cast(Value *&, Value *&, std::string = "computation");
std::unique_ptr<IRBuilder> builder; std::unique_ptr<IRBuilder> builder;
Scope scope; Scope scope;
std::unique_ptr<Module> module; std::unique_ptr<Module> module;
......
...@@ -5,15 +5,18 @@ ...@@ -5,15 +5,18 @@
#include "cminusf_builder.hpp" #include "cminusf_builder.hpp"
#include "logging.hpp"
#define CONST_FP(num) ConstantFP::get((float)num, module.get()) #define CONST_FP(num) ConstantFP::get((float)num, module.get())
#define CONST_INT(num) ConstantInt::get(num, module.get()) #define CONST_INT(num) ConstantInt::get(num, module.get())
// TODO: Global Variable Declarations
// TODO: Global Variable Declarations
// You can define global variables here // You can define global variables here
// to store state. You can expand these // to store state. You can expand these
// definitions if you need to. // definitions if you need to.
// the latest return value
Value *cur_value = nullptr;
// function that is being built // function that is being built
Function *cur_fun = nullptr; Function *cur_fun = nullptr;
...@@ -33,6 +36,28 @@ Type *FLOATPTR_T; ...@@ -33,6 +36,28 @@ Type *FLOATPTR_T;
* scope.find: find and return the value bound to the name * scope.find: find and return the value bound to the name
*/ */
void error_exit(std::string s) {
LOG_ERROR << s;
std::abort();
}
// This function makes sure that
// 1. 2 values have same type
// 2. type is either int or float
// 3. return true if there is float
bool CminusfBuilder::type_cast(Value *&lvalue, Value *&rvalue, std::string util) {
if (not Type::is_eq_type(lvalue->get_type(), rvalue->get_type())) {
if (Type::is_eq_type(lvalue->get_type(), INT32_T) and Type::is_eq_type(rvalue->get_type(), FLOAT_T))
lvalue = builder->create_sitofp(lvalue, FLOAT_T);
else if (Type::is_eq_type(rvalue->get_type(), INT32_T) and Type::is_eq_type(lvalue->get_type(), FLOAT_T))
rvalue = builder->create_sitofp(rvalue, FLOAT_T);
}
// now 2 value is the same type, but we only support computing between int and float
if (not Type::is_eq_type(lvalue->get_type(), INT32_T) or not Type::is_eq_type(lvalue->get_type(), FLOAT_T))
error_exit("not supported cross-type " + util);
return Type::is_eq_type(lvalue->get_type(), FLOAT_T);
}
void CminusfBuilder::visit(ASTProgram &node) { void CminusfBuilder::visit(ASTProgram &node) {
VOID_T = Type::get_void_type(module.get()); VOID_T = Type::get_void_type(module.get());
INT1_T = Type::get_int1_type(module.get()); INT1_T = Type::get_int1_type(module.get());
...@@ -46,16 +71,73 @@ void CminusfBuilder::visit(ASTProgram &node) { ...@@ -46,16 +71,73 @@ void CminusfBuilder::visit(ASTProgram &node) {
} }
} }
// Done
void CminusfBuilder::visit(ASTNum &node) { void CminusfBuilder::visit(ASTNum &node) {
//!TODO: This function is empty now. //!TODO: This function is empty now.
// Add some code here. // Add some code here.
//
switch (node.type) {
case TYPE_INT:
cur_value = CONST_INT(node.i_val);
return;
case TYPE_FLOAT:
cur_value = CONST_FP(node.f_val);
return;
default:
error_exit("ASTNum is not int or float");
}
} }
// Done
void CminusfBuilder::visit(ASTVarDeclaration &node) { void CminusfBuilder::visit(ASTVarDeclaration &node) {
//!TODO: This function is empty now. //!TODO: This function is empty now.
// Add some code here. // Add some code here.
if (node.num) {
// declares an array
//
// get array size
node.num->accept(*this);
//
// type cast
if (Type::is_eq_type(cur_value->get_type(), FLOAT_T))
cur_value = builder->create_fptosi(cur_value, INT32_T);
int size = static_cast<ConstantInt *>(cur_value)->get_value();
if (size <= 0)
error_exit("array size[" + std::to_string(size) + "] <= 0");
switch (node.type) {
case TYPE_INT: {
auto I32Array_T = Type::get_array_type(INT32_T, size);
cur_value = builder->create_alloca(I32Array_T);
break;
}
case TYPE_FLOAT: {
auto FloatArray_T = Type::get_array_type(FLOAT_T, size);
cur_value = builder->create_alloca(FloatArray_T);
break;
}
default:
error_exit("Variable type(not array) is not int or float");
}
} else {
switch (node.type) {
case TYPE_INT:
cur_value = builder->create_alloca(INT32_T);
break;
case TYPE_FLOAT:
cur_value = builder->create_alloca(FLOAT_T);
break;
default:
error_exit("Variable type(not array) is not int or float");
}
}
if (not scope.push(node.id, cur_value))
error_exit("variable redefined: " + node.id);
} }
// Done
void CminusfBuilder::visit(ASTFunDeclaration &node) { void CminusfBuilder::visit(ASTFunDeclaration &node) {
FunctionType *fun_type; FunctionType *fun_type;
Type *ret_type; Type *ret_type;
...@@ -69,32 +151,46 @@ void CminusfBuilder::visit(ASTFunDeclaration &node) { ...@@ -69,32 +151,46 @@ void CminusfBuilder::visit(ASTFunDeclaration &node) {
for (auto &param : node.params) { for (auto &param : node.params) {
//!TODO: Please accomplish param_types. //!TODO: Please accomplish param_types.
//
// First make function BB, which needs this param type,
// then set_insert_point, we can call accept to gen code,
switch (param->type) {
case TYPE_INT:
param_types.push_back(param->isarray ? INT32PTR_T : INT32_T);
break;
case TYPE_FLOAT:
param_types.push_back(param->isarray ? FLOATPTR_T : FLOAT_T);
break;
case TYPE_VOID:
if (not param_types.empty())
error_exit("function parameters weird");
break;
}
} }
fun_type = FunctionType::get(ret_type, param_types); fun_type = FunctionType::get(ret_type, param_types);
auto fun = Function::create(fun_type, node.id, module.get()); auto fun = Function::create(fun_type, node.id, module.get());
scope.push(node.id, fun);
cur_fun = fun; cur_fun = fun;
scope.push(node.id, fun);
auto funBB = BasicBlock::create(module.get(), "entry", fun); auto funBB = BasicBlock::create(module.get(), "entry", fun);
builder->set_insert_point(funBB); builder->set_insert_point(funBB);
scope.enter(); scope.enter();
std::vector<Value *> args; std::vector<Value *> args;
for (auto arg = fun->arg_begin(); arg != fun->arg_end(); arg++) { for (auto arg = fun->arg_begin(); arg != fun->arg_end(); arg++) {
args.push_back(*arg); args.push_back(*arg);
} }
for (int i = 0; i < node.params.size(); ++i) { for (int i = 0; i < node.params.size(); ++i) {
//!TODO: You need to deal with params //!TODO: You need to deal with params
// and store them in the scope. // and store them in the scope.
cur_value = args[i];
node.params[i]->accept(*this);
} }
node.compound_stmt->accept(*this); node.compound_stmt->accept(*this);
if (builder->get_insert_block()->get_terminator() == nullptr) // default return value
{ if (builder->get_insert_block()->get_terminator() == nullptr) {
if (cur_fun->get_return_type()->is_void_type()) if (cur_fun->get_return_type()->is_void_type())
builder->create_void_ret(); builder->create_void_ret();
else if (cur_fun->get_return_type()->is_float_type()) else if (cur_fun->get_return_type()->is_float_type())
...@@ -105,16 +201,28 @@ void CminusfBuilder::visit(ASTFunDeclaration &node) { ...@@ -105,16 +201,28 @@ void CminusfBuilder::visit(ASTFunDeclaration &node) {
scope.exit(); scope.exit();
} }
// Done
void CminusfBuilder::visit(ASTParam &node) { void CminusfBuilder::visit(ASTParam &node) {
//!TODO: This function is empty now. //!TODO: This function is empty now.
// Add some code here. // If the parameter is int|float, copy and store them
switch (node.type) {
case TYPE_INT: {
scope.push(node.id, cur_value);
break;
}
case TYPE_FLOAT: {
scope.push(node.id, cur_value);
break;
}
case TYPE_VOID:
break;
}
} }
void CminusfBuilder::visit(ASTCompoundStmt &node) { void CminusfBuilder::visit(ASTCompoundStmt &node) {
//!TODO: This function is not complete. //!TODO: This function is not complete.
// You may need to add some code here // You may need to add some code here
// to deal with complex statements. // to deal with complex statements.
for (auto &decl : node.local_declarations) { for (auto &decl : node.local_declarations) {
decl->accept(*this); decl->accept(*this);
...@@ -142,43 +250,245 @@ void CminusfBuilder::visit(ASTIterationStmt &node) { ...@@ -142,43 +250,245 @@ void CminusfBuilder::visit(ASTIterationStmt &node) {
// Add some code here. // Add some code here.
} }
// Jobs:
// - call accept()
// - gen return code
void CminusfBuilder::visit(ASTReturnStmt &node) { void CminusfBuilder::visit(ASTReturnStmt &node) {
if (node.expression == nullptr) { if (node.expression == nullptr) {
builder->create_void_ret(); builder->create_void_ret();
} else { } else {
//!TODO: The given code is incomplete. //!TODO: The given code is incomplete.
// You need to solve other return cases (e.g. return an integer). // You need to solve other return cases (e.g. return an integer).
//
node.expression->accept(*this);
builder->create_ret(cur_value);
} }
} }
void CminusfBuilder::visit(ASTVar &node) { void CminusfBuilder::visit(ASTVar &node) {
//!TODO: This function is empty now. //!TODO: This function is empty now.
// Add some code here. // Add some code here.
//
// Goal: calculate address
// 1. get base
// 2. get bias if there is, and cast it if needed.
auto memory = scope.find(node.id);
Value *addr;
if (memory == nullptr) {
LOG_ERROR << node.id << " not declared!";
std::abort();
}
if (node.expression) { // a[1] = 1;
node.expression->accept(*this);
if (not Type::is_eq_type(cur_value->get_type(), INT32_T)) {
if (Type::is_eq_type(cur_value->get_type(), FLOAT_T))
cur_value = builder->create_fptosi(cur_value, INT32_T);
else {
LOG_ERROR << "unexpected type!";
std::abort();
}
}
addr = builder->create_gep(memory, {cur_value});
} else { // a = 1;
addr = memory;
}
cur_value = addr;
} }
void CminusfBuilder::visit(ASTAssignExpression &node) { void CminusfBuilder::visit(ASTAssignExpression &node) {
//!TODO: This function is empty now. //!TODO: This function is empty now.
// Add some code here. // Add some code here.
//
// 1. For assignment, both side should have a vaule,
// the left side has an addr, right side have the correspond value
// 2. Type cast!!!
//
//
// This accept() should update `cur_value` to the left value
node.var->accept(*this);
auto left = cur_value;
// This accept() should update `cur_value` to the right value
node.expression->accept(*this);
// type cast
auto type = scope.find(node.var->id)->get_type();
if (not Type::is_eq_type(type, cur_value->get_type())) {
if (type->is_pointer_type())
cur_value = builder->create_fptosi(cur_value, INT32_T);
else if (type->is_float_type())
cur_value = builder->create_sitofp(cur_value, FLOAT_T);
else {
LOG(ERROR) << "Bad assignment!";
std::abort();
}
}
// gen code
builder->create_store(left, cur_value);
} }
// Done
void CminusfBuilder::visit(ASTSimpleExpression &node) { void CminusfBuilder::visit(ASTSimpleExpression &node) {
//!TODO: This function is empty now. //!TODO: This function is empty now.
// Add some code here. // Add some code here.
//
node.additive_expression_l->accept(*this);
if (node.additive_expression_r) {
auto lvalue = cur_value;
node.additive_expression_r->accept(*this);
auto rvalue = cur_value;
// type cast
bool float_cmp = type_cast(lvalue, rvalue, "cmp");
switch (node.op) {
case OP_LE: {
if (float_cmp)
cur_value = builder->create_fcmp_le(lvalue, rvalue);
else
cur_value = builder->create_icmp_le(lvalue, rvalue);
break;
}
case OP_LT: {
if (float_cmp)
cur_value = builder->create_fcmp_lt(lvalue, rvalue);
else
cur_value = builder->create_icmp_lt(lvalue, rvalue);
break;
}
case OP_GT: {
if (float_cmp)
cur_value = builder->create_fcmp_gt(lvalue, rvalue);
else
cur_value = builder->create_icmp_gt(lvalue, rvalue);
break;
}
case OP_GE: {
if (float_cmp)
cur_value = builder->create_fcmp_ge(lvalue, rvalue);
else
cur_value = builder->create_icmp_ge(lvalue, rvalue);
break;
}
case OP_EQ: {
if (float_cmp)
cur_value = builder->create_fcmp_eq(lvalue, rvalue);
else
cur_value = builder->create_icmp_eq(lvalue, rvalue);
break;
}
case OP_NEQ: {
if (float_cmp)
cur_value = builder->create_fcmp_ne(lvalue, rvalue);
else
cur_value = builder->create_icmp_ne(lvalue, rvalue);
break;
}
}
}
} }
// Done
void CminusfBuilder::visit(ASTAdditiveExpression &node) { void CminusfBuilder::visit(ASTAdditiveExpression &node) {
//!TODO: This function is empty now. //!TODO: This function is empty now.
// Add some code here. // Add some code here.
//
node.term->accept(*this);
if (node.additive_expression) {
auto lvalue = cur_value;
node.additive_expression->accept(*this);
auto rvalue = cur_value;
// type cast
bool float_type = type_cast(lvalue, rvalue, "addop");
// now left and right is the same type
switch (node.op) {
case OP_PLUS: {
if (float_type)
cur_value = builder->create_fadd(lvalue, rvalue);
else
cur_value = builder->create_iadd(lvalue, rvalue);
break;
}
case OP_MINUS: {
if (float_type)
cur_value = builder->create_fsub(lvalue, rvalue);
else
cur_value = builder->create_isub(lvalue, rvalue);
break;
}
}
}
} }
// Done
void CminusfBuilder::visit(ASTTerm &node) { void CminusfBuilder::visit(ASTTerm &node) {
//!TODO: This function is empty now. //!TODO: This function is empty now.
// Add some code here. // Add some code here.
node.factor->accept(*this);
if (node.term) {
auto lvalue = cur_value;
node.term->accept(*this);
auto rvalue = cur_value;
// type cast
bool float_type = type_cast(lvalue, rvalue, "mulop");
// now left and right is the same type
switch (node.op) {
case OP_MUL: {
if (float_type)
cur_value = builder->create_fmul(lvalue, rvalue);
else
cur_value = builder->create_imul(lvalue, rvalue);
break;
}
case OP_DIV: {
if (float_type)
cur_value = builder->create_fdiv(lvalue, rvalue);
else
cur_value = builder->create_isdiv(lvalue, rvalue);
break;
}
}
}
} }
// Done
void CminusfBuilder::visit(ASTCall &node) { void CminusfBuilder::visit(ASTCall &node) {
//!TODO: This function is empty now. //!TODO: This function is empty now.
// Add some code here. // Add some code here.
Function *func = static_cast<Function *>(scope.find(node.id));
std::vector<Value *> args;
if (func == nullptr)
error_exit("function " + node.id + " not declared");
if (node.args.size() != func->get_num_of_args())
error_exit("expect " + std::to_string(func->get_num_of_args()) + " params, but " +
std::to_string(node.args.size()) + " is given");
for (int i = 0; i != node.args.size(); ++i) {
Type *param_type = func->get_function_type()->get_param_type(i);
node.args[i]->accept(*this);
// type cast
if (not Type::is_eq_type(param_type, cur_value->get_type())) {
if (param_type->is_pointer_type()) {
if (not Type::is_eq_type(param_type->get_pointer_element_type(),
cur_value->get_type()->get_array_element_type()))
error_exit("expected right pointer type");
// int[] to int* or float[] to flot*
cur_value = builder->create_gep(cur_value, {0, 0});
} else if (param_type->is_integer_type() or param_type->is_float_type()) {
// need type cast between int and float
if (Type::is_eq_type(cur_value->get_type(), INT32_T))
cur_value = builder->create_sitofp(cur_value, FLOAT_T);
else if (Type::is_eq_type(cur_value->get_type(), FLOAT_T))
cur_value = builder->create_fptosi(cur_value, INT32_T);
else
error_exit("unexpected type cast!");
} else
error_exit("unexpected case when casting arguments for function call" + node.id);
}
// now cur_value fits the param type
args.push_back(cur_value);
}
cur_value = builder->create_call(func, args);
} }
#include "cminusf_builder.hpp" #include "cminusf_builder.hpp"
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <memory> #include <memory>
...@@ -6,11 +7,10 @@ ...@@ -6,11 +7,10 @@
using namespace std::literals::string_literals; using namespace std::literals::string_literals;
void print_help(std::string exe_name) { void print_help(std::string exe_name) {
std::cout << "Usage: " << exe_name << std::cout << "Usage: " << exe_name << " [ -h | --help ] [ -o <target-file> ] [ -emit-llvm ] <input-file>"
" [ -h | --help ] [ -o <target-file> ] [ -emit-llvm ] <input-file>" << std::endl; << std::endl;
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
std::string target_path; std::string target_path;
std::string input_path; std::string input_path;
......
#include "ast.hpp" #include "ast.hpp"
#include <cstring> #include <cstring>
#include <stack>
#include <iostream> #include <iostream>
#define _AST_NODE_ERROR_ \ #include <stack>
std::cerr << "Abort due to node cast error."\ #define _AST_NODE_ERROR_ \
"Contact with TAs to solve your problem."\ std::cerr << "Abort due to node cast error." \
<< std::endl;\ "Contact with TAs to solve your problem." \
<< std::endl; \
std::abort(); std::abort();
#define _STR_EQ(a, b) (strcmp((a), (b)) == 0) #define _STR_EQ(a, b) (strcmp((a), (b)) == 0)
void AST::run_visitor(ASTVisitor &visitor) { void AST::run_visitor(ASTVisitor &visitor) { root->accept(visitor); }
root->accept(visitor);
}
AST::AST(syntax_tree* s) { AST::AST(syntax_tree *s) {
if (s == nullptr) { if (s == nullptr) {
std::cerr << "empty input tree!" << std::endl; std::cerr << "empty input tree!" << std::endl;
std::abort(); std::abort();
} }
auto node = transform_node_iter(s->root); auto node = transform_node_iter(s->root);
del_syntax_tree(s); del_syntax_tree(s);
root = std::shared_ptr<ASTProgram>( root = std::shared_ptr<ASTProgram>(static_cast<ASTProgram *>(node));
static_cast<ASTProgram *>(node));
} }
ASTNode * ASTNode *AST::transform_node_iter(syntax_tree_node *n) {
AST::transform_node_iter(syntax_tree_node *n) {
if (_STR_EQ(n->name, "program")) { if (_STR_EQ(n->name, "program")) {
auto node = new ASTProgram(); auto node = new ASTProgram();
...@@ -39,11 +36,9 @@ AST::transform_node_iter(syntax_tree_node *n) { ...@@ -39,11 +36,9 @@ AST::transform_node_iter(syntax_tree_node *n) {
s.push(list_ptr->children[0]); s.push(list_ptr->children[0]);
while (!s.empty()) { while (!s.empty()) {
auto child_node = static_cast<ASTDeclaration*>( auto child_node = static_cast<ASTDeclaration *>(transform_node_iter(s.top()));
transform_node_iter(s.top()));
auto child_node_shared = auto child_node_shared = std::shared_ptr<ASTDeclaration>(child_node);
std::shared_ptr<ASTDeclaration>(child_node);
node->declarations.push_back(child_node_shared); node->declarations.push_back(child_node_shared);
s.pop(); s.pop();
} }
...@@ -57,7 +52,7 @@ AST::transform_node_iter(syntax_tree_node *n) { ...@@ -57,7 +52,7 @@ AST::transform_node_iter(syntax_tree_node *n) {
node->type = TYPE_INT; node->type = TYPE_INT;
else else
node->type = TYPE_FLOAT; node->type = TYPE_FLOAT;
if (n->children_num == 3) { if (n->children_num == 3) {
node->id = n->children[1]->name; node->id = n->children[1]->name;
} else if (n->children_num == 6) { } else if (n->children_num == 6) {
...@@ -97,19 +92,15 @@ AST::transform_node_iter(syntax_tree_node *n) { ...@@ -97,19 +92,15 @@ AST::transform_node_iter(syntax_tree_node *n) {
s.push(list_ptr->children[0]); s.push(list_ptr->children[0]);
while (!s.empty()) { while (!s.empty()) {
auto child_node = static_cast<ASTParam*>( auto child_node = static_cast<ASTParam *>(transform_node_iter(s.top()));
transform_node_iter(s.top()));
auto child_node_shared = auto child_node_shared = std::shared_ptr<ASTParam>(child_node);
std::shared_ptr<ASTParam>(child_node);
node->params.push_back(child_node_shared); node->params.push_back(child_node_shared);
s.pop(); s.pop();
} }
} }
auto stmt_node = auto stmt_node = static_cast<ASTCompoundStmt *>(transform_node_iter(n->children[5]));
static_cast<ASTCompoundStmt *>(
transform_node_iter(n->children[5]));
node->compound_stmt = std::shared_ptr<ASTCompoundStmt>(stmt_node); node->compound_stmt = std::shared_ptr<ASTCompoundStmt>(stmt_node);
return node; return node;
} else if (_STR_EQ(n->name, "param")) { } else if (_STR_EQ(n->name, "param")) {
...@@ -134,16 +125,14 @@ AST::transform_node_iter(syntax_tree_node *n) { ...@@ -134,16 +125,14 @@ AST::transform_node_iter(syntax_tree_node *n) {
} }
while (!s.empty()) { while (!s.empty()) {
auto decl_node = auto decl_node = static_cast<ASTVarDeclaration *>(transform_node_iter(s.top()));
static_cast<ASTVarDeclaration*>(
transform_node_iter(s.top()));
auto decl_node_ptr = std::shared_ptr<ASTVarDeclaration>(decl_node); auto decl_node_ptr = std::shared_ptr<ASTVarDeclaration>(decl_node);
node->local_declarations.push_back(decl_node_ptr); node->local_declarations.push_back(decl_node_ptr);
s.pop(); s.pop();
} }
} }
if (n->children[2]->children_num == 2) { if (n->children[2]->children_num == 2) {
// flatten statement-list // flatten statement-list
auto list_ptr = n->children[2]; auto list_ptr = n->children[2];
std::stack<syntax_tree_node *> s; std::stack<syntax_tree_node *> s;
...@@ -153,9 +142,7 @@ AST::transform_node_iter(syntax_tree_node *n) { ...@@ -153,9 +142,7 @@ AST::transform_node_iter(syntax_tree_node *n) {
} }
while (!s.empty()) { while (!s.empty()) {
auto stmt_node = auto stmt_node = static_cast<ASTStatement *>(transform_node_iter(s.top()));
static_cast<ASTStatement *>(
transform_node_iter(s.top()));
auto stmt_node_ptr = std::shared_ptr<ASTStatement>(stmt_node); auto stmt_node_ptr = std::shared_ptr<ASTStatement>(stmt_node);
node->statement_list.push_back(stmt_node_ptr); node->statement_list.push_back(stmt_node_ptr);
s.pop(); s.pop();
...@@ -167,9 +154,7 @@ AST::transform_node_iter(syntax_tree_node *n) { ...@@ -167,9 +154,7 @@ AST::transform_node_iter(syntax_tree_node *n) {
} else if (_STR_EQ(n->name, "expression-stmt")) { } else if (_STR_EQ(n->name, "expression-stmt")) {
auto node = new ASTExpressionStmt(); auto node = new ASTExpressionStmt();
if (n->children_num == 2) { if (n->children_num == 2) {
auto expr_node = auto expr_node = static_cast<ASTExpression *>(transform_node_iter(n->children[0]));
static_cast<ASTExpression *>(
transform_node_iter(n->children[0]));
auto expr_node_ptr = std::shared_ptr<ASTExpression>(expr_node); auto expr_node_ptr = std::shared_ptr<ASTExpression>(expr_node);
node->expression = expr_node_ptr; node->expression = expr_node_ptr;
...@@ -178,24 +163,18 @@ AST::transform_node_iter(syntax_tree_node *n) { ...@@ -178,24 +163,18 @@ AST::transform_node_iter(syntax_tree_node *n) {
} else if (_STR_EQ(n->name, "selection-stmt")) { } else if (_STR_EQ(n->name, "selection-stmt")) {
auto node = new ASTSelectionStmt(); auto node = new ASTSelectionStmt();
auto expr_node = auto expr_node = static_cast<ASTExpression *>(transform_node_iter(n->children[2]));
static_cast<ASTExpression *>(
transform_node_iter(n->children[2]));
auto expr_node_ptr = std::shared_ptr<ASTExpression>(expr_node); auto expr_node_ptr = std::shared_ptr<ASTExpression>(expr_node);
node->expression = expr_node_ptr; node->expression = expr_node_ptr;
auto if_stmt_node = auto if_stmt_node = static_cast<ASTStatement *>(transform_node_iter(n->children[4]));
static_cast<ASTStatement *>(
transform_node_iter(n->children[4]));
auto if_stmt_node_ptr = std::shared_ptr<ASTStatement>(if_stmt_node); auto if_stmt_node_ptr = std::shared_ptr<ASTStatement>(if_stmt_node);
node->if_statement = if_stmt_node_ptr; node->if_statement = if_stmt_node_ptr;
// check whether this selection statement contains // check whether this selection statement contains
// else structure // else structure
if (n->children_num == 7) { if (n->children_num == 7) {
auto else_stmt_node = auto else_stmt_node = static_cast<ASTStatement *>(transform_node_iter(n->children[6]));
static_cast<ASTStatement *>(
transform_node_iter(n->children[6]));
auto else_stmt_node_ptr = std::shared_ptr<ASTStatement>(else_stmt_node); auto else_stmt_node_ptr = std::shared_ptr<ASTStatement>(else_stmt_node);
node->else_statement = else_stmt_node_ptr; node->else_statement = else_stmt_node_ptr;
} }
...@@ -204,15 +183,11 @@ AST::transform_node_iter(syntax_tree_node *n) { ...@@ -204,15 +183,11 @@ AST::transform_node_iter(syntax_tree_node *n) {
} else if (_STR_EQ(n->name, "iteration-stmt")) { } else if (_STR_EQ(n->name, "iteration-stmt")) {
auto node = new ASTIterationStmt(); auto node = new ASTIterationStmt();
auto expr_node = auto expr_node = static_cast<ASTExpression *>(transform_node_iter(n->children[2]));
static_cast<ASTExpression *>(
transform_node_iter(n->children[2]));
auto expr_node_ptr = std::shared_ptr<ASTExpression>(expr_node); auto expr_node_ptr = std::shared_ptr<ASTExpression>(expr_node);
node->expression = expr_node_ptr; node->expression = expr_node_ptr;
auto stmt_node = auto stmt_node = static_cast<ASTStatement *>(transform_node_iter(n->children[4]));
static_cast<ASTStatement *>(
transform_node_iter(n->children[4]));
auto stmt_node_ptr = std::shared_ptr<ASTStatement>(stmt_node); auto stmt_node_ptr = std::shared_ptr<ASTStatement>(stmt_node);
node->statement = stmt_node_ptr; node->statement = stmt_node_ptr;
...@@ -220,11 +195,8 @@ AST::transform_node_iter(syntax_tree_node *n) { ...@@ -220,11 +195,8 @@ AST::transform_node_iter(syntax_tree_node *n) {
} else if (_STR_EQ(n->name, "return-stmt")) { } else if (_STR_EQ(n->name, "return-stmt")) {
auto node = new ASTReturnStmt(); auto node = new ASTReturnStmt();
if (n->children_num == 3) { if (n->children_num == 3) {
auto expr_node = auto expr_node = static_cast<ASTExpression *>(transform_node_iter(n->children[1]));
static_cast<ASTExpression *>( node->expression = std::shared_ptr<ASTExpression>(expr_node);
transform_node_iter(n->children[1]));
node->expression =
std::shared_ptr<ASTExpression>(expr_node);
} }
return node; return node;
} else if (_STR_EQ(n->name, "expression")) { } else if (_STR_EQ(n->name, "expression")) {
...@@ -234,36 +206,25 @@ AST::transform_node_iter(syntax_tree_node *n) { ...@@ -234,36 +206,25 @@ AST::transform_node_iter(syntax_tree_node *n) {
} }
auto node = new ASTAssignExpression(); auto node = new ASTAssignExpression();
auto var_node = auto var_node = static_cast<ASTVar *>(transform_node_iter(n->children[0]));
static_cast<ASTVar *>(
transform_node_iter(n->children[0]));
node->var = std::shared_ptr<ASTVar>(var_node); node->var = std::shared_ptr<ASTVar>(var_node);
auto expr_node = auto expr_node = static_cast<ASTExpression *>(transform_node_iter(n->children[2]));
static_cast<ASTExpression *>( node->expression = std::shared_ptr<ASTExpression>(expr_node);
transform_node_iter(n->children[2]));
node->expression =
std::shared_ptr<ASTExpression>(expr_node);
return node; return node;
} else if (_STR_EQ(n->name, "var")) { } else if (_STR_EQ(n->name, "var")) {
auto node = new ASTVar(); auto node = new ASTVar();
node->id = n->children[0]->name; node->id = n->children[0]->name;
if (n->children_num == 4) { if (n->children_num == 4) {
auto expr_node = auto expr_node = static_cast<ASTExpression *>(transform_node_iter(n->children[2]));
static_cast<ASTExpression *>( node->expression = std::shared_ptr<ASTExpression>(expr_node);
transform_node_iter(n->children[2]));
node->expression =
std::shared_ptr<ASTExpression>(expr_node);
} }
return node; return node;
} else if (_STR_EQ(n->name, "simple-expression")) { } else if (_STR_EQ(n->name, "simple-expression")) {
auto node = new ASTSimpleExpression(); auto node = new ASTSimpleExpression();
auto expr_node_1 = auto expr_node_1 = static_cast<ASTAdditiveExpression *>(transform_node_iter(n->children[0]));
static_cast<ASTAdditiveExpression *>( node->additive_expression_l = std::shared_ptr<ASTAdditiveExpression>(expr_node_1);
transform_node_iter(n->children[0]));
node->additive_expression_l =
std::shared_ptr<ASTAdditiveExpression>(expr_node_1);
if (n->children_num == 3) { if (n->children_num == 3) {
auto op_name = n->children[1]->children[0]->name; auto op_name = n->children[1]->children[0]->name;
...@@ -280,21 +241,15 @@ AST::transform_node_iter(syntax_tree_node *n) { ...@@ -280,21 +241,15 @@ AST::transform_node_iter(syntax_tree_node *n) {
else if (_STR_EQ(op_name, "!=")) else if (_STR_EQ(op_name, "!="))
node->op = OP_NEQ; node->op = OP_NEQ;
auto expr_node_2 = auto expr_node_2 = static_cast<ASTAdditiveExpression *>(transform_node_iter(n->children[2]));
static_cast<ASTAdditiveExpression *>( node->additive_expression_r = std::shared_ptr<ASTAdditiveExpression>(expr_node_2);
transform_node_iter(n->children[2]));
node->additive_expression_r =
std::shared_ptr<ASTAdditiveExpression>(expr_node_2);
} }
return node; return node;
} else if (_STR_EQ(n->name, "additive-expression")) { } else if (_STR_EQ(n->name, "additive-expression")) {
auto node = new ASTAdditiveExpression(); auto node = new ASTAdditiveExpression();
if (n->children_num == 3) { if (n->children_num == 3) {
auto add_expr_node = auto add_expr_node = static_cast<ASTAdditiveExpression *>(transform_node_iter(n->children[0]));
static_cast<ASTAdditiveExpression *>( node->additive_expression = std::shared_ptr<ASTAdditiveExpression>(add_expr_node);
transform_node_iter(n->children[0]));
node->additive_expression =
std::shared_ptr<ASTAdditiveExpression>(add_expr_node);
auto op_name = n->children[1]->children[0]->name; auto op_name = n->children[1]->children[0]->name;
if (_STR_EQ(op_name, "+")) if (_STR_EQ(op_name, "+"))
...@@ -302,25 +257,18 @@ AST::transform_node_iter(syntax_tree_node *n) { ...@@ -302,25 +257,18 @@ AST::transform_node_iter(syntax_tree_node *n) {
else if (_STR_EQ(op_name, "-")) else if (_STR_EQ(op_name, "-"))
node->op = OP_MINUS; node->op = OP_MINUS;
auto term_node = auto term_node = static_cast<ASTTerm *>(transform_node_iter(n->children[2]));
static_cast<ASTTerm *>(
transform_node_iter(n->children[2]));
node->term = std::shared_ptr<ASTTerm>(term_node); node->term = std::shared_ptr<ASTTerm>(term_node);
} else { } else {
auto term_node = auto term_node = static_cast<ASTTerm *>(transform_node_iter(n->children[0]));
static_cast<ASTTerm *>(
transform_node_iter(n->children[0]));
node->term = std::shared_ptr<ASTTerm>(term_node); node->term = std::shared_ptr<ASTTerm>(term_node);
} }
return node; return node;
} else if (_STR_EQ(n->name, "term")) { } else if (_STR_EQ(n->name, "term")) {
auto node = new ASTTerm(); auto node = new ASTTerm();
if (n->children_num == 3) { if (n->children_num == 3) {
auto term_node = auto term_node = static_cast<ASTTerm *>(transform_node_iter(n->children[0]));
static_cast<ASTTerm *>( node->term = std::shared_ptr<ASTTerm>(term_node);
transform_node_iter(n->children[0]));
node->term =
std::shared_ptr<ASTTerm>(term_node);
auto op_name = n->children[1]->children[0]->name; auto op_name = n->children[1]->children[0]->name;
if (_STR_EQ(op_name, "*")) if (_STR_EQ(op_name, "*"))
...@@ -328,14 +276,10 @@ AST::transform_node_iter(syntax_tree_node *n) { ...@@ -328,14 +276,10 @@ AST::transform_node_iter(syntax_tree_node *n) {
else if (_STR_EQ(op_name, "/")) else if (_STR_EQ(op_name, "/"))
node->op = OP_DIV; node->op = OP_DIV;
auto factor_node = auto factor_node = static_cast<ASTFactor *>(transform_node_iter(n->children[2]));
static_cast<ASTFactor *>(
transform_node_iter(n->children[2]));
node->factor = std::shared_ptr<ASTFactor>(factor_node); node->factor = std::shared_ptr<ASTFactor>(factor_node);
} else { } else {
auto factor_node = auto factor_node = static_cast<ASTFactor *>(transform_node_iter(n->children[0]));
static_cast<ASTFactor *>(
transform_node_iter(n->children[0]));
node->factor = std::shared_ptr<ASTFactor>(factor_node); node->factor = std::shared_ptr<ASTFactor>(factor_node);
} }
return node; return node;
...@@ -344,9 +288,7 @@ AST::transform_node_iter(syntax_tree_node *n) { ...@@ -344,9 +288,7 @@ AST::transform_node_iter(syntax_tree_node *n) {
if (n->children_num == 3) if (n->children_num == 3)
i = 1; i = 1;
auto name = n->children[i]->name; auto name = n->children[i]->name;
if (_STR_EQ(name, "expression") || if (_STR_EQ(name, "expression") || _STR_EQ(name, "var") || _STR_EQ(name, "call"))
_STR_EQ(name, "var") ||
_STR_EQ(name, "call"))
return transform_node_iter(n->children[i]); return transform_node_iter(n->children[i]);
else { else {
auto num_node = new ASTNum(); auto num_node = new ASTNum();
...@@ -375,11 +317,8 @@ AST::transform_node_iter(syntax_tree_node *n) { ...@@ -375,11 +317,8 @@ AST::transform_node_iter(syntax_tree_node *n) {
s.push(list_ptr->children[0]); s.push(list_ptr->children[0]);
while (!s.empty()) { while (!s.empty()) {
auto expr_node = auto expr_node = static_cast<ASTExpression *>(transform_node_iter(s.top()));
static_cast<ASTExpression *>( auto expr_node_ptr = std::shared_ptr<ASTExpression>(expr_node);
transform_node_iter(s.top()));
auto expr_node_ptr =
std::shared_ptr<ASTExpression>(expr_node);
node->args.push_back(expr_node_ptr); node->args.push_back(expr_node_ptr);
s.pop(); s.pop();
} }
...@@ -409,29 +348,25 @@ void ASTTerm::accept(ASTVisitor &visitor) { visitor.visit(*this); } ...@@ -409,29 +348,25 @@ void ASTTerm::accept(ASTVisitor &visitor) { visitor.visit(*this); }
void ASTCall::accept(ASTVisitor &visitor) { visitor.visit(*this); } void ASTCall::accept(ASTVisitor &visitor) { visitor.visit(*this); }
void ASTFactor::accept(ASTVisitor &visitor) { void ASTFactor::accept(ASTVisitor &visitor) {
auto expr = auto expr = dynamic_cast<ASTExpression *>(this);
dynamic_cast<ASTExpression *>(this);
if (expr) { if (expr) {
expr->accept(visitor); expr->accept(visitor);
return; return;
} }
auto var = auto var = dynamic_cast<ASTVar *>(this);
dynamic_cast<ASTVar *>(this);
if (var) { if (var) {
var->accept(visitor); var->accept(visitor);
return; return;
} }
auto call = auto call = dynamic_cast<ASTCall *>(this);
dynamic_cast<ASTCall *>(this);
if (call) { if (call) {
call->accept(visitor); call->accept(visitor);
return; return;
} }
auto num = auto num = dynamic_cast<ASTNum *>(this);
dynamic_cast<ASTNum *>(this);
if (num) { if (num) {
num->accept(visitor); num->accept(visitor);
return; return;
...@@ -441,14 +376,12 @@ void ASTFactor::accept(ASTVisitor &visitor) { ...@@ -441,14 +376,12 @@ void ASTFactor::accept(ASTVisitor &visitor) {
} }
void ASTDeclaration::accept(ASTVisitor &visitor) { void ASTDeclaration::accept(ASTVisitor &visitor) {
auto var_decl = auto var_decl = dynamic_cast<ASTVarDeclaration *>(this);
dynamic_cast<ASTVarDeclaration *>(this);
if (var_decl) { if (var_decl) {
var_decl->accept(visitor); var_decl->accept(visitor);
return; return;
} }
auto fun_decl = auto fun_decl = dynamic_cast<ASTFunDeclaration *>(this);
dynamic_cast<ASTFunDeclaration *>(this);
if (fun_decl) { if (fun_decl) {
fun_decl->accept(visitor); fun_decl->accept(visitor);
return; return;
...@@ -457,36 +390,31 @@ void ASTDeclaration::accept(ASTVisitor &visitor) { ...@@ -457,36 +390,31 @@ void ASTDeclaration::accept(ASTVisitor &visitor) {
} }
void ASTStatement::accept(ASTVisitor &visitor) { void ASTStatement::accept(ASTVisitor &visitor) {
auto comp_stmt = auto comp_stmt = dynamic_cast<ASTCompoundStmt *>(this);
dynamic_cast<ASTCompoundStmt *>(this);
if (comp_stmt) { if (comp_stmt) {
comp_stmt->accept(visitor); comp_stmt->accept(visitor);
return; return;
} }
auto expr_stmt = auto expr_stmt = dynamic_cast<ASTExpressionStmt *>(this);
dynamic_cast<ASTExpressionStmt *>(this);
if (expr_stmt) { if (expr_stmt) {
expr_stmt->accept(visitor); expr_stmt->accept(visitor);
return; return;
} }
auto sele_stmt = auto sele_stmt = dynamic_cast<ASTSelectionStmt *>(this);
dynamic_cast<ASTSelectionStmt *>(this);
if (sele_stmt) { if (sele_stmt) {
sele_stmt->accept(visitor); sele_stmt->accept(visitor);
return; return;
} }
auto iter_stmt = auto iter_stmt = dynamic_cast<ASTIterationStmt *>(this);
dynamic_cast<ASTIterationStmt *>(this);
if (iter_stmt) { if (iter_stmt) {
iter_stmt->accept(visitor); iter_stmt->accept(visitor);
return; return;
} }
auto ret_stmt = auto ret_stmt = dynamic_cast<ASTReturnStmt *>(this);
dynamic_cast<ASTReturnStmt *>(this);
if (ret_stmt) { if (ret_stmt) {
ret_stmt->accept(visitor); ret_stmt->accept(visitor);
return; return;
...@@ -495,15 +423,13 @@ void ASTStatement::accept(ASTVisitor &visitor) { ...@@ -495,15 +423,13 @@ void ASTStatement::accept(ASTVisitor &visitor) {
} }
void ASTExpression::accept(ASTVisitor &visitor) { void ASTExpression::accept(ASTVisitor &visitor) {
auto simple_expr = auto simple_expr = dynamic_cast<ASTSimpleExpression *>(this);
dynamic_cast<ASTSimpleExpression *>(this);
if (simple_expr) { if (simple_expr) {
simple_expr->accept(visitor); simple_expr->accept(visitor);
return; return;
} }
auto assign_expr = auto assign_expr = dynamic_cast<ASTAssignExpression *>(this);
dynamic_cast<ASTAssignExpression *>(this);
if (assign_expr) { if (assign_expr) {
assign_expr->accept(visitor); assign_expr->accept(visitor);
return; return;
...@@ -511,15 +437,14 @@ void ASTExpression::accept(ASTVisitor &visitor) { ...@@ -511,15 +437,14 @@ void ASTExpression::accept(ASTVisitor &visitor) {
_AST_NODE_ERROR_ _AST_NODE_ERROR_
} }
#define _DEBUG_PRINT_N_(N) {\ #define _DEBUG_PRINT_N_(N) \
std::cout << std::string(N, '-');\ { std::cout << std::string(N, '-'); }
}
void ASTPrinter::visit(ASTProgram &node) { void ASTPrinter::visit(ASTProgram &node) {
_DEBUG_PRINT_N_(depth); _DEBUG_PRINT_N_(depth);
std::cout << "program" << std::endl; std::cout << "program" << std::endl;
add_depth(); add_depth();
for (auto decl: node.declarations) { for (auto decl : node.declarations) {
decl->accept(*this); decl->accept(*this);
} }
remove_depth(); remove_depth();
...@@ -534,7 +459,6 @@ void ASTPrinter::visit(ASTNum &node) { ...@@ -534,7 +459,6 @@ void ASTPrinter::visit(ASTNum &node) {
} else { } else {
_AST_NODE_ERROR_ _AST_NODE_ERROR_
} }
} }
void ASTPrinter::visit(ASTVarDeclaration &node) { void ASTPrinter::visit(ASTVarDeclaration &node) {
...@@ -554,7 +478,7 @@ void ASTPrinter::visit(ASTFunDeclaration &node) { ...@@ -554,7 +478,7 @@ void ASTPrinter::visit(ASTFunDeclaration &node) {
_DEBUG_PRINT_N_(depth); _DEBUG_PRINT_N_(depth);
std::cout << "fun-declaration: " << node.id << std::endl; std::cout << "fun-declaration: " << node.id << std::endl;
add_depth(); add_depth();
for (auto param: node.params) { for (auto param : node.params) {
param->accept(*this); param->accept(*this);
} }
...@@ -574,11 +498,11 @@ void ASTPrinter::visit(ASTCompoundStmt &node) { ...@@ -574,11 +498,11 @@ void ASTPrinter::visit(ASTCompoundStmt &node) {
_DEBUG_PRINT_N_(depth); _DEBUG_PRINT_N_(depth);
std::cout << "compound-stmt" << std::endl; std::cout << "compound-stmt" << std::endl;
add_depth(); add_depth();
for (auto decl: node.local_declarations) { for (auto decl : node.local_declarations) {
decl->accept(*this); decl->accept(*this);
} }
for (auto stmt: node.statement_list) { for (auto stmt : node.statement_list) {
stmt->accept(*this); stmt->accept(*this);
} }
remove_depth(); remove_depth();
...@@ -600,7 +524,7 @@ void ASTPrinter::visit(ASTSelectionStmt &node) { ...@@ -600,7 +524,7 @@ void ASTPrinter::visit(ASTSelectionStmt &node) {
node.expression->accept(*this); node.expression->accept(*this);
node.if_statement->accept(*this); node.if_statement->accept(*this);
if (node.else_statement != nullptr) if (node.else_statement != nullptr)
node.else_statement->accept(*this); node.else_statement->accept(*this);
remove_depth(); remove_depth();
} }
...@@ -730,7 +654,7 @@ void ASTPrinter::visit(ASTCall &node) { ...@@ -730,7 +654,7 @@ void ASTPrinter::visit(ASTCall &node) {
_DEBUG_PRINT_N_(depth); _DEBUG_PRINT_N_(depth);
std::cout << "call: " << node.id << "()" << std::endl; std::cout << "call: " << node.id << "()" << std::endl;
add_depth(); add_depth();
for (auto arg: node.args) { for (auto arg : node.args) {
arg->accept(*this); arg->accept(*this);
} }
remove_depth(); remove_depth();
......
#include "syntax_tree.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "syntax_tree.h" syntax_tree_node *new_syntax_tree_node(const char *name) {
syntax_tree_node *new_node = (syntax_tree_node *)malloc(sizeof(syntax_tree_node));
syntax_tree_node * new_syntax_tree_node(const char * name) if (name)
{ strncpy(new_node->name, name, SYNTAX_TREE_NODE_NAME_MAX);
syntax_tree_node * new_node = (syntax_tree_node *)malloc(sizeof(syntax_tree_node)); else
if (name) new_node->name[0] = '\0';
strncpy(new_node->name, name, SYNTAX_TREE_NODE_NAME_MAX); new_node->children_num = 0;
else return new_node;
new_node->name[0] = '\0';
new_node->children_num = 0;
return new_node;
} }
int syntax_tree_add_child(syntax_tree_node * parent, syntax_tree_node * child) int syntax_tree_add_child(syntax_tree_node *parent, syntax_tree_node *child) {
{ if (!parent || !child)
if (!parent || !child) return -1; return -1;
parent->children[parent->children_num++] = child; parent->children[parent->children_num++] = child;
return parent->children_num; return parent->children_num;
} }
void del_syntax_tree_node(syntax_tree_node * node, int recursive) void del_syntax_tree_node(syntax_tree_node *node, int recursive) {
{ if (!node)
if (!node) return; return;
int i; int i;
if (recursive) { if (recursive) {
for (i = 0; i < node->children_num; i++) { for (i = 0; i < node->children_num; i++) {
del_syntax_tree_node(node->children[i], 1); del_syntax_tree_node(node->children[i], 1);
} }
} }
free(node); free(node);
} }
syntax_tree * new_syntax_tree() syntax_tree *new_syntax_tree() { return (syntax_tree *)malloc(sizeof(syntax_tree)); }
{
return (syntax_tree *)malloc(sizeof(syntax_tree));
}
void del_syntax_tree(syntax_tree * tree) void del_syntax_tree(syntax_tree *tree) {
{ if (!tree)
if (!tree) return; return;
if (tree->root) { if (tree->root) {
del_syntax_tree_node(tree->root, 1); del_syntax_tree_node(tree->root, 1);
} }
free(tree); free(tree);
} }
void print_syntax_tree_node(FILE * fout, syntax_tree_node * node, int level) void print_syntax_tree_node(FILE *fout, syntax_tree_node *node, int level) {
{ // assume fout valid now
// assume fout valid now
// check if "node" empty pointer
if (!node) return;
// print myself
int i;
for (i = 0; i < level; i++) {
fprintf(fout, "| ");
}
fprintf(fout, ">--%s %s\n", (node->children_num ? "+" : "*"), node->name);
for (i = 0; i < node->children_num; i++) { // check if "node" empty pointer
print_syntax_tree_node(fout, node->children[i], level + 1); if (!node)
} return;
}
// print myself
int i;
for (i = 0; i < level; i++) {
fprintf(fout, "| ");
}
fprintf(fout, ">--%s %s\n", (node->children_num ? "+" : "*"), node->name);
void print_syntax_tree(FILE * fout, syntax_tree * tree) for (i = 0; i < node->children_num; i++) {
{ print_syntax_tree_node(fout, node->children[i], level + 1);
if (!fout) return; }
print_syntax_tree_node(fout, tree->root, 0);
} }
void print_syntax_tree(FILE *fout, syntax_tree *tree) {
if (!fout)
return;
print_syntax_tree_node(fout, tree->root, 0);
}
*.ll
clean.sh
decl_float_array
decl_float
decl_int_array
decl_int
input
output_float
output_int
return
*.ll
clean.sh
num_add_float
num_add_int
num_add_mixed
num_comp1
num_comp2
num_div_float
num_div_int
num_div_mixed
num_eq_float
num_eq_int
num_eq_mixed
num_ge_float
num_ge_int
num_ge_mixed
num_gt_float
num_gt_int
num_gt_mixed
num_le_float
num_le_int
num_le_mixed
num_lt_float
num_lt_int
num_lt_mixed
num_mul_float
num_mul_int
num_mul_mixed
num_neq_float
num_neq_int
num_neq_mixed
num_sub_float
num_sub_int
num_sub_mixed
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment