Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
2
2022fall-Compiler_CMinus
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
李晓奇
2022fall-Compiler_CMinus
Commits
d7dae728
Commit
d7dae728
authored
Oct 26, 2022
by
李晓奇
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
backup on halfway
parent
2dd8c34b
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
599 additions
and
267 deletions
+599
-267
.clang-format
.clang-format
+2
-2
Reports/3-ir-gen/report.md
Reports/3-ir-gen/report.md
+59
-2
include/ast.hpp
include/ast.hpp
+37
-41
include/cminusf_builder.hpp
include/cminusf_builder.hpp
+2
-0
src/cminusfc/cminusf_builder.cpp
src/cminusfc/cminusf_builder.cpp
+326
-16
src/cminusfc/cminusfc.cpp
src/cminusfc/cminusfc.cpp
+3
-3
src/common/ast.cpp
src/common/ast.cpp
+68
-144
src/common/syntax_tree.c
src/common/syntax_tree.c
+54
-59
tests/3-ir-gen/.gitignore
tests/3-ir-gen/.gitignore
+2
-0
tests/3-ir-gen/testcases/lv0_1/.gitignore
tests/3-ir-gen/testcases/lv0_1/.gitignore
+11
-0
tests/3-ir-gen/testcases/lv0_2/.gitignore
tests/3-ir-gen/testcases/lv0_2/.gitignore
+35
-0
No files found.
.clang-format
View file @
d7dae728
...
@@ -15,8 +15,8 @@ IncludeCategories:
...
@@ -15,8 +15,8 @@ IncludeCategories:
Priority: 2
Priority: 2
- Regex: '.*'
- Regex: '.*'
Priority: 1
Priority: 1
IndentCaseLabels:
fals
e
IndentCaseLabels:
tru
e
AllowShortCaseLabelsOnASingleLine:
tru
e
AllowShortCaseLabelsOnASingleLine:
fals
e
IndentWidth: 4
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: false
KeepEmptyLinesAtTheStartOfBlocks: false
PenaltyReturnTypeOnItsOwnLine: 200
PenaltyReturnTypeOnItsOwnLine: 200
...
...
Reports/3-ir-gen/report.md
View file @
d7dae728
# 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指针?这个关乎地址的计算、类型转换……
答案在于:中间代码是如何生成的?
按我的理解,
-
在翻译为中间代码时,函数内部声明的只能是数组,计算地址时会得到指针。
-
在传递给函数时,只能传递数组,但是传递为指针。
## 实验设计
## 实验设计
...
...
include/ast.hpp
View file @
d7dae728
...
@@ -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
include/cminusf_builder.hpp
View file @
d7dae728
...
@@ -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
;
...
...
src/cminusfc/cminusf_builder.cpp
View file @
d7dae728
...
@@ -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
);
}
}
src/cminusfc/cminusfc.cpp
View file @
d7dae728
#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
;
...
...
src/common/ast.cpp
View file @
d7dae728
#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
();
...
...
src/common/syntax_tree.c
View file @
d7dae728
#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
);
}
tests/3-ir-gen/.gitignore
0 → 100644
View file @
d7dae728
eval_result
tests/3-ir-gen/testcases/lv0_1/.gitignore
0 → 100644
View file @
d7dae728
*.ll
clean.sh
decl_float_array
decl_float
decl_int_array
decl_int
input
output_float
output_int
return
tests/3-ir-gen/testcases/lv0_2/.gitignore
0 → 100644
View file @
d7dae728
*.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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment