Commit 521d50fcc059a8c7793f8535f7e88a0cfb7b2009

Authored by Austin Sun
1 parent 1b3210488e
Exists in master

wol

Showing 2 changed files with 124 additions and 85 deletions Inline Diff

/* File: ast_expr.cc 1 1 /* File: ast_expr.cc
* ----------------- 2 2 * -----------------
* Implementation of expression node classes. 3 3 * Implementation of expression node classes.
*/ 4 4 */
5 5
#include <string.h> 6 6 #include <string.h>
#include "ast_expr.h" 7 7 #include "ast_expr.h"
#include "ast_type.h" 8 8 #include "ast_type.h"
#include "ast_decl.h" 9 9 #include "ast_decl.h"
#include "symtable.h" 10 10 #include "symtable.h"
11 11
IntConstant::IntConstant(yyltype loc, int val) : Expr(loc) { 12 12 IntConstant::IntConstant(yyltype loc, int val) : Expr(loc) {
value = val; 13 13 value = val;
} 14 14 }
void IntConstant::PrintChildren(int indentLevel) { 15 15 void IntConstant::PrintChildren(int indentLevel) {
printf("%d", value); 16 16 printf("%d", value);
} 17 17 }
18 18
FloatConstant::FloatConstant(yyltype loc, double val) : Expr(loc) { 19 19 FloatConstant::FloatConstant(yyltype loc, double val) : Expr(loc) {
value = val; 20 20 value = val;
} 21 21 }
void FloatConstant::PrintChildren(int indentLevel) { 22 22 void FloatConstant::PrintChildren(int indentLevel) {
printf("%g", value); 23 23 printf("%g", value);
} 24 24 }
25 25
BoolConstant::BoolConstant(yyltype loc, bool val) : Expr(loc) { 26 26 BoolConstant::BoolConstant(yyltype loc, bool val) : Expr(loc) {
value = val; 27 27 value = val;
} 28 28 }
void BoolConstant::PrintChildren(int indentLevel) { 29 29 void BoolConstant::PrintChildren(int indentLevel) {
printf("%s", value ? "true" : "false"); 30 30 printf("%s", value ? "true" : "false");
} 31 31 }
32 32
VarExpr::VarExpr(yyltype loc, Identifier *ident) : Expr(loc) { 33 33 VarExpr::VarExpr(yyltype loc, Identifier *ident) : Expr(loc) {
Assert(ident != NULL); 34 34 Assert(ident != NULL);
this->id = ident; 35 35 this->id = ident;
} 36 36 }
37 37
void VarExpr::PrintChildren(int indentLevel) { 38 38 void VarExpr::PrintChildren(int indentLevel) {
id->Print(indentLevel+1); 39 39 id->Print(indentLevel+1);
} 40 40 }
41 41
Operator::Operator(yyltype loc, const char *tok) : Node(loc) { 42 42 Operator::Operator(yyltype loc, const char *tok) : Node(loc) {
Assert(tok != NULL); 43 43 Assert(tok != NULL);
strncpy(tokenString, tok, sizeof(tokenString)); 44 44 strncpy(tokenString, tok, sizeof(tokenString));
} 45 45 }
46 46
void Operator::PrintChildren(int indentLevel) { 47 47 void Operator::PrintChildren(int indentLevel) {
printf("%s",tokenString); 48 48 printf("%s",tokenString);
} 49 49 }
50 50
bool Operator::IsOp(const char *op) const { 51 51 bool Operator::IsOp(const char *op) const {
return strcmp(tokenString, op) == 0; 52 52 return strcmp(tokenString, op) == 0;
} 53 53 }
54 54
CompoundExpr::CompoundExpr(Expr *l, Operator *o, Expr *r) 55 55 CompoundExpr::CompoundExpr(Expr *l, Operator *o, Expr *r)
: Expr(Join(l->GetLocation(), r->GetLocation())) { 56 56 : Expr(Join(l->GetLocation(), r->GetLocation())) {
Assert(l != NULL && o != NULL && r != NULL); 57 57 Assert(l != NULL && o != NULL && r != NULL);
(op=o)->SetParent(this); 58 58 (op=o)->SetParent(this);
(left=l)->SetParent(this); 59 59 (left=l)->SetParent(this);
(right=r)->SetParent(this); 60 60 (right=r)->SetParent(this);
} 61 61 }
62 62
CompoundExpr::CompoundExpr(Operator *o, Expr *r) 63 63 CompoundExpr::CompoundExpr(Operator *o, Expr *r)
: Expr(Join(o->GetLocation(), r->GetLocation())) { 64 64 : Expr(Join(o->GetLocation(), r->GetLocation())) {
Assert(o != NULL && r != NULL); 65 65 Assert(o != NULL && r != NULL);
left = NULL; 66 66 left = NULL;
(op=o)->SetParent(this); 67 67 (op=o)->SetParent(this);
(right=r)->SetParent(this); 68 68 (right=r)->SetParent(this);
} 69 69 }
70 70
CompoundExpr::CompoundExpr(Expr *l, Operator *o) 71 71 CompoundExpr::CompoundExpr(Expr *l, Operator *o)
: Expr(Join(l->GetLocation(), o->GetLocation())) { 72 72 : Expr(Join(l->GetLocation(), o->GetLocation())) {
Assert(l != NULL && o != NULL); 73 73 Assert(l != NULL && o != NULL);
(left=l)->SetParent(this); 74 74 (left=l)->SetParent(this);
(op=o)->SetParent(this); 75 75 (op=o)->SetParent(this);
} 76 76 }
77 77
void CompoundExpr::PrintChildren(int indentLevel) { 78 78 void CompoundExpr::PrintChildren(int indentLevel) {
if (left) left->Print(indentLevel+1); 79 79 if (left) left->Print(indentLevel+1);
op->Print(indentLevel+1); 80 80 op->Print(indentLevel+1);
if (right) right->Print(indentLevel+1); 81 81 if (right) right->Print(indentLevel+1);
} 82 82 }
83 83
ConditionalExpr::ConditionalExpr(Expr *c, Expr *t, Expr *f) 84 84 ConditionalExpr::ConditionalExpr(Expr *c, Expr *t, Expr *f)
: Expr(Join(c->GetLocation(), f->GetLocation())) { 85 85 : Expr(Join(c->GetLocation(), f->GetLocation())) {
Assert(c != NULL && t != NULL && f != NULL); 86 86 Assert(c != NULL && t != NULL && f != NULL);
(cond=c)->SetParent(this); 87 87 (cond=c)->SetParent(this);
(trueExpr=t)->SetParent(this); 88 88 (trueExpr=t)->SetParent(this);
(falseExpr=f)->SetParent(this); 89 89 (falseExpr=f)->SetParent(this);
} 90 90 }
91 91
void ConditionalExpr::PrintChildren(int indentLevel) { 92 92 void ConditionalExpr::PrintChildren(int indentLevel) {
cond->Print(indentLevel+1, "(cond) "); 93 93 cond->Print(indentLevel+1, "(cond) ");
trueExpr->Print(indentLevel+1, "(true) "); 94 94 trueExpr->Print(indentLevel+1, "(true) ");
falseExpr->Print(indentLevel+1, "(false) "); 95 95 falseExpr->Print(indentLevel+1, "(false) ");
} 96 96 }
ArrayAccess::ArrayAccess(yyltype loc, Expr *b, Expr *s) : LValue(loc) { 97 97 ArrayAccess::ArrayAccess(yyltype loc, Expr *b, Expr *s) : LValue(loc) {
(base=b)->SetParent(this); 98 98 (base=b)->SetParent(this);
(subscript=s)->SetParent(this); 99 99 (subscript=s)->SetParent(this);
} 100 100 }
101 101
void ArrayAccess::PrintChildren(int indentLevel) { 102 102 void ArrayAccess::PrintChildren(int indentLevel) {
base->Print(indentLevel+1); 103 103 base->Print(indentLevel+1);
subscript->Print(indentLevel+1, "(subscript) "); 104 104 subscript->Print(indentLevel+1, "(subscript) ");
} 105 105 }
106 106
FieldAccess::FieldAccess(Expr *b, Identifier *f) 107 107 FieldAccess::FieldAccess(Expr *b, Identifier *f)
: LValue(b? Join(b->GetLocation(), f->GetLocation()) : *f->GetLocation()) { 108 108 : LValue(b? Join(b->GetLocation(), f->GetLocation()) : *f->GetLocation()) {
Assert(f != NULL); // b can be be NULL (just means no explicit base) 109 109 Assert(f != NULL); // b can be be NULL (just means no explicit base)
base = b; 110 110 base = b;
if (base) base->SetParent(this); 111 111 if (base) base->SetParent(this);
(field=f)->SetParent(this); 112 112 (field=f)->SetParent(this);
} 113 113 }
114 114
115 115
void FieldAccess::PrintChildren(int indentLevel) { 116 116 void FieldAccess::PrintChildren(int indentLevel) {
if (base) base->Print(indentLevel+1); 117 117 if (base) base->Print(indentLevel+1);
field->Print(indentLevel+1); 118 118 field->Print(indentLevel+1);
} 119 119 }
120 120
Call::Call(yyltype loc, Expr *b, Identifier *f, List<Expr*> *a) : Expr(loc) { 121 121 Call::Call(yyltype loc, Expr *b, Identifier *f, List<Expr*> *a) : Expr(loc) {
Assert(f != NULL && a != NULL); // b can be be NULL (just means no explicit base) 122 122 Assert(f != NULL && a != NULL); // b can be be NULL (just means no explicit base)
base = b; 123 123 base = b;
if (base) base->SetParent(this); 124 124 if (base) base->SetParent(this);
(field=f)->SetParent(this); 125 125 (field=f)->SetParent(this);
(actuals=a)->SetParentAll(this); 126 126 (actuals=a)->SetParentAll(this);
} 127 127 }
128 128
void Call::PrintChildren(int indentLevel) { 129 129 void Call::PrintChildren(int indentLevel) {
if (base) base->Print(indentLevel+1); 130 130 if (base) base->Print(indentLevel+1);
if (field) field->Print(indentLevel+1); 131 131 if (field) field->Print(indentLevel+1);
if (actuals) actuals->PrintAll(indentLevel+1, "(actuals) "); 132 132 if (actuals) actuals->PrintAll(indentLevel+1, "(actuals) ");
} 133 133 }
134 134
llvm::Value* VarExpr::Emit() { 135 135 llvm::Value* VarExpr::Emit() {
return new llvm::LoadInst(findSymbol(id->GetName()).second, "", irgen.GetBasicBlock()); 136 136 return new llvm::LoadInst(findSymbol(id->GetName()).second, "", irgen.GetBasicBlock());
} 137 137 }
/* 138 138 /*
llvm::Value* AssignExpr::Emit() { 139 139 llvm::Value* AssignExpr::Emit() {
VarExpr* ve = dynamic_cast<VarExpr*>(left); 140 140 VarExpr* ve = dynamic_cast<VarExpr*>(left);
return new llvm::StoreInst(right->Emit(), findSymbol(ve->GetIdentifier()->GetName()).second, false, irgen.GetBasicBlock()); 141 141 return new llvm::StoreInst(right->Emit(), findSymbol(ve->GetIdentifier()->GetName()).second, false, irgen.GetBasicBlock());
} 142 142 }
*/ 143 143 */
144 144
string Operator::getToken() const { 145 145 string Operator::getToken() const {
return tokenString; 146 146 return tokenString;
} 147 147 }
148 148
llvm::Value* IntConstant::Emit() { 149 149 llvm::Value* IntConstant::Emit() {
return llvm::ConstantInt::get(llvm::Type::getInt32Ty(*irgen.GetContext()), value, true); 150 150 return llvm::ConstantInt::get(llvm::Type::getInt32Ty(*irgen.GetContext()), value, true);
} 151 151 }
152 152
llvm::Value* FloatConstant::Emit() { 153 153 llvm::Value* FloatConstant::Emit() {
return llvm::ConstantFP::get(llvm::Type::getFloatTy(*irgen.GetContext()), value); 154 154 return llvm::ConstantFP::get(llvm::Type::getFloatTy(*irgen.GetContext()), value);
} 155 155 }
156 156
llvm::Value* BoolConstant::Emit() { 157 157 llvm::Value* BoolConstant::Emit() {
return llvm::ConstantInt::get(llvm::Type::getInt1Ty(*irgen.GetContext()), value, false); 158 158 return llvm::ConstantInt::get(llvm::Type::getInt1Ty(*irgen.GetContext()), value, false);
} 159 159 }
160 160
llvm::Value* Call::Emit() { 161 161 llvm::Value* Call::Emit() {
vector<llvm::Value*> args; 162 162 vector<llvm::Value*> args;
for(int i = 0; i < actuals->NumElements(); i++) { 163 163 for(int i = 0; i < actuals->NumElements(); i++) {
args.push_back(actuals->Nth(i)->Emit()); 164 164 args.push_back(actuals->Nth(i)->Emit());
} 165 165 }
return llvm::CallInst::Create(findSymbol(field->GetName()).second, args, NULL, irgen.GetBasicBlock()); 166 166 return llvm::CallInst::Create(findSymbol(field->GetName()).second, args, NULL, irgen.GetBasicBlock());
} 167 167 }
168 168
llvm::Value* CompoundExpr::Emit() { 169 169 llvm::Value* CompoundExpr::Emit() {
llvm::Value* l = left ? left->Emit() : NULL; 170 170 llvm::Value* l = left ? left->Emit() : NULL;
llvm::Value* r = right ? right->Emit() : NULL; 171 171 llvm::Value* r = right ? right->Emit() : NULL;
llvm::BasicBlock* b = irgen.GetBasicBlock(); 172 172 llvm::BasicBlock* b = irgen.GetBasicBlock();
//austins additional value 173 173 //austins additional value
llvm::Value *val; 174 174 llvm::Value *val;
if(!l || !r) { 175 175 if(!l || !r) {
VarExpr* ve = dynamic_cast<VarExpr*>(l ? left : right); 176 176 VarExpr* ve = dynamic_cast<VarExpr*>(l ? left : right);
llvm::Value* ret; 177 177 llvm::Value* ret;
llvm::Value* var = l ? l : r; 178 178 llvm::Value* var = l ? l : r;
179 179
if(var->getType()->isFPOrFPVectorTy()) val = llvm::ConstantFP::get(irgen.GetFloatType(), 1.0); 180 180 if(var->getType()->isFPOrFPVectorTy()) val = llvm::ConstantFP::get(irgen.GetFloatType(), 1.0);
else val = llvm::ConstantInt::get(irgen.GetIntType(), 1); 181 181 else val = llvm::ConstantInt::get(irgen.GetIntType(), 1);
182 182
if(op->getToken() == "++") { 183 183 if(op->getToken() == "++") {
ret = llvm::BinaryOperator::CreateAdd(var, val, "", b); 184 184 ret = llvm::BinaryOperator::CreateAdd(var, val, "", b);
} 185 185 }
else if(op->getToken() == "--") { 186 186 else if(op->getToken() == "--") {
ret = llvm::BinaryOperator::CreateSub(var, val, "", b); 187 187 ret = llvm::BinaryOperator::CreateSub(var, val, "", b);
} 188 188 }
new llvm::StoreInst(ret, findSymbol(ve->GetIdentifier()->GetName()).second, false, b); 189 189 new llvm::StoreInst(ret, findSymbol(ve->GetIdentifier()->GetName()).second, false, b);
190 190
if(!l) return ret; 191 191 if(!l) return ret;
else return var; 192 192 else return var;
} 193 193 }
if(l->getType()->isFPOrFPVectorTy()) { 194 194 if(l->getType()->isFPOrFPVectorTy()) {
if(op->getToken() == "+") 195 195 if(op->getToken() == "+")
return llvm::BinaryOperator::Create(llvm::Instruction::FAdd, l, r, "", b); 196 196 return llvm::BinaryOperator::Create(llvm::Instruction::FAdd, l, r, "", b);
if(op->getToken() == "-") 197 197 if(op->getToken() == "-")
return llvm::BinaryOperator::Create(llvm::Instruction::FSub, l, r, "", b); 198 198 return llvm::BinaryOperator::Create(llvm::Instruction::FSub, l, r, "", b);
if(op->getToken() == "*") 199 199 if(op->getToken() == "*")
return llvm::BinaryOperator::Create(llvm::Instruction::FMul, l, r, "", b); 200 200 return llvm::BinaryOperator::Create(llvm::Instruction::FMul, l, r, "", b);
if(op->getToken() == "/") 201 201 if(op->getToken() == "/")
return llvm::BinaryOperator::Create(llvm::Instruction::FDiv, l, r, "", b); 202 202 return llvm::BinaryOperator::Create(llvm::Instruction::FDiv, l, r, "", b);
if(op->getToken() == "==") 203 203 if(op->getToken() == "==")
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OEQ, l, r, "", b); 204 204 return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OEQ, l, r, "", b);
if(op->getToken() == "!=") 205 205 if(op->getToken() == "!=")
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_ONE, l, r, "", b); 206 206 return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_ONE, l, r, "", b);
if(op->getToken() == "<=") 207 207 if(op->getToken() == "<=")
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLE, l, r, "", b); 208 208 return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLE, l, r, "", b);
if(op->getToken() == ">=") 209 209 if(op->getToken() == ">=")
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGE, l, r, "", b); 210 210 return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGE, l, r, "", b);
if(op->getToken() == "<") 211 211 if(op->getToken() == "<")
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLT, l, r, "", b); 212 212 return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OLT, l, r, "", b);
if(op->getToken() == ">") 213 213 if(op->getToken() == ">")
return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGT, l, r, "", b); 214 214 return llvm::CmpInst::Create(llvm::CmpInst::FCmp, llvm::CmpInst::FCMP_OGT, l, r, "", b);
} 215 215 }
if(l->getType()->isIntOrIntVectorTy()) { 216 216 if(l->getType()->isIntOrIntVectorTy()) {
if(op->getToken() == "+") 217 217 if(op->getToken() == "+")
return llvm::BinaryOperator::Create(llvm::Instruction::Add, l, r, "", b); 218 218 return llvm::BinaryOperator::Create(llvm::Instruction::Add, l, r, "", b);
if(op->getToken() == "-") 219 219 if(op->getToken() == "-")
return llvm::BinaryOperator::Create(llvm::Instruction::Sub, l, r, "", b); 220 220 return llvm::BinaryOperator::Create(llvm::Instruction::Sub, l, r, "", b);
if(op->getToken() == "*") 221 221 if(op->getToken() == "*")
return llvm::BinaryOperator::Create(llvm::Instruction::Mul, l, r, "", b); 222 222 return llvm::BinaryOperator::Create(llvm::Instruction::Mul, l, r, "", b);
if(op->getToken() == "/") 223 223 if(op->getToken() == "/")
return llvm::BinaryOperator::Create(llvm::Instruction::SDiv, l, r, "", b); 224 224 return llvm::BinaryOperator::Create(llvm::Instruction::SDiv, l, r, "", b);
if(op->getToken() == "==") 225 225 if(op->getToken() == "==")
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_EQ, l, r, "", b); 226 226 return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_EQ, l, r, "", b);
if(op->getToken() == "!=") 227 227 if(op->getToken() == "!=")
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_NE, l, r, "", b); 228 228 return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_NE, l, r, "", b);
if(op->getToken() == "<=") 229 229 if(op->getToken() == "<=")
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLE, l, r, "", b); 230 230 return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLE, l, r, "", b);
if(op->getToken() == ">=") 231 231 if(op->getToken() == ">=")
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGE, l, r, "", b); 232 232 return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGE, l, r, "", b);
if(op->getToken() == "<") 233 233 if(op->getToken() == "<")
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLT, l, r, "", b); 234 234 return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SLT, l, r, "", b);
if(op->getToken() == ">") 235 235 if(op->getToken() == ">")
return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGT, l, r, "", b); 236 236 return llvm::CmpInst::Create(llvm::CmpInst::ICmp, llvm::CmpInst::ICMP_SGT, l, r, "", b);
} 237 237 }
if(op->getToken() == "&&") { 238 238 if(op->getToken() == "&&") {
return llvm::BinaryOperator::Create(llvm::Instruction::And, l, r, "", b); 239 239 return llvm::BinaryOperator::Create(llvm::Instruction::And, l, r, "", b);
} 240 240 }
if(op->getToken() == "||") { 241 241 if(op->getToken() == "||") {
return llvm::BinaryOperator::Create(llvm::Instruction::Or, l, r, "", b); 242 242 return llvm::BinaryOperator::Create(llvm::Instruction::Or, l, r, "", b);
} 243 243 }
return NULL; 244 244 return NULL;
} 245 245 }
246 246
//---------------------------------------------------------------------------------------- 247 247 //----------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------- 248 248 //----------------------------------------------------------------------------------------
llvm::Value * AssignExpr::AssignField(){ 249
FieldAccess * f = (FieldAccess *) left; 250
llvm::Value * rightval = right->Emit(); 251
string operationStr(op->getToken()); 252
bool isFloat = rightval->getType()->isFloatingPointTy(); 253
llvm::Type * intTyp = irgen.GetIntType(); 254
char * ptr = f->getField()->GetName();; 255
256 249
std::vector<llvm::Constant *> maskI; 257
for(; *ptr; ptr++){ 258
switch(*ptr){ 259
case 'x': 260
maskI.push_back(llvm::ConstantInt::get(intTyp, 0)); 261
break; 262
case 'y': 263
maskI.push_back(llvm::ConstantInt::get(intTyp, 1)); 264
break; 265
case 'z': 266
maskI.push_back(llvm::ConstantInt::get(intTyp, 2)); 267
break; 268
case 'w': 269
maskI.push_back(llvm::ConstantInt::get(intTyp, 3)); 270
break; 271
default: 272
break; 273
} 274
} 275
llvm::Value * element; 276
llvm::Value * rightop = rightval; 277
llvm::Value * base_field = f->getBase()->Emit(); 278
llvm::Value * storeInst = f->getBase()->Emit(); 279
280
281
for (int i = 0; i < maskI.size(); i++){ 282
element = llvm::ExtractElementInst::Create (base_field, maskI[i], "", irgen.GetBasicBlock()); 283
if (rightval->getType()->isVectorTy()){ 284
rightop = llvm::ExtractElementInst::Create(rightval, llvm::ConstantInt::get(intTyp, i), "", irgen.GetBasicBlock()); 285
} 286
if (!operationStr.compare("=")){ 287
storeInst = llvm::InsertElementInst::Create (storeInst, rightop, maskI[i], "", irgen.GetBasicBlock()); 288
} 289
if (!operationStr.compare("+=")){ 290
element = llvm::BinaryOperator::CreateFAdd(element, rightop, "", irgen.GetBasicBlock()); 291
storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); 292
} 293
if (!operationStr.compare("-=")){ 294
element = llvm::BinaryOperator::CreateFSub(element, rightop, "", irgen.GetBasicBlock()); 295
storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); 296
} 297
if (!operationStr.compare("*=")){ 298
element = llvm::BinaryOperator::CreateFMul(element, rightop, "", irgen.GetBasicBlock()); 299
storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); 300
} 301
if (!operationStr.compare("/=")){ 302
element = llvm::BinaryOperator::CreateFDiv(element, rightop, "", irgen.GetBasicBlock()); 303
storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock()); 304
} 305
} 306
VarExpr * ve = dynamic_cast<VarExpr *>(f->getBase()); 307
ve->AddressStore(storeInst); 308
if (isFloat){ 309
return llvm::ExtractElementInst::Create (storeInst, maskI.back(), "", irgen.GetBasicBlock()); 310
} 311
return storeInst; 312
} 313
314
llvm::Value * AssignExpr::Emit(){ 315 250 llvm::Value * AssignExpr::Emit(){
llvm::Value * leftval; 316 251 llvm::Value * leftval;
llvm::Value * rightval; 317 252 llvm::Value * rightval;
318 253
FieldAccess * f = dynamic_cast<FieldAccess *>(left); 319 254 FieldAccess * f = dynamic_cast<FieldAccess *>(left);
if (f){ 320 255 if (f){
return this->AssignField(); 321 256 return this->AssignField();
} 322 257 }
leftval = left->Emit(); 323 258 leftval = left->Emit();
rightval = right->Emit(); 324 259 rightval = right->Emit();
325 260
string operationStr(op->getToken()); 326 261 string operationStr(op->getToken());
327 262
VarExpr * vd = dynamic_cast<VarExpr *>(left); 328 263 VarExpr * vd = dynamic_cast<VarExpr *>(left);
329 264
llvm::Value * storeInst = NULL; 330 265 llvm::Value * storeInst = NULL;
if ( operationStr.compare("=") == 0 ){ 331 266 if ( operationStr.compare("+=") == 0 ){
if (vd){ 332
vd->AddressStore(rightval); 333
return rightval; 334
} 335
return ((VarExpr *) left)->AddressStore(rightval); 336
} 337
else if ( operationStr.compare("+=") == 0 ){ 338
if (leftval->getType()->isIntegerTy()){ 339 267 if (leftval->getType()->isIntegerTy()){
storeInst = llvm::BinaryOperator::CreateAdd(leftval, rightval, "", irgen.GetBasicBlock()); 340 268 storeInst = llvm::BinaryOperator::CreateAdd(leftval, rightval, "", irgen.GetBasicBlock());
if (vd){ 341 269 if (vd){
vd->AddressStore(storeInst); 342 270 vd->AddressStore(storeInst);
return storeInst; 343 271 return storeInst;
} 344 272 }
} 345 273 }
else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ 346 274 else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){
storeInst = llvm::BinaryOperator::CreateFAdd(leftval, rightval, "", irgen.GetBasicBlock()); 347 275 storeInst = llvm::BinaryOperator::CreateFAdd(leftval, rightval, "", irgen.GetBasicBlock());
if (vd){ 348 276 if (vd){
vd->AddressStore(storeInst); 349 277 vd->AddressStore(storeInst);
return storeInst; 350 278 return storeInst;
} 351 279 }
} 352 280 }
else{ 353 281 else{
storeInst = convert(leftval, rightval, 0); 354 282 storeInst = convert(leftval, rightval, 0);
if (vd){ 355 283 if (vd){
vd->AddressStore(storeInst); 356 284 vd->AddressStore(storeInst);
return storeInst; 357 285 return storeInst;
} 358 286 }
} 359 287 }
} 360 288 }
289 else if ( operationStr.compare("=") == 0 ){
290 if (vd){
291 vd->AddressStore(rightval);
292 return rightval;
293 }
294 return ((VarExpr *) left)->AddressStore(rightval);
295 }
else if ( operationStr.compare("-=") == 0 ){ 361 296 else if ( operationStr.compare("-=") == 0 ){
if (leftval->getType()->isIntegerTy()){ 362 297 if (leftval->getType()->isIntegerTy()){
storeInst = llvm::BinaryOperator::CreateSub(leftval, rightval, "", irgen.GetBasicBlock()); 363 298 storeInst = llvm::BinaryOperator::CreateSub(leftval, rightval, "", irgen.GetBasicBlock());
if (vd){ 364 299 if (vd){
vd->AddressStore(storeInst); 365 300 vd->AddressStore(storeInst);
return storeInst; 366 301 return storeInst;
} 367 302 }
} 368 303 }
else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ 369 304 else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){
storeInst = llvm::BinaryOperator::CreateFSub(leftval, rightval, "", irgen.GetBasicBlock()); 370 305 storeInst = llvm::BinaryOperator::CreateFSub(leftval, rightval, "", irgen.GetBasicBlock());
if (vd){ 371 306 if (vd){
vd->AddressStore(storeInst); 372 307 vd->AddressStore(storeInst);
return storeInst; 373 308 return storeInst;
} 374 309 }
} 375 310 }
else{ 376 311 else{
storeInst = convert(leftval, rightval, 1); 377 312 storeInst = convert(leftval, rightval, 1);
if (vd){ 378 313 if (vd){
vd->AddressStore(storeInst); 379 314 vd->AddressStore(storeInst);
return storeInst; 380 315 return storeInst;
} 381 316 }
} 382 317 }
} 383 318 }
else if ( operationStr.compare("*=") == 0 ){ 384 319 else if ( operationStr.compare("/=") == 0 ){
if (leftval->getType()->isIntegerTy()){ 385 320 if (leftval->getType()->isIntegerTy()){
storeInst = llvm::BinaryOperator::CreateMul(leftval, rightval, "", irgen.GetBasicBlock()); 386 321 storeInst = llvm::BinaryOperator::CreateSDiv(leftval, rightval, "", irgen.GetBasicBlock());
if (vd){ 387 322 if (vd){
vd->AddressStore(storeInst); 388 323 vd->AddressStore(storeInst);
return storeInst; 389 324 return storeInst;
} 390 325 }
} 391 326 }
else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ 392 327 else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){
storeInst = llvm::BinaryOperator::CreateFMul(leftval, rightval, "", irgen.GetBasicBlock()); 393 328 storeInst = llvm::BinaryOperator::CreateFDiv(leftval, rightval, "", irgen.GetBasicBlock());
if (vd){ 394 329 if (vd){
vd->AddressStore(storeInst); 395 330 vd->AddressStore(storeInst);
return storeInst; 396 331 return storeInst;
} 397 332 }
} 398 333 }
else{ 399 334 else{
storeInst = convert(leftval, rightval, 3); 400 335 storeInst = convert(leftval, rightval, 2);
if (vd){ 401 336 if (vd){
vd->AddressStore(storeInst); 402 337 vd->AddressStore(storeInst);
return storeInst; 403 338 return storeInst;
} 404 339 }
} 405 340 }
} 406 341 }
else if ( operationStr.compare("/=") == 0 ){ 407 342 else if ( operationStr.compare("*=") == 0 ){
if (leftval->getType()->isIntegerTy()){ 408 343 if (leftval->getType()->isIntegerTy()){
storeInst = llvm::BinaryOperator::CreateSDiv(leftval, rightval, "", irgen.GetBasicBlock()); 409 344 storeInst = llvm::BinaryOperator::CreateMul(leftval, rightval, "", irgen.GetBasicBlock());
if (vd){ 410 345 if (vd){
vd->AddressStore(storeInst); 411 346 vd->AddressStore(storeInst);
return storeInst; 412 347 return storeInst;
} 413 348 }
} 414 349 }
else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){ 415 350 else if (leftval->getType()->isFloatingPointTy() || rightval->getType()->isVectorTy()){
storeInst = llvm::BinaryOperator::CreateFDiv(leftval, rightval, "", irgen.GetBasicBlock()); 416 351 storeInst = llvm::BinaryOperator::CreateFMul(leftval, rightval, "", irgen.GetBasicBlock());
if (vd){ 417 352 if (vd){
vd->AddressStore(storeInst); 418 353 vd->AddressStore(storeInst);
return storeInst; 419 354 return storeInst;
} 420 355 }
} 421 356 }
else{ 422 357 else{
storeInst = convert(leftval, rightval, 2); 423 358 storeInst = convert(leftval, rightval, 3);
if (vd){ 424 359 if (vd){
vd->AddressStore(storeInst); 425 360 vd->AddressStore(storeInst);
return storeInst; 426 361 return storeInst;
} 427 362 }
} 428 363 }
} 429 364 }
return NULL; 430 365 return NULL;
} 431 366 }
432 367
llvm::Value * AssignExpr::convert(llvm::Value * vec, llvm::Value * val, int status ){ 433 368 llvm::Value * AssignExpr::convert(llvm::Value * vec, llvm::Value * val, int status ){
llvm::Type * intTyp = irgen.GetIntType(); 434 369 llvm::Type * intTyp = irgen.GetIntType();
llvm::Type * fltTyp = irgen.GetFloatType(); 435 370 llvm::Type * fltTyp = irgen.GetFloatType();
llvm::Value *idVal; 436 371 llvm::Value *idVal;
llvm::Value * element; 437 372 llvm::Value * element;
llvm::Value * retVal = vec; 438 373 llvm::Value * retVal = vec;
439 374
//get vector size 440 375 //get vector size
int numElements=-1; 441 376 int numElements=-1;
if(vec->getType()==irgen.GetVec2Type()){ 442 377 if(vec->getType()==irgen.GetVec2Type()){
numElements=2; 443 378 numElements=2;
} 444 379 }
else if(vec->getType()==irgen.GetVec3Type()){ 445 380 else if(vec->getType()==irgen.GetVec3Type()){
numElements=3; 446 381 numElements=3;
} 447 382 }
else if(vec->getType()==irgen.GetVec4Type()){ 448 383 else if(vec->getType()==irgen.GetVec4Type()){
numElements=4; 449 384 numElements=4;
} 450 385 }
451 386
for (int i = 0; i < numElements; i++){ 452 387 for (int i = 0; i < numElements; i++){
idVal = llvm::ConstantInt::get(intTyp, i); 453 388 idVal = llvm::ConstantInt::get(intTyp, i);
element = llvm::ExtractElementInst::Create (vec, idVal, "", irgen.GetBasicBlock()); 454 389 element = llvm::ExtractElementInst::Create (vec, idVal, "", irgen.GetBasicBlock());
if (status == 0){ 455 390 if (status == 0){
element = llvm::BinaryOperator::CreateFAdd(element, val, "", irgen.GetBasicBlock()); 456 391 element = llvm::BinaryOperator::CreateFAdd(element, val, "", irgen.GetBasicBlock());
} 457 392 }
else if (status == 1){ 458 393 else if (status == 1){
element = llvm::BinaryOperator::CreateFSub(element, val, "", irgen.GetBasicBlock()); 459 394 element = llvm::BinaryOperator::CreateFSub(element, val, "", irgen.GetBasicBlock());
} 460 395 }
else if (status == 2){ 461 396 else if (status == 2){
element = llvm::BinaryOperator::CreateFMul(element, val, "", irgen.GetBasicBlock()); 462 397 element = llvm::BinaryOperator::CreateFMul(element, val, "", irgen.GetBasicBlock());
} 463 398 }
else{ 464 399 else{
element = llvm::BinaryOperator::CreateFDiv(element, val, "", irgen.GetBasicBlock()); 465 400 element = llvm::BinaryOperator::CreateFDiv(element, val, "", irgen.GetBasicBlock());
} 466 401 }
retVal = llvm::InsertElementInst::Create (retVal, element, idVal, "", irgen.GetBasicBlock()); 467 402 retVal = llvm::InsertElementInst::Create (retVal, element, idVal, "", irgen.GetBasicBlock());
} 468 403 }
return retVal; 469 404 return retVal;
} 470 405 }
471 406
llvm::Value* VarExpr::AddressStore(llvm::Value *store){ 472 407 llvm::Value* VarExpr::AddressStore(llvm::Value *store){
char * varname = GetIdentifier()->GetName(); 473 408 char * varname = GetIdentifier()->GetName();
474 409
pair<Decl *, llvm::Value *> symbol = findSymbol(string(varname)); 475 410 pair<Decl *, llvm::Value *> symbol = findSymbol(string(varname));
//value of symbol 476 411 //value of symbol
llvm::StoreInst* storeInst = new llvm::StoreInst(store, symbol.second, "",irgen.GetBasicBlock()); 477 412 llvm::StoreInst* storeInst = new llvm::StoreInst(store, symbol.second, "",irgen.GetBasicBlock());
return storeInst; 478 413 return storeInst;
414 }
415
416 llvm::Value * AssignExpr::AssignField(){
417 FieldAccess * f = (FieldAccess *) left;
418 llvm::Value * rightval = right->Emit();
419 string operationStr(op->getToken());
420 bool isFloat = rightval->getType()->isFloatingPointTy();
421 llvm::Type * intTyp = irgen.GetIntType();
422 char * ptr = f->getField()->GetName();;
423
424 std::vector<llvm::Constant *> maskI;
425 for(; *ptr; ptr++){
426 if(*ptr =='x'){
427 maskI.push_back(llvm::ConstantInt::get(intTyp, 0));
428 }
429 else if(*ptr='y'){
430 maskI.push_back(llvm::ConstantInt::get(intTyp, 1));
431 }
432 else if(*ptr='z'){
433 maskI.push_back(llvm::ConstantInt::get(intTyp, 2));
434 }
435 else if(*ptr='w'){
436 maskI.push_back(llvm::ConstantInt::get(intTyp, 3));
437 }
438 }
439
440 llvm::Value * element;
441 llvm::Value * rightop = rightval;
442 llvm::Value * baseF = f->getBase()->Emit();
443 llvm::Value * storeInst = f->getBase()->Emit();
444
445
446 for (int i = 0; i < maskI.size(); i++){
447 element = llvm::ExtractElementInst::Create (baseF, maskI[i], "", irgen.GetBasicBlock());
448 if (rightval->getType()->isVectorTy()){
449 rightop = llvm::ExtractElementInst::Create(rightval, llvm::ConstantInt::get(intTyp, i), "", irgen.GetBasicBlock());
450 }
451 if (!operationStr.compare("=")){
452 storeInst = llvm::InsertElementInst::Create (storeInst, rightop, maskI[i], "", irgen.GetBasicBlock());
453 }
454 if (!operationStr.compare("+=")){
455 element = llvm::BinaryOperator::CreateFAdd(element, rightop, "", irgen.GetBasicBlock());
456 storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock());
457 }
458 if (!operationStr.compare("-=")){
459 element = llvm::BinaryOperator::CreateFSub(element, rightop, "", irgen.GetBasicBlock());
460 storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock());
461 }
462 if (!operationStr.compare("*=")){
463 element = llvm::BinaryOperator::CreateFMul(element, rightop, "", irgen.GetBasicBlock());
464 storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock());
465 }
466 if (!operationStr.compare("/=")){
467 element = llvm::BinaryOperator::CreateFDiv(element, rightop, "", irgen.GetBasicBlock());
468 storeInst = llvm::InsertElementInst::Create (storeInst, element, maskI[i], "", irgen.GetBasicBlock());
469 }
470 }
471 VarExpr * ve = dynamic_cast<VarExpr *>(f->getBase());
472 ve->AddressStore(storeInst);
473 if (isFloat){
474 return llvm::ExtractElementInst::Create (storeInst, maskI.back(), "", irgen.GetBasicBlock());
475 }
476 return storeInst;
477 }
478
479
480 llvm::Value * FieldAccess::Emit(){
481 char * mask = this->getField()->GetName();
482 char * ptr = mask;
483
484 llvm::Type * intTyp = irgen.GetIntType();
485 std::vector<llvm::Constant *> maskI;
/* File: ast_expr.h 1 1 /* File: ast_expr.h
* ---------------- 2 2 * ----------------
* The Expr class and its subclasses are used to represent 3 3 * The Expr class and its subclasses are used to represent
* expressions in the parse tree. For each expression in the 4 4 * expressions in the parse tree. For each expression in the
* language (add, call, New, etc.) there is a corresponding 5 5 * language (add, call, New, etc.) there is a corresponding
* node class for that construct. 6 6 * node class for that construct.
* 7 7 *
* pp3: You will need to extend the Expr classes to implement 8 8 * pp3: You will need to extend the Expr classes to implement
* semantic analysis for rules pertaining to expressions. 9 9 * semantic analysis for rules pertaining to expressions.
*/ 10 10 */
11 11
12 12
#ifndef _H_ast_expr 13 13 #ifndef _H_ast_expr
#define _H_ast_expr 14 14 #define _H_ast_expr
15 15
#include "ast.h" 16 16 #include "ast.h"
#include "ast_stmt.h" 17 17 #include "ast_stmt.h"
#include "list.h" 18 18 #include "list.h"
#include "ast_type.h" 19 19 #include "ast_type.h"
20 20
void yyerror(const char *msg); 21 21 void yyerror(const char *msg);
22 22
class Expr : public Stmt 23 23 class Expr : public Stmt
{ 24 24 {
public: 25 25 public:
Expr(yyltype loc) : Stmt(loc) {} 26 26 Expr(yyltype loc) : Stmt(loc) {}
Expr() : Stmt() {} 27 27 Expr() : Stmt() {}
28 28
friend std::ostream& operator<< (std::ostream& stream, Expr * expr) { 29 29 friend std::ostream& operator<< (std::ostream& stream, Expr * expr) {
return stream << expr->GetPrintNameForNode(); 30 30 return stream << expr->GetPrintNameForNode();
} 31 31 }
}; 32 32 };
33 33
class ExprError : public Expr 34 34 class ExprError : public Expr
{ 35 35 {
public: 36 36 public:
ExprError() : Expr() { yyerror(this->GetPrintNameForNode()); } 37 37 ExprError() : Expr() { yyerror(this->GetPrintNameForNode()); }
const char *GetPrintNameForNode() { return "ExprError"; } 38 38 const char *GetPrintNameForNode() { return "ExprError"; }
}; 39 39 };
40 40
/* This node type is used for those places where an expression is optional. 41 41 /* This node type is used for those places where an expression is optional.
* We could use a NULL pointer, but then it adds a lot of checking for 42 42 * We could use a NULL pointer, but then it adds a lot of checking for
* NULL. By using a valid, but no-op, node, we save that trouble */ 43 43 * NULL. By using a valid, but no-op, node, we save that trouble */
class EmptyExpr : public Expr 44 44 class EmptyExpr : public Expr
{ 45 45 {
public: 46 46 public:
const char *GetPrintNameForNode() { return "Empty"; } 47 47 const char *GetPrintNameForNode() { return "Empty"; }
}; 48 48 };
49 49
class IntConstant : public Expr 50 50 class IntConstant : public Expr
{ 51 51 {
protected: 52 52 protected:
int value; 53 53 int value;
54 54
public: 55 55 public:
IntConstant(yyltype loc, int val); 56 56 IntConstant(yyltype loc, int val);
const char *GetPrintNameForNode() { return "IntConstant"; } 57 57 const char *GetPrintNameForNode() { return "IntConstant"; }
void PrintChildren(int indentLevel); 58 58 void PrintChildren(int indentLevel);
llvm::Value* Emit(); 59 59 llvm::Value* Emit();
}; 60 60 };
61 61
class FloatConstant: public Expr 62 62 class FloatConstant: public Expr
{ 63 63 {
protected: 64 64 protected:
double value; 65 65 double value;
66 66
public: 67 67 public:
FloatConstant(yyltype loc, double val); 68 68 FloatConstant(yyltype loc, double val);
const char *GetPrintNameForNode() { return "FloatConstant"; } 69 69 const char *GetPrintNameForNode() { return "FloatConstant"; }
void PrintChildren(int indentLevel); 70 70 void PrintChildren(int indentLevel);
llvm::Value* Emit(); 71 71 llvm::Value* Emit();
}; 72 72 };
73 73
class BoolConstant : public Expr 74 74 class BoolConstant : public Expr
{ 75 75 {
protected: 76 76 protected:
bool value; 77 77 bool value;
78 78
public: 79 79 public:
BoolConstant(yyltype loc, bool val); 80 80 BoolConstant(yyltype loc, bool val);
const char *GetPrintNameForNode() { return "BoolConstant"; } 81 81 const char *GetPrintNameForNode() { return "BoolConstant"; }
void PrintChildren(int indentLevel); 82 82 void PrintChildren(int indentLevel);
llvm::Value* Emit(); 83 83 llvm::Value* Emit();
}; 84 84 };
85 85
class VarExpr : public Expr 86 86 class VarExpr : public Expr
{ 87 87 {
protected: 88 88 protected:
Identifier *id; 89 89 Identifier *id;
90 90
public: 91 91 public:
VarExpr(yyltype loc, Identifier *id); 92 92 VarExpr(yyltype loc, Identifier *id);
const char *GetPrintNameForNode() { return "VarExpr"; } 93 93 const char *GetPrintNameForNode() { return "VarExpr"; }
void PrintChildren(int indentLevel); 94 94 void PrintChildren(int indentLevel);
Identifier *GetIdentifier() {return id;} 95 95 Identifier *GetIdentifier() {return id;}
llvm::Value* Emit(); 96 96 llvm::Value* Emit();
llvm::Value * AddressStore(llvm::Value* store); 97 97 llvm::Value * AddressStore(llvm::Value* store);
}; 98 98 };
99 99
class Operator : public Node 100 100 class Operator : public Node
{ 101 101 {
protected: 102 102 protected:
char tokenString[4]; 103 103 char tokenString[4];
104 104
public: 105 105 public:
string getToken() const; 106 106 string getToken() const;
Operator(yyltype loc, const char *tok); 107 107 Operator(yyltype loc, const char *tok);
const char *GetPrintNameForNode() { return "Operator"; } 108 108 const char *GetPrintNameForNode() { return "Operator"; }
void PrintChildren(int indentLevel); 109 109 void PrintChildren(int indentLevel);
friend ostream& operator<<(ostream& out, Operator *o) { return out << o->tokenString; } 110 110 friend ostream& operator<<(ostream& out, Operator *o) { return out << o->tokenString; }
bool IsOp(const char *op) const; 111 111 bool IsOp(const char *op) const;
}; 112 112 };
113 113
class CompoundExpr : public Expr 114 114 class CompoundExpr : public Expr
{ 115 115 {
protected: 116 116 protected:
Operator *op; 117 117 Operator *op;
Expr *left, *right; // left will be NULL if unary 118 118 Expr *left, *right; // left will be NULL if unary
119 119
public: 120 120 public:
CompoundExpr(Expr *lhs, Operator *op, Expr *rhs); // for binary 121 121 CompoundExpr(Expr *lhs, Operator *op, Expr *rhs); // for binary
CompoundExpr(Operator *op, Expr *rhs); // for unary 122 122 CompoundExpr(Operator *op, Expr *rhs); // for unary
CompoundExpr(Expr *lhs, Operator *op); // for unary 123 123 CompoundExpr(Expr *lhs, Operator *op); // for unary
void PrintChildren(int indentLevel); 124 124 void PrintChildren(int indentLevel);
virtual llvm::Value* Emit(); 125 125 virtual llvm::Value* Emit();
}; 126 126 };
127 127
class ArithmeticExpr : public CompoundExpr 128 128 class ArithmeticExpr : public CompoundExpr
{ 129 129 {
public: 130 130 public:
ArithmeticExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} 131 131 ArithmeticExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {}
ArithmeticExpr(Operator *op, Expr *rhs) : CompoundExpr(op,rhs) {} 132 132 ArithmeticExpr(Operator *op, Expr *rhs) : CompoundExpr(op,rhs) {}
const char *GetPrintNameForNode() { return "ArithmeticExpr"; } 133 133 const char *GetPrintNameForNode() { return "ArithmeticExpr"; }
}; 134 134 };
135 135
class RelationalExpr : public CompoundExpr 136 136 class RelationalExpr : public CompoundExpr
{ 137 137 {
public: 138 138 public:
RelationalExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} 139 139 RelationalExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {}
const char *GetPrintNameForNode() { return "RelationalExpr"; } 140 140 const char *GetPrintNameForNode() { return "RelationalExpr"; }
}; 141 141 };
142 142
class EqualityExpr : public CompoundExpr 143 143 class EqualityExpr : public CompoundExpr
{ 144 144 {
public: 145 145 public:
EqualityExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} 146 146 EqualityExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {}
const char *GetPrintNameForNode() { return "EqualityExpr"; } 147 147 const char *GetPrintNameForNode() { return "EqualityExpr"; }
}; 148 148 };
149 149
class LogicalExpr : public CompoundExpr 150 150 class LogicalExpr : public CompoundExpr
{ 151 151 {
public: 152 152 public:
LogicalExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} 153 153 LogicalExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {}
LogicalExpr(Operator *op, Expr *rhs) : CompoundExpr(op,rhs) {} 154 154 LogicalExpr(Operator *op, Expr *rhs) : CompoundExpr(op,rhs) {}
const char *GetPrintNameForNode() { return "LogicalExpr"; } 155 155 const char *GetPrintNameForNode() { return "LogicalExpr"; }
}; 156 156 };
157 157
class AssignExpr : public CompoundExpr 158 158 class AssignExpr : public CompoundExpr
{ 159 159 {
public: 160 160 public:
AssignExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {} 161 161 AssignExpr(Expr *lhs, Operator *op, Expr *rhs) : CompoundExpr(lhs,op,rhs) {}
const char *GetPrintNameForNode() { return "AssignExpr"; } 162 162 const char *GetPrintNameForNode() { return "AssignExpr"; }
llvm::Value* Emit(); 163 163 llvm::Value* Emit();
llvm::Value * convert(llvm::Value * vec, llvm::Value * val, int status ); 164 164 llvm::Value * convert(llvm::Value * vec, llvm::Value * val, int status );
llvm::Value *AssignField(); 165 165 llvm::Value *AssignField();
}; 166 166 };
167 167
class PostfixExpr : public CompoundExpr 168 168 class PostfixExpr : public CompoundExpr
{ 169 169 {
public: 170 170 public:
PostfixExpr(Expr *lhs, Operator *op) : CompoundExpr(lhs,op) {} 171 171 PostfixExpr(Expr *lhs, Operator *op) : CompoundExpr(lhs,op) {}
const char *GetPrintNameForNode() { return "PostfixExpr"; } 172 172 const char *GetPrintNameForNode() { return "PostfixExpr"; }
173 173
}; 174 174 };
175 175
class ConditionalExpr : public Expr 176 176 class ConditionalExpr : public Expr
{ 177 177 {
protected: 178 178 protected:
Expr *cond, *trueExpr, *falseExpr; 179 179 Expr *cond, *trueExpr, *falseExpr;
public: 180 180 public:
ConditionalExpr(Expr *c, Expr *t, Expr *f); 181 181 ConditionalExpr(Expr *c, Expr *t, Expr *f);
void PrintChildren(int indentLevel); 182 182 void PrintChildren(int indentLevel);
const char *GetPrintNameForNode() { return "ConditionalExpr"; } 183 183 const char *GetPrintNameForNode() { return "ConditionalExpr"; }
}; 184 184 };
185 185
class LValue : public Expr 186 186 class LValue : public Expr
{ 187 187 {
public: 188 188 public:
LValue(yyltype loc) : Expr(loc) {} 189 189 LValue(yyltype loc) : Expr(loc) {}
}; 190 190 };
191 191
class ArrayAccess : public LValue 192 192 class ArrayAccess : public LValue
{ 193 193 {
protected: 194 194 protected:
Expr *base, *subscript; 195 195 Expr *base, *subscript;
196 196
public: 197 197 public:
ArrayAccess(yyltype loc, Expr *base, Expr *subscript); 198 198 ArrayAccess(yyltype loc, Expr *base, Expr *subscript);
const char *GetPrintNameForNode() { return "ArrayAccess"; } 199 199 const char *GetPrintNameForNode() { return "ArrayAccess"; }
void PrintChildren(int indentLevel); 200 200 void PrintChildren(int indentLevel);
}; 201 201 };
202 202
/* Note that field access is used both for qualified names 203 203 /* Note that field access is used both for qualified names
* base.field and just field without qualification. We don't 204 204 * base.field and just field without qualification. We don't
* know for sure whether there is an implicit "this." in 205 205 * know for sure whether there is an implicit "this." in
* front until later on, so we use one node type for either 206 206 * front until later on, so we use one node type for either
* and sort it out later. */ 207 207 * and sort it out later. */
class FieldAccess : public LValue 208 208 class FieldAccess : public LValue
{ 209 209 {
protected: 210 210 protected:
Expr *base; // will be NULL if no explicit base 211 211 Expr *base; // will be NULL if no explicit base
Identifier *field; 212 212 Identifier *field;