Skip to content

Commit fe3c07a

Browse files
committed
Added support for continue and break statements
1 parent a750d0e commit fe3c07a

File tree

7 files changed

+117
-20
lines changed

7 files changed

+117
-20
lines changed

include/ast.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
#include "ast/Function/ast_sizeof.hpp"
1212

1313
#include "ast/Keyword/ast_return.hpp"
14+
#include "ast/Keyword/ast_break.hpp"
15+
#include "ast/Keyword/ast_continue.hpp"
16+
1417
#include "ast/Types/ast_types.hpp"
1518
#include "ast/Arrays/ast_arrays.hpp"
1619

include/ast/Blocks/ast_forloop.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ class forloop : public Node {
4646

4747
//create labels
4848
std::string start_loop = helper.createLabel("start_for");
49+
std::string update_loop = helper.createLabel("update_con");
4950
std::string end_loop = helper.createLabel("end_for");
51+
helper.new_loop(start_loop, end_loop, update_loop);
5052

5153
//initialise condition
5254
init_cont->riscv_asm(dst,helper,destReg,bindings);
@@ -61,15 +63,17 @@ class forloop : public Node {
6163
if (for_block!=NULL){
6264
for_block->riscv_asm(dst,helper,destReg,bindings);
6365
}
66+
//update conditions
67+
dst<<update_loop<<":"<<std::endl;
6468
update_cont->riscv_asm(dst,helper,destReg,bindings);
6569
dst<<"beq zero, zero, "<<start_loop<<std::endl;
6670

6771
//end loop
6872
dst<<end_loop<<":"<<std::endl;
73+
helper.exit_loop();
6974

7075
//clear registers
7176
if (init_cont->getType() != "NULL"){ // if control was intialised within loop construct -> need to earse it
72-
dst<<"addi "<<bindings[init_cont->getId()][0]<<", zero, 0"<<std::endl;
7377
bindings.erase(init_cont->getId());
7478
}
7579
dst<<"addi "<<condition_reg<<", zero, 0"<<std::endl;

include/ast/Blocks/ast_whileloop.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class whileloop : public Node {
4444
//create labels
4545
std::string start_loop = helper.createLabel("start_while");
4646
std::string end_loop = helper.createLabel("end_while");
47+
helper.new_loop(start_loop, end_loop);
4748

4849
//evalute conditon
4950
std::string condition_reg = helper.allocateReg("None"); //this is not ideal, prevents unwanted float regs being used
@@ -59,6 +60,8 @@ class whileloop : public Node {
5960

6061
//end loop
6162
dst<<end_loop<<":"<<std::endl;
63+
helper.exit_loop();
64+
6265

6366
//clear registers
6467
dst<<"addi "<<condition_reg<<", zero, 0"<<std::endl;

include/ast/Keyword/ast_break.hpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#ifndef ast_break_hpp
2+
#define ast_break_hpp
3+
4+
#include <string>
5+
#include <iostream>
6+
7+
#include "../ast_node.hpp"
8+
9+
class Break : public Node {
10+
public:
11+
Break()
12+
{}
13+
virtual void print(std::ostream &dst, int span) const override{
14+
dst<<std::setw(span*4)<<"break ";
15+
dst<<std::endl;
16+
}
17+
18+
virtual void riscv_asm(std::ostream &dst,
19+
Helper &helper,
20+
std::string destReg,
21+
std::map<std::string, std::vector<std::string>> &bindings,
22+
std::string datatype = "None")const override{
23+
24+
dst<<"beq zero, zero, "<<helper.get_loop_labels("End")<<std::endl;
25+
}
26+
};
27+
#endif
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#ifndef ast_continue_hpp
2+
#define ast_continue_hpp
3+
4+
#include <string>
5+
#include <iostream>
6+
7+
#include "../ast_node.hpp"
8+
9+
10+
11+
class Continue : public Node {
12+
public:
13+
Continue()
14+
{}
15+
virtual void print(std::ostream &dst, int span) const override{
16+
dst<<std::setw(span*4)<<"continue ";
17+
dst<<std::endl;
18+
}
19+
20+
virtual void riscv_asm(std::ostream &dst,
21+
Helper &helper,
22+
std::string destReg,
23+
std::map<std::string, std::vector<std::string>> &bindings,
24+
std::string datatype = "None")const override{
25+
std::string label = helper.get_loop_labels("Update");
26+
if (label == "None"){
27+
//in while loop then -> use "Start" instead
28+
label = helper.get_loop_labels("Start");
29+
}
30+
dst<<"beq zero, zero, "<<label<<std::endl;
31+
}
32+
};
33+
34+
35+
#endif

include/ast/Keyword/ast_return.hpp

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,24 +33,6 @@ class Return : public Node {
3333
}
3434
};
3535

36-
class Continue : public Node {
37-
public:
38-
Continue()
39-
{}
40-
virtual void print(std::ostream &dst, int span) const override{
41-
dst<<std::setw(span*4)<<"continue ";
42-
dst<<std::endl;
43-
}
44-
};
4536

46-
class Break : public Node {
47-
public:
48-
Break()
49-
{}
50-
virtual void print(std::ostream &dst, int span) const override{
51-
dst<<std::setw(span*4)<<"break ";
52-
dst<<std::endl;
53-
}
54-
};
5537

5638
#endif

include/ast/ast_helper.hpp

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,50 @@ class Helper {
6060

6161

6262

63-
63+
// loop end and start
64+
std::string current_loop_end;
65+
std::string current_loop_update;
66+
std::string current_loop_start;
67+
std::vector<std::string> loop_end;
68+
std::vector<std::string> loop_update;
69+
std::vector<std::string> loop_start;
70+
71+
void new_loop(std::string new_loop_start, std::string new_loop_end, std::string new_loop_update = "None"){
72+
loop_start.push_back(new_loop_start);
73+
loop_update.push_back(new_loop_update);
74+
loop_end.push_back(new_loop_end);
75+
current_loop_start = new_loop_start;
76+
current_loop_update = new_loop_update;
77+
current_loop_end = new_loop_end;
78+
}
79+
void exit_loop(){
80+
if (!loop_start.empty()){
81+
current_loop_start = loop_start.back();
82+
current_loop_update = loop_update.back();
83+
current_loop_end = loop_end.back();
84+
loop_start.pop_back();
85+
loop_update.pop_back();
86+
loop_end.pop_back();
87+
}
88+
else{
89+
std::cerr << "Tried to break or continue in a scope of no loops" << std::endl;
90+
exit(1);
91+
}
92+
}
93+
std::string get_loop_labels(std::string where){
94+
if (where == "Start"){
95+
return current_loop_start;
96+
}
97+
else if (where == "End"){
98+
return current_loop_end;
99+
}
100+
else if (where == "Update"){
101+
return current_loop_update;
102+
}
103+
else{
104+
return "invalid location to jump";
105+
}
106+
}
64107

65108

66109
//Creates Labels for function jumps

0 commit comments

Comments
 (0)