-
Notifications
You must be signed in to change notification settings - Fork 0
/
ASTReturnNode.cpp
136 lines (110 loc) · 3.11 KB
/
ASTReturnNode.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
* File: ASTReturnNode.cpp
* Author: claire
*
* Created on October 9, 2013, 12:09 AM
*/
#include "ASTReturnNode.h"
#include "SemanticAnalyzer.h"
ASTReturnNode::ASTReturnNode(): ASTStatementNode(), expression(NULL),
funcScope(NULL)
{
}
ASTReturnNode::ASTReturnNode(const ASTReturnNode& orig):ASTStatementNode(orig),
expression(orig.expression), funcScope(orig.funcScope)
{
}
ASTReturnNode& ASTReturnNode::operator= (const ASTReturnNode &rhs)
{
ASTStatementNode::operator=(rhs);
// do the copy
expression = rhs.expression;
funcScope = rhs.funcScope;
// return the existing object
return *this;
}
ASTReturnNode::~ASTReturnNode() {
delete expression;
}
string ASTReturnNode::genQuadruples() {
stringstream ss;
ss << funcScope->getParamCount();
//if its a void function , create a ret quadruple
if(funcScope->declarationType == Scanner::VOID) {
vec.push_back(Quadruple("ret",ss.str(),"",""));
}
//if it returns a value, create a retv quadruple
else {
vec.push_back(Quadruple("retv",ss.str(),expression->genQuadruples(),""));
}
if(this->next != NULL) {
this->next->genQuadruples();
}
return "";
}
void ASTReturnNode::semAnalyze(){
if(init || !this->isGlobalDec){
this->scopeAnalyze();
if(init)
return;
}
if(this->expression !=NULL)
this->expression->semAnalyze();
returnAnalyzeType();
if(this->next != NULL)
this->next->semAnalyze();
//this->typeAnalyze();
}
void ASTReturnNode::scopeAnalyze(){
}
bool ASTReturnNode::returnAnalyze() {
return true;
}
void ASTReturnNode::returnAnalyzeType() {
if(funcScope == NULL) {
//sa->semanticError("Use of return outside of function", lineNumber);
// Do nothing
}
// Assumption: funcScope's type already determined
else if(funcScope->declarationType == Scanner::VOID) {
if(this->expression != NULL) {
sa->semanticError("Returning value from void function", lineNumber);
}
}
else {
// Missing return
if(this->expression == NULL) {
sa->semanticError("Missing return value for " +
Scanner::namesRev[funcScope->declarationType] +
"-returning function", lineNumber);
}
else if(this->expression->type == -1) {
// Do nothing, error already reported
}
// Incorrect type
else if((this->expression->type != Scanner::NUM &&
this->expression->type != Scanner::INT) &&
funcScope->declarationType == Scanner::INT) {
sa->semanticError("Incorrect return type for " +
Scanner::namesRev[funcScope->declarationType] +
"-returning function", lineNumber);
}
else if((this->expression->type != Scanner::BLIT &&
this->expression->type != Scanner::BOOL) &&
funcScope->declarationType == Scanner::BOOL) {
sa->semanticError("Incorrect return type for " +
Scanner::namesRev[funcScope->declarationType] +
"-returning function", lineNumber);
}
}
}
void ASTReturnNode::printNode(int indent, ostream * output) {
this->output = output;
printIndented("return", indent);
if(expression != NULL) {
expression->printNode(indent + 2, output);
}
if(next != NULL) {
next->printNode(indent, output);
}
}