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

backup on halfway

parent 2dd8c34b
......@@ -15,8 +15,8 @@ IncludeCategories:
Priority: 2
- Regex: '.*'
Priority: 1
IndentCaseLabels: false
AllowShortCaseLabelsOnASingleLine: true
IndentCaseLabels: true
AllowShortCaseLabelsOnASingleLine: false
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: false
PenaltyReturnTypeOnItsOwnLine: 200
......
# 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 @@
#define _SYNTAX_TREE_HPP_
extern "C" {
#include "syntax_tree.h"
extern syntax_tree *parse(const char *input);
extern syntax_tree *parse(const char *input);
}
#include <vector>
#include <memory>
#include <string>
#include <vector>
enum CminusType {
TYPE_INT,
TYPE_FLOAT,
TYPE_VOID
};
enum CminusType { TYPE_INT, TYPE_FLOAT, TYPE_VOID };
enum RelOp {
// <=
......@@ -64,23 +60,24 @@ struct ASTVar;
struct ASTAssignExpression;
struct ASTSimpleExpression;
struct ASTAdditiveExpression;
struct ASTTerm ;
struct ASTTerm;
struct ASTCall;
class ASTVisitor;
class AST {
public:
public:
AST() = delete;
AST(syntax_tree *);
AST(AST &&tree) {
root = tree.root;
tree.root = nullptr;
};
ASTProgram* get_root() { return root.get(); }
void run_visitor(ASTVisitor& visitor);
private:
ASTNode* transform_node_iter(syntax_tree_node *);
ASTProgram *get_root() { return root.get(); }
void run_visitor(ASTVisitor &visitor);
private:
ASTNode *transform_node_iter(syntax_tree_node *);
std::shared_ptr<ASTProgram> root = nullptr;
};
......@@ -90,21 +87,20 @@ struct ASTNode {
struct ASTProgram : ASTNode {
virtual void accept(ASTVisitor &) override final;
std::vector<std::shared_ptr<ASTDeclaration>>
declarations;
std::vector<std::shared_ptr<ASTDeclaration>> declarations;
};
struct ASTDeclaration: ASTNode {
struct ASTDeclaration : ASTNode {
virtual void accept(ASTVisitor &) override;
CminusType type;
std::string id;
};
struct ASTFactor: ASTNode {
struct ASTFactor : ASTNode {
virtual void accept(ASTVisitor &) override;
};
struct ASTNum: ASTFactor {
struct ASTNum : ASTFactor {
virtual void accept(ASTVisitor &) override final;
CminusType type;
union {
......@@ -113,19 +109,19 @@ struct ASTNum: ASTFactor {
};
};
struct ASTVarDeclaration: ASTDeclaration {
struct ASTVarDeclaration : ASTDeclaration {
virtual void accept(ASTVisitor &) override final;
CminusType type;
std::shared_ptr<ASTNum> num;
};
struct ASTFunDeclaration: ASTDeclaration {
struct ASTFunDeclaration : ASTDeclaration {
virtual void accept(ASTVisitor &) override final;
std::vector<std::shared_ptr<ASTParam>> params;
std::shared_ptr<ASTCompoundStmt> compound_stmt;
};
struct ASTParam: ASTNode {
struct ASTParam : ASTNode {
virtual void accept(ASTVisitor &) override final;
CminusType type;
std::string id;
......@@ -137,18 +133,18 @@ struct ASTStatement : ASTNode {
virtual void accept(ASTVisitor &) override;
};
struct ASTCompoundStmt: ASTStatement {
virtual void accept(ASTVisitor&) override final;
struct ASTCompoundStmt : ASTStatement {
virtual void accept(ASTVisitor &) override final;
std::vector<std::shared_ptr<ASTVarDeclaration>> local_declarations;
std::vector<std::shared_ptr<ASTStatement>> statement_list;
};
struct ASTExpressionStmt: ASTStatement {
struct ASTExpressionStmt : ASTStatement {
virtual void accept(ASTVisitor &) override final;
std::shared_ptr<ASTExpression> expression;
};
struct ASTSelectionStmt: ASTStatement {
struct ASTSelectionStmt : ASTStatement {
virtual void accept(ASTVisitor &) override final;
std::shared_ptr<ASTExpression> expression;
std::shared_ptr<ASTStatement> if_statement;
......@@ -156,43 +152,43 @@ struct ASTSelectionStmt: ASTStatement {
std::shared_ptr<ASTStatement> else_statement;
};
struct ASTIterationStmt: ASTStatement {
struct ASTIterationStmt : ASTStatement {
virtual void accept(ASTVisitor &) override final;
std::shared_ptr<ASTExpression> expression;
std::shared_ptr<ASTStatement> statement;
};
struct ASTReturnStmt: ASTStatement {
struct ASTReturnStmt : ASTStatement {
virtual void accept(ASTVisitor &) override final;
// should be nullptr if return void
std::shared_ptr<ASTExpression> expression;
};
struct ASTExpression: ASTFactor {
struct ASTExpression : ASTFactor {
virtual void accept(ASTVisitor &) override;
};
struct ASTAssignExpression: ASTExpression {
struct ASTAssignExpression : ASTExpression {
virtual void accept(ASTVisitor &) override final;
std::shared_ptr<ASTVar> var;
std::shared_ptr<ASTExpression> expression;
};
struct ASTSimpleExpression: ASTExpression {
struct ASTSimpleExpression : ASTExpression {
virtual void accept(ASTVisitor &) override final;
std::shared_ptr<ASTAdditiveExpression> additive_expression_l;
std::shared_ptr<ASTAdditiveExpression> additive_expression_r;
RelOp op;
};
struct ASTVar: ASTFactor {
struct ASTVar : ASTFactor {
virtual void accept(ASTVisitor &) override final;
std::string id;
// nullptr if var is of int type
std::shared_ptr<ASTExpression> expression;
};
struct ASTAdditiveExpression: ASTNode {
struct ASTAdditiveExpression : ASTNode {
virtual void accept(ASTVisitor &) override final;
std::shared_ptr<ASTAdditiveExpression> additive_expression;
AddOp op;
......@@ -206,14 +202,14 @@ struct ASTTerm : ASTNode {
std::shared_ptr<ASTFactor> factor;
};
struct ASTCall: ASTFactor {
struct ASTCall : ASTFactor {
virtual void accept(ASTVisitor &) override final;
std::string id;
std::vector<std::shared_ptr<ASTExpression>> args;
};
class ASTVisitor {
public:
public:
virtual void visit(ASTProgram &) = 0;
virtual void visit(ASTNum &) = 0;
virtual void visit(ASTVarDeclaration &) = 0;
......@@ -233,7 +229,7 @@ public:
};
class ASTPrinter : public ASTVisitor {
public:
public:
virtual void visit(ASTProgram &) override final;
virtual void visit(ASTNum &) override final;
virtual void visit(ASTVarDeclaration &) override final;
......@@ -252,8 +248,8 @@ public:
virtual void visit(ASTCall &) override final;
void add_depth() { depth += 2; }
void remove_depth() { depth -= 2; }
private:
private:
int depth = 0;
};
#endif
......@@ -96,6 +96,8 @@ class CminusfBuilder : public ASTVisitor {
virtual void visit(ASTTerm &) override final;
virtual void visit(ASTCall &) override final;
bool type_cast(Value *&, Value *&, std::string = "computation");
std::unique_ptr<IRBuilder> builder;
Scope scope;
std::unique_ptr<Module> module;
......
......@@ -5,15 +5,18 @@
#include "cminusf_builder.hpp"
#include "logging.hpp"
#define CONST_FP(num) ConstantFP::get((float)num, module.get())
#define CONST_INT(num) ConstantInt::get(num, module.get())
// TODO: Global Variable Declarations
// You can define global variables here
// to store state. You can expand these
// definitions if you need to.
// the latest return value
Value *cur_value = nullptr;
// function that is being built
Function *cur_fun = nullptr;
......@@ -33,6 +36,28 @@ Type *FLOATPTR_T;
* 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_T = Type::get_void_type(module.get());
INT1_T = Type::get_int1_type(module.get());
......@@ -46,16 +71,73 @@ void CminusfBuilder::visit(ASTProgram &node) {
}
}
// Done
void CminusfBuilder::visit(ASTNum &node) {
//!TODO: This function is empty now.
// 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) {
//!TODO: This function is empty now.
// 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) {
FunctionType *fun_type;
Type *ret_type;
......@@ -69,32 +151,46 @@ void CminusfBuilder::visit(ASTFunDeclaration &node) {
for (auto &param : node.params) {
//!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);
auto fun = Function::create(fun_type, node.id, module.get());
scope.push(node.id, fun);
cur_fun = fun;
scope.push(node.id, fun);
auto funBB = BasicBlock::create(module.get(), "entry", fun);
builder->set_insert_point(funBB);
scope.enter();
std::vector<Value *> args;
for (auto arg = fun->arg_begin(); arg != fun->arg_end(); arg++) {
args.push_back(*arg);
}
for (int i = 0; i < node.params.size(); ++i) {
//!TODO: You need to deal with params
// and store them in the scope.
cur_value = args[i];
node.params[i]->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())
builder->create_void_ret();
else if (cur_fun->get_return_type()->is_float_type())
......@@ -105,9 +201,22 @@ void CminusfBuilder::visit(ASTFunDeclaration &node) {
scope.exit();
}
// Done
void CminusfBuilder::visit(ASTParam &node) {
//!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) {
......@@ -115,7 +224,6 @@ void CminusfBuilder::visit(ASTCompoundStmt &node) {
// You may need to add some code here
// to deal with complex statements.
for (auto &decl : node.local_declarations) {
decl->accept(*this);
}
......@@ -142,43 +250,245 @@ void CminusfBuilder::visit(ASTIterationStmt &node) {
// Add some code here.
}
// Jobs:
// - call accept()
// - gen return code
void CminusfBuilder::visit(ASTReturnStmt &node) {
if (node.expression == nullptr) {
builder->create_void_ret();
} else {
//!TODO: The given code is incomplete.
// 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) {
//!TODO: This function is empty now.
// 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) {
//!TODO: This function is empty now.
// 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) {
//!TODO: This function is empty now.
// 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) {
//!TODO: This function is empty now.
// 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) {
//!TODO: This function is empty now.
// 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) {
//!TODO: This function is empty now.
// 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 <fstream>
#include <iostream>
#include <memory>
......@@ -6,11 +7,10 @@
using namespace std::literals::string_literals;
void print_help(std::string exe_name) {
std::cout << "Usage: " << exe_name <<
" [ -h | --help ] [ -o <target-file> ] [ -emit-llvm ] <input-file>" << std::endl;
std::cout << "Usage: " << exe_name << " [ -h | --help ] [ -o <target-file> ] [ -emit-llvm ] <input-file>"
<< std::endl;
}
int main(int argc, char **argv) {
std::string target_path;
std::string input_path;
......
#include "ast.hpp"
#include <cstring>
#include <stack>
#include <iostream>
#include <stack>
#define _AST_NODE_ERROR_ \
std::cerr << "Abort due to node cast error."\
"Contact with TAs to solve your problem."\
<< std::endl;\
std::cerr << "Abort due to node cast error." \
"Contact with TAs to solve your problem." \
<< std::endl; \
std::abort();
#define _STR_EQ(a, b) (strcmp((a), (b)) == 0)
void AST::run_visitor(ASTVisitor &visitor) {
root->accept(visitor);
}
void AST::run_visitor(ASTVisitor &visitor) { root->accept(visitor); }
AST::AST(syntax_tree* s) {
AST::AST(syntax_tree *s) {
if (s == nullptr) {
std::cerr << "empty input tree!" << std::endl;
std::abort();
}
auto node = transform_node_iter(s->root);
del_syntax_tree(s);
root = std::shared_ptr<ASTProgram>(
static_cast<ASTProgram *>(node));
root = std::shared_ptr<ASTProgram>(static_cast<ASTProgram *>(node));
}
ASTNode *
AST::transform_node_iter(syntax_tree_node *n) {
ASTNode *AST::transform_node_iter(syntax_tree_node *n) {
if (_STR_EQ(n->name, "program")) {
auto node = new ASTProgram();
......@@ -39,11 +36,9 @@ AST::transform_node_iter(syntax_tree_node *n) {
s.push(list_ptr->children[0]);
while (!s.empty()) {
auto child_node = static_cast<ASTDeclaration*>(
transform_node_iter(s.top()));
auto child_node = static_cast<ASTDeclaration *>(transform_node_iter(s.top()));
auto child_node_shared =
std::shared_ptr<ASTDeclaration>(child_node);
auto child_node_shared = std::shared_ptr<ASTDeclaration>(child_node);
node->declarations.push_back(child_node_shared);
s.pop();
}
......@@ -97,19 +92,15 @@ AST::transform_node_iter(syntax_tree_node *n) {
s.push(list_ptr->children[0]);
while (!s.empty()) {
auto child_node = static_cast<ASTParam*>(
transform_node_iter(s.top()));
auto child_node = static_cast<ASTParam *>(transform_node_iter(s.top()));
auto child_node_shared =
std::shared_ptr<ASTParam>(child_node);
auto child_node_shared = std::shared_ptr<ASTParam>(child_node);
node->params.push_back(child_node_shared);
s.pop();
}
}
auto stmt_node =
static_cast<ASTCompoundStmt *>(
transform_node_iter(n->children[5]));
auto stmt_node = static_cast<ASTCompoundStmt *>(transform_node_iter(n->children[5]));
node->compound_stmt = std::shared_ptr<ASTCompoundStmt>(stmt_node);
return node;
} else if (_STR_EQ(n->name, "param")) {
......@@ -134,9 +125,7 @@ AST::transform_node_iter(syntax_tree_node *n) {
}
while (!s.empty()) {
auto decl_node =
static_cast<ASTVarDeclaration*>(
transform_node_iter(s.top()));
auto decl_node = static_cast<ASTVarDeclaration *>(transform_node_iter(s.top()));
auto decl_node_ptr = std::shared_ptr<ASTVarDeclaration>(decl_node);
node->local_declarations.push_back(decl_node_ptr);
s.pop();
......@@ -153,9 +142,7 @@ AST::transform_node_iter(syntax_tree_node *n) {
}
while (!s.empty()) {
auto stmt_node =
static_cast<ASTStatement *>(
transform_node_iter(s.top()));
auto stmt_node = static_cast<ASTStatement *>(transform_node_iter(s.top()));
auto stmt_node_ptr = std::shared_ptr<ASTStatement>(stmt_node);
node->statement_list.push_back(stmt_node_ptr);
s.pop();
......@@ -167,9 +154,7 @@ AST::transform_node_iter(syntax_tree_node *n) {
} else if (_STR_EQ(n->name, "expression-stmt")) {
auto node = new ASTExpressionStmt();
if (n->children_num == 2) {
auto expr_node =
static_cast<ASTExpression *>(
transform_node_iter(n->children[0]));
auto expr_node = static_cast<ASTExpression *>(transform_node_iter(n->children[0]));
auto expr_node_ptr = std::shared_ptr<ASTExpression>(expr_node);
node->expression = expr_node_ptr;
......@@ -178,24 +163,18 @@ AST::transform_node_iter(syntax_tree_node *n) {
} else if (_STR_EQ(n->name, "selection-stmt")) {
auto node = new ASTSelectionStmt();
auto expr_node =
static_cast<ASTExpression *>(
transform_node_iter(n->children[2]));
auto expr_node = static_cast<ASTExpression *>(transform_node_iter(n->children[2]));
auto expr_node_ptr = std::shared_ptr<ASTExpression>(expr_node);
node->expression = expr_node_ptr;
auto if_stmt_node =
static_cast<ASTStatement *>(
transform_node_iter(n->children[4]));
auto if_stmt_node = static_cast<ASTStatement *>(transform_node_iter(n->children[4]));
auto if_stmt_node_ptr = std::shared_ptr<ASTStatement>(if_stmt_node);
node->if_statement = if_stmt_node_ptr;
// check whether this selection statement contains
// else structure
if (n->children_num == 7) {
auto else_stmt_node =
static_cast<ASTStatement *>(
transform_node_iter(n->children[6]));
auto else_stmt_node = static_cast<ASTStatement *>(transform_node_iter(n->children[6]));
auto else_stmt_node_ptr = std::shared_ptr<ASTStatement>(else_stmt_node);
node->else_statement = else_stmt_node_ptr;
}
......@@ -204,15 +183,11 @@ AST::transform_node_iter(syntax_tree_node *n) {
} else if (_STR_EQ(n->name, "iteration-stmt")) {
auto node = new ASTIterationStmt();
auto expr_node =
static_cast<ASTExpression *>(
transform_node_iter(n->children[2]));
auto expr_node = static_cast<ASTExpression *>(transform_node_iter(n->children[2]));
auto expr_node_ptr = std::shared_ptr<ASTExpression>(expr_node);
node->expression = expr_node_ptr;
auto stmt_node =
static_cast<ASTStatement *>(
transform_node_iter(n->children[4]));
auto stmt_node = static_cast<ASTStatement *>(transform_node_iter(n->children[4]));
auto stmt_node_ptr = std::shared_ptr<ASTStatement>(stmt_node);
node->statement = stmt_node_ptr;
......@@ -220,11 +195,8 @@ AST::transform_node_iter(syntax_tree_node *n) {
} else if (_STR_EQ(n->name, "return-stmt")) {
auto node = new ASTReturnStmt();
if (n->children_num == 3) {
auto expr_node =
static_cast<ASTExpression *>(
transform_node_iter(n->children[1]));
node->expression =
std::shared_ptr<ASTExpression>(expr_node);
auto expr_node = static_cast<ASTExpression *>(transform_node_iter(n->children[1]));
node->expression = std::shared_ptr<ASTExpression>(expr_node);
}
return node;
} else if (_STR_EQ(n->name, "expression")) {
......@@ -234,36 +206,25 @@ AST::transform_node_iter(syntax_tree_node *n) {
}
auto node = new ASTAssignExpression();
auto var_node =
static_cast<ASTVar *>(
transform_node_iter(n->children[0]));
auto var_node = static_cast<ASTVar *>(transform_node_iter(n->children[0]));
node->var = std::shared_ptr<ASTVar>(var_node);
auto expr_node =
static_cast<ASTExpression *>(
transform_node_iter(n->children[2]));
node->expression =
std::shared_ptr<ASTExpression>(expr_node);
auto expr_node = static_cast<ASTExpression *>(transform_node_iter(n->children[2]));
node->expression = std::shared_ptr<ASTExpression>(expr_node);
return node;
} else if (_STR_EQ(n->name, "var")) {
auto node = new ASTVar();
node->id = n->children[0]->name;
if (n->children_num == 4) {
auto expr_node =
static_cast<ASTExpression *>(
transform_node_iter(n->children[2]));
node->expression =
std::shared_ptr<ASTExpression>(expr_node);
auto expr_node = static_cast<ASTExpression *>(transform_node_iter(n->children[2]));
node->expression = std::shared_ptr<ASTExpression>(expr_node);
}
return node;
} else if (_STR_EQ(n->name, "simple-expression")) {
auto node = new ASTSimpleExpression();
auto expr_node_1 =
static_cast<ASTAdditiveExpression *>(
transform_node_iter(n->children[0]));
node->additive_expression_l =
std::shared_ptr<ASTAdditiveExpression>(expr_node_1);
auto expr_node_1 = static_cast<ASTAdditiveExpression *>(transform_node_iter(n->children[0]));
node->additive_expression_l = std::shared_ptr<ASTAdditiveExpression>(expr_node_1);
if (n->children_num == 3) {
auto op_name = n->children[1]->children[0]->name;
......@@ -280,21 +241,15 @@ AST::transform_node_iter(syntax_tree_node *n) {
else if (_STR_EQ(op_name, "!="))
node->op = OP_NEQ;
auto expr_node_2 =
static_cast<ASTAdditiveExpression *>(
transform_node_iter(n->children[2]));
node->additive_expression_r =
std::shared_ptr<ASTAdditiveExpression>(expr_node_2);
auto expr_node_2 = static_cast<ASTAdditiveExpression *>(transform_node_iter(n->children[2]));
node->additive_expression_r = std::shared_ptr<ASTAdditiveExpression>(expr_node_2);
}
return node;
} else if (_STR_EQ(n->name, "additive-expression")) {
auto node = new ASTAdditiveExpression();
if (n->children_num == 3) {
auto add_expr_node =
static_cast<ASTAdditiveExpression *>(
transform_node_iter(n->children[0]));
node->additive_expression =
std::shared_ptr<ASTAdditiveExpression>(add_expr_node);
auto add_expr_node = static_cast<ASTAdditiveExpression *>(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;
if (_STR_EQ(op_name, "+"))
......@@ -302,25 +257,18 @@ AST::transform_node_iter(syntax_tree_node *n) {
else if (_STR_EQ(op_name, "-"))
node->op = OP_MINUS;
auto term_node =
static_cast<ASTTerm *>(
transform_node_iter(n->children[2]));
auto term_node = static_cast<ASTTerm *>(transform_node_iter(n->children[2]));
node->term = std::shared_ptr<ASTTerm>(term_node);
} else {
auto term_node =
static_cast<ASTTerm *>(
transform_node_iter(n->children[0]));
auto term_node = static_cast<ASTTerm *>(transform_node_iter(n->children[0]));
node->term = std::shared_ptr<ASTTerm>(term_node);
}
return node;
} else if (_STR_EQ(n->name, "term")) {
auto node = new ASTTerm();
if (n->children_num == 3) {
auto term_node =
static_cast<ASTTerm *>(
transform_node_iter(n->children[0]));
node->term =
std::shared_ptr<ASTTerm>(term_node);
auto term_node = static_cast<ASTTerm *>(transform_node_iter(n->children[0]));
node->term = std::shared_ptr<ASTTerm>(term_node);
auto op_name = n->children[1]->children[0]->name;
if (_STR_EQ(op_name, "*"))
......@@ -328,14 +276,10 @@ AST::transform_node_iter(syntax_tree_node *n) {
else if (_STR_EQ(op_name, "/"))
node->op = OP_DIV;
auto factor_node =
static_cast<ASTFactor *>(
transform_node_iter(n->children[2]));
auto factor_node = static_cast<ASTFactor *>(transform_node_iter(n->children[2]));
node->factor = std::shared_ptr<ASTFactor>(factor_node);
} else {
auto factor_node =
static_cast<ASTFactor *>(
transform_node_iter(n->children[0]));
auto factor_node = static_cast<ASTFactor *>(transform_node_iter(n->children[0]));
node->factor = std::shared_ptr<ASTFactor>(factor_node);
}
return node;
......@@ -344,9 +288,7 @@ AST::transform_node_iter(syntax_tree_node *n) {
if (n->children_num == 3)
i = 1;
auto name = n->children[i]->name;
if (_STR_EQ(name, "expression") ||
_STR_EQ(name, "var") ||
_STR_EQ(name, "call"))
if (_STR_EQ(name, "expression") || _STR_EQ(name, "var") || _STR_EQ(name, "call"))
return transform_node_iter(n->children[i]);
else {
auto num_node = new ASTNum();
......@@ -375,11 +317,8 @@ AST::transform_node_iter(syntax_tree_node *n) {
s.push(list_ptr->children[0]);
while (!s.empty()) {
auto expr_node =
static_cast<ASTExpression *>(
transform_node_iter(s.top()));
auto expr_node_ptr =
std::shared_ptr<ASTExpression>(expr_node);
auto expr_node = static_cast<ASTExpression *>(transform_node_iter(s.top()));
auto expr_node_ptr = std::shared_ptr<ASTExpression>(expr_node);
node->args.push_back(expr_node_ptr);
s.pop();
}
......@@ -409,29 +348,25 @@ void ASTTerm::accept(ASTVisitor &visitor) { visitor.visit(*this); }
void ASTCall::accept(ASTVisitor &visitor) { visitor.visit(*this); }
void ASTFactor::accept(ASTVisitor &visitor) {
auto expr =
dynamic_cast<ASTExpression *>(this);
auto expr = dynamic_cast<ASTExpression *>(this);
if (expr) {
expr->accept(visitor);
return;
}
auto var =
dynamic_cast<ASTVar *>(this);
auto var = dynamic_cast<ASTVar *>(this);
if (var) {
var->accept(visitor);
return;
}
auto call =
dynamic_cast<ASTCall *>(this);
auto call = dynamic_cast<ASTCall *>(this);
if (call) {
call->accept(visitor);
return;
}
auto num =
dynamic_cast<ASTNum *>(this);
auto num = dynamic_cast<ASTNum *>(this);
if (num) {
num->accept(visitor);
return;
......@@ -441,14 +376,12 @@ void ASTFactor::accept(ASTVisitor &visitor) {
}
void ASTDeclaration::accept(ASTVisitor &visitor) {
auto var_decl =
dynamic_cast<ASTVarDeclaration *>(this);
auto var_decl = dynamic_cast<ASTVarDeclaration *>(this);
if (var_decl) {
var_decl->accept(visitor);
return;
}
auto fun_decl =
dynamic_cast<ASTFunDeclaration *>(this);
auto fun_decl = dynamic_cast<ASTFunDeclaration *>(this);
if (fun_decl) {
fun_decl->accept(visitor);
return;
......@@ -457,36 +390,31 @@ void ASTDeclaration::accept(ASTVisitor &visitor) {
}
void ASTStatement::accept(ASTVisitor &visitor) {
auto comp_stmt =
dynamic_cast<ASTCompoundStmt *>(this);
auto comp_stmt = dynamic_cast<ASTCompoundStmt *>(this);
if (comp_stmt) {
comp_stmt->accept(visitor);
return;
}
auto expr_stmt =
dynamic_cast<ASTExpressionStmt *>(this);
auto expr_stmt = dynamic_cast<ASTExpressionStmt *>(this);
if (expr_stmt) {
expr_stmt->accept(visitor);
return;
}
auto sele_stmt =
dynamic_cast<ASTSelectionStmt *>(this);
auto sele_stmt = dynamic_cast<ASTSelectionStmt *>(this);
if (sele_stmt) {
sele_stmt->accept(visitor);
return;
}
auto iter_stmt =
dynamic_cast<ASTIterationStmt *>(this);
auto iter_stmt = dynamic_cast<ASTIterationStmt *>(this);
if (iter_stmt) {
iter_stmt->accept(visitor);
return;
}
auto ret_stmt =
dynamic_cast<ASTReturnStmt *>(this);
auto ret_stmt = dynamic_cast<ASTReturnStmt *>(this);
if (ret_stmt) {
ret_stmt->accept(visitor);
return;
......@@ -495,15 +423,13 @@ void ASTStatement::accept(ASTVisitor &visitor) {
}
void ASTExpression::accept(ASTVisitor &visitor) {
auto simple_expr =
dynamic_cast<ASTSimpleExpression *>(this);
auto simple_expr = dynamic_cast<ASTSimpleExpression *>(this);
if (simple_expr) {
simple_expr->accept(visitor);
return;
}
auto assign_expr =
dynamic_cast<ASTAssignExpression *>(this);
auto assign_expr = dynamic_cast<ASTAssignExpression *>(this);
if (assign_expr) {
assign_expr->accept(visitor);
return;
......@@ -511,15 +437,14 @@ void ASTExpression::accept(ASTVisitor &visitor) {
_AST_NODE_ERROR_
}
#define _DEBUG_PRINT_N_(N) {\
std::cout << std::string(N, '-');\
}
#define _DEBUG_PRINT_N_(N) \
{ std::cout << std::string(N, '-'); }
void ASTPrinter::visit(ASTProgram &node) {
_DEBUG_PRINT_N_(depth);
std::cout << "program" << std::endl;
add_depth();
for (auto decl: node.declarations) {
for (auto decl : node.declarations) {
decl->accept(*this);
}
remove_depth();
......@@ -534,7 +459,6 @@ void ASTPrinter::visit(ASTNum &node) {
} else {
_AST_NODE_ERROR_
}
}
void ASTPrinter::visit(ASTVarDeclaration &node) {
......@@ -554,7 +478,7 @@ void ASTPrinter::visit(ASTFunDeclaration &node) {
_DEBUG_PRINT_N_(depth);
std::cout << "fun-declaration: " << node.id << std::endl;
add_depth();
for (auto param: node.params) {
for (auto param : node.params) {
param->accept(*this);
}
......@@ -574,11 +498,11 @@ void ASTPrinter::visit(ASTCompoundStmt &node) {
_DEBUG_PRINT_N_(depth);
std::cout << "compound-stmt" << std::endl;
add_depth();
for (auto decl: node.local_declarations) {
for (auto decl : node.local_declarations) {
decl->accept(*this);
}
for (auto stmt: node.statement_list) {
for (auto stmt : node.statement_list) {
stmt->accept(*this);
}
remove_depth();
......@@ -730,7 +654,7 @@ void ASTPrinter::visit(ASTCall &node) {
_DEBUG_PRINT_N_(depth);
std::cout << "call: " << node.id << "()" << std::endl;
add_depth();
for (auto arg: node.args) {
for (auto arg : node.args) {
arg->accept(*this);
}
remove_depth();
......
#include "syntax_tree.h"
#include <stdlib.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) {
syntax_tree_node *new_node = (syntax_tree_node *)malloc(sizeof(syntax_tree_node));
if (name)
strncpy(new_node->name, name, SYNTAX_TREE_NODE_NAME_MAX);
else
......@@ -14,16 +13,16 @@ syntax_tree_node * new_syntax_tree_node(const char * name)
return new_node;
}
int syntax_tree_add_child(syntax_tree_node * parent, syntax_tree_node * child)
{
if (!parent || !child) return -1;
int syntax_tree_add_child(syntax_tree_node *parent, syntax_tree_node *child) {
if (!parent || !child)
return -1;
parent->children[parent->children_num++] = child;
return parent->children_num;
}
void del_syntax_tree_node(syntax_tree_node * node, int recursive)
{
if (!node) return;
void del_syntax_tree_node(syntax_tree_node *node, int recursive) {
if (!node)
return;
int i;
if (recursive) {
......@@ -34,14 +33,11 @@ void del_syntax_tree_node(syntax_tree_node * node, int recursive)
free(node);
}
syntax_tree * new_syntax_tree()
{
return (syntax_tree *)malloc(sizeof(syntax_tree));
}
syntax_tree *new_syntax_tree() { return (syntax_tree *)malloc(sizeof(syntax_tree)); }
void del_syntax_tree(syntax_tree * tree)
{
if (!tree) return;
void del_syntax_tree(syntax_tree *tree) {
if (!tree)
return;
if (tree->root) {
del_syntax_tree_node(tree->root, 1);
......@@ -49,12 +45,12 @@ void del_syntax_tree(syntax_tree * 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
// check if "node" empty pointer
if (!node) return;
if (!node)
return;
// print myself
int i;
......@@ -68,10 +64,9 @@ void print_syntax_tree_node(FILE * fout, syntax_tree_node * node, int level)
}
}
void print_syntax_tree(FILE * fout, syntax_tree * tree)
{
if (!fout) return;
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