compiler: Formatting

This commit is contained in:
Michael Fabian 'Xaymar' Dirks
2019-01-18 17:04:57 +01:00
parent 79cc5fae95
commit c9ff5b8ca4
34 changed files with 7101 additions and 3392 deletions
+410 -194
View File
@@ -1,33 +1,38 @@
#include "std.hpp"
#include "nodes.hpp"
#include "std.hpp"
#include <math.h>
#include <float.h>
#include <math.h>
//////////////////////////////////
// Cast an expression to a type //
//////////////////////////////////
ExprNode *ExprNode::castTo(Type *ty, Environ *e) {
ExprNode* ExprNode::castTo(Type* ty, Environ* e)
{
if (!sem_type->canCastTo(ty)) {
ex("Illegal type conversion");
}
ExprNode *cast = new CastNode(this, ty);
ExprNode* cast = new CastNode(this, ty);
cast->semant(e);
return cast;
}
ExprNode *CastNode::semant(Environ *e) {
ExprNode* CastNode::semant(Environ* e)
{
if (!expr->sem_type) {
expr = expr->semant(e);
}
if (ConstNode *c = expr->constNode()) {
ExprNode *e;
if (type == Type::int_type) e = new IntConstNode(c->intValue());
else if (type == Type::float_type) e = new FloatConstNode(c->floatValue());
else e = new StringConstNode(c->stringValue());
if (ConstNode* c = expr->constNode()) {
ExprNode* e;
if (type == Type::int_type)
e = new IntConstNode(c->intValue());
else if (type == Type::float_type)
e = new FloatConstNode(c->floatValue());
else
e = new StringConstNode(c->stringValue());
delete this;
return e;
}
@@ -39,8 +44,9 @@ ExprNode *CastNode::semant(Environ *e) {
//////////////////////////////////
// Cast an expression to a type //
//////////////////////////////////
TNode *CastNode::translate(Codegen *g) {
TNode *t = expr->translate(g);
TNode* CastNode::translate(Codegen* g)
{
TNode* t = expr->translate(g);
if (expr->sem_type == Type::float_type && sem_type == Type::int_type) {
//float->int
return new TNode(IR_CAST, t, 0);
@@ -75,20 +81,22 @@ TNode *CastNode::translate(Codegen *g) {
/////////////////////////////
// Sequence of Expressions //
/////////////////////////////
void ExprSeqNode::semant(Environ *e) {
void ExprSeqNode::semant(Environ* e)
{
for (int k = 0; k < exprs.size(); ++k) {
if (exprs[k]) exprs[k] = exprs[k]->semant(e);
if (exprs[k])
exprs[k] = exprs[k]->semant(e);
}
}
TNode *ExprSeqNode::translate(Codegen *g, bool cfunc) {
TNode* ExprSeqNode::translate(Codegen* g, bool cfunc)
{
TNode *t = 0, *l = 0;
for (int k = 0; k < exprs.size(); ++k) {
TNode *q = exprs[k]->translate(g);
TNode* q = exprs[k]->translate(g);
if (cfunc) {
Type *ty = exprs[k]->sem_type;
Type* ty = exprs[k]->sem_type;
if (ty->stringType()) {
q = call("__bbStrToCStr", q);
} else if (ty->structType()) {
@@ -98,24 +106,27 @@ TNode *ExprSeqNode::translate(Codegen *g, bool cfunc) {
}
}
TNode *p;
TNode* p;
p = new TNode(IR_ARG, 0, 0, k * 4);
p = new TNode(IR_MEM, p, 0);
p = new TNode(IR_MOVE, q, p);
p = new TNode(IR_SEQ, p, 0);
if (l) l->r = p;
else t = p;
if (l)
l->r = p;
else
t = p;
l = p;
}
return t;
}
void ExprSeqNode::castTo(DeclSeq *decls, Environ *e, bool cfunc) {
if (exprs.size() > decls->size()) ex("Too many parameters");
void ExprSeqNode::castTo(DeclSeq* decls, Environ* e, bool cfunc)
{
if (exprs.size() > decls->size())
ex("Too many parameters");
for (int k = 0; k < decls->size(); ++k) {
Decl *d = decls->decls[k];
Decl* d = decls->decls[k];
if (k < exprs.size() && exprs[k]) {
if (cfunc && d->type->structType()) {
if (exprs[k]->sem_type->structType()) {
} else if (exprs[k]->sem_type->intType()) {
@@ -129,15 +140,19 @@ void ExprSeqNode::castTo(DeclSeq *decls, Environ *e, bool cfunc) {
exprs[k] = exprs[k]->castTo(d->type, e);
} else {
if (!d->defType) ex("Not enough parameters");
ExprNode *expr = constValue(d->defType);
if (k < exprs.size()) exprs[k] = expr;
else exprs.push_back(expr);
if (!d->defType)
ex("Not enough parameters");
ExprNode* expr = constValue(d->defType);
if (k < exprs.size())
exprs[k] = expr;
else
exprs.push_back(expr);
}
}
}
void ExprSeqNode::castTo(Type *t, Environ *e) {
void ExprSeqNode::castTo(Type* t, Environ* e)
{
for (int k = 0; k < exprs.size(); ++k) {
exprs[k] = exprs[k]->castTo(t, e);
}
@@ -146,25 +161,28 @@ void ExprSeqNode::castTo(Type *t, Environ *e) {
///////////////////
// Function call //
///////////////////
ExprNode *CallNode::semant(Environ *e) {
Type *t = e->findType(tag);
ExprNode* CallNode::semant(Environ* e)
{
Type* t = e->findType(tag);
sem_decl = e->findFunc(ident);
if (!sem_decl || !(sem_decl->kind & DECL_FUNC)) ex("Function '" + ident + "' not found");
FuncType *f = sem_decl->type->funcType();
if (t && f->returnType != t) ex("incorrect function return type");
if (!sem_decl || !(sem_decl->kind & DECL_FUNC))
ex("Function '" + ident + "' not found");
FuncType* f = sem_decl->type->funcType();
if (t && f->returnType != t)
ex("incorrect function return type");
exprs->semant(e);
exprs->castTo(f->params, e, f->cfunc);
sem_type = f->returnType;
return this;
}
TNode *CallNode::translate(Codegen *g) {
TNode* CallNode::translate(Codegen* g)
{
FuncType* f = sem_decl->type->funcType();
FuncType *f = sem_decl->type->funcType();
TNode *t;
TNode *l = global("_f" + ident);
TNode *r = exprs->translate(g, f->cfunc);
TNode* t;
TNode* l = global("_f" + ident);
TNode* r = exprs->translate(g, f->cfunc);
if (f->userlib) {
l = new TNode(IR_MEM, l);
@@ -188,57 +206,71 @@ TNode *CallNode::translate(Codegen *g) {
/////////////////////////
// Variable expression //
/////////////////////////
ExprNode *VarExprNode::semant(Environ *e) {
ExprNode* VarExprNode::semant(Environ* e)
{
var->semant(e);
sem_type = var->sem_type;
ConstType *c = sem_type->constType();
if (!c) return this;
ExprNode *expr = constValue(c);
delete this; return expr;
sem_type = var->sem_type;
ConstType* c = sem_type->constType();
if (!c)
return this;
ExprNode* expr = constValue(c);
delete this;
return expr;
}
TNode *VarExprNode::translate(Codegen *g) {
TNode* VarExprNode::translate(Codegen* g)
{
return var->load(g);
}
//////////////////////
// Integer constant //
//////////////////////
IntConstNode::IntConstNode(int n) :value(n) {
IntConstNode::IntConstNode(int n) : value(n)
{
sem_type = Type::int_type;
}
TNode *IntConstNode::translate(Codegen *g) {
TNode* IntConstNode::translate(Codegen* g)
{
return new TNode(IR_CONST, 0, 0, value);
}
int IntConstNode::intValue() {
int IntConstNode::intValue()
{
return value;
}
float IntConstNode::floatValue() {
float IntConstNode::floatValue()
{
return value;
}
string IntConstNode::stringValue() {
string IntConstNode::stringValue()
{
return itoa(value);
}
////////////////////
// Float constant //
////////////////////
FloatConstNode::FloatConstNode(float f) :value(f) {
FloatConstNode::FloatConstNode(float f) : value(f)
{
sem_type = Type::float_type;
}
TNode *FloatConstNode::translate(Codegen *g) {
TNode* FloatConstNode::translate(Codegen* g)
{
return new TNode(IR_CONST, 0, 0, *(int*)&value);
}
int FloatConstNode::intValue() {
int FloatConstNode::intValue()
{
float flt = value;
int temp;
_control87(_RC_NEAR | _PC_24 | _EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW | _EM_INEXACT | _EM_DENORMAL, 0xfffff);
int temp;
_control87(_RC_NEAR | _PC_24 | _EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW | _EM_UNDERFLOW | _EM_INEXACT
| _EM_DENORMAL,
0xfffff);
_asm {
fld[flt];
fistp[temp];
@@ -247,61 +279,86 @@ int FloatConstNode::intValue() {
return temp;
}
float FloatConstNode::floatValue() {
float FloatConstNode::floatValue()
{
return value;
}
string FloatConstNode::stringValue() {
string FloatConstNode::stringValue()
{
return ftoa(value);
}
/////////////////////
// String constant //
/////////////////////
StringConstNode::StringConstNode(const string &s) :value(s) {
StringConstNode::StringConstNode(const string& s) : value(s)
{
sem_type = Type::string_type;
}
TNode *StringConstNode::translate(Codegen *g) {
TNode* StringConstNode::translate(Codegen* g)
{
string lab = genLabel();
g->s_data(value, lab);
return call("__bbStrConst", global(lab));
}
int StringConstNode::intValue() {
int StringConstNode::intValue()
{
return atoi(value);
}
float StringConstNode::floatValue() {
float StringConstNode::floatValue()
{
return (float)atof(value);
}
string StringConstNode::stringValue() {
string StringConstNode::stringValue()
{
return value;
}
////////////////////
// Unary operator //
////////////////////
ExprNode *UniExprNode::semant(Environ *e) {
expr = expr->semant(e);
ExprNode* UniExprNode::semant(Environ* e)
{
expr = expr->semant(e);
sem_type = expr->sem_type;
if (sem_type != Type::int_type && sem_type != Type::float_type) ex("Illegal operator for type");
if (ConstNode *c = expr->constNode()) {
ExprNode *e;
if (sem_type != Type::int_type && sem_type != Type::float_type)
ex("Illegal operator for type");
if (ConstNode* c = expr->constNode()) {
ExprNode* e;
if (sem_type == Type::int_type) {
switch (op) {
case '+':e = new IntConstNode(+c->intValue()); break;
case '-':e = new IntConstNode(-c->intValue()); break;
case ABS:e = new IntConstNode(c->intValue() >= 0 ? c->intValue() : -c->intValue()); break;
case SGN:e = new IntConstNode(c->intValue() > 0 ? 1 : (c->intValue() < 0 ? -1 : 0)); break;
case '+':
e = new IntConstNode(+c->intValue());
break;
case '-':
e = new IntConstNode(-c->intValue());
break;
case ABS:
e = new IntConstNode(c->intValue() >= 0 ? c->intValue() : -c->intValue());
break;
case SGN:
e = new IntConstNode(c->intValue() > 0 ? 1 : (c->intValue() < 0 ? -1 : 0));
break;
}
} else {
switch (op) {
case '+':e = new FloatConstNode(+c->floatValue()); break;
case '-':e = new FloatConstNode(-c->floatValue()); break;
case ABS:e = new FloatConstNode(c->floatValue() >= 0 ? c->floatValue() : -c->floatValue()); break;
case SGN:e = new FloatConstNode(c->floatValue() > 0 ? 1 : (c->floatValue() < 0 ? -1 : 0)); break;
case '+':
e = new FloatConstNode(+c->floatValue());
break;
case '-':
e = new FloatConstNode(-c->floatValue());
break;
case ABS:
e = new FloatConstNode(c->floatValue() >= 0 ? c->floatValue() : -c->floatValue());
break;
case SGN:
e = new FloatConstNode(c->floatValue() > 0 ? 1 : (c->floatValue() < 0 ? -1 : 0));
break;
}
}
delete this;
@@ -310,22 +367,33 @@ ExprNode *UniExprNode::semant(Environ *e) {
return this;
}
TNode *UniExprNode::translate(Codegen *g) {
int n = 0;
TNode *l = expr->translate(g);
TNode* UniExprNode::translate(Codegen* g)
{
int n = 0;
TNode* l = expr->translate(g);
if (sem_type == Type::int_type) {
switch (op) {
case '+':return l;
case '-':n = IR_NEG; break;
case ABS:return call("__bbAbs", l);
case SGN:return call("__bbSgn", l);
case '+':
return l;
case '-':
n = IR_NEG;
break;
case ABS:
return call("__bbAbs", l);
case SGN:
return call("__bbSgn", l);
}
} else {
switch (op) {
case '+':return l;
case '-':n = IR_FNEG; break;
case ABS:return fcall("__bbFAbs", l);
case SGN:return fcall("__bbFSgn", l);
case '+':
return l;
case '-':
n = IR_FNEG;
break;
case ABS:
return fcall("__bbFAbs", l);
case SGN:
return fcall("__bbFSgn", l);
}
}
return new TNode(n, l, 0);
@@ -334,19 +402,34 @@ TNode *UniExprNode::translate(Codegen *g) {
/////////////////////////////////////////////////////
// boolean expression - accepts ints, returns ints //
/////////////////////////////////////////////////////
ExprNode *BinExprNode::semant(Environ *e) {
lhs = lhs->semant(e); lhs = lhs->castTo(Type::int_type, e);
rhs = rhs->semant(e); rhs = rhs->castTo(Type::int_type, e);
ExprNode* BinExprNode::semant(Environ* e)
{
lhs = lhs->semant(e);
lhs = lhs->castTo(Type::int_type, e);
rhs = rhs->semant(e);
rhs = rhs->castTo(Type::int_type, e);
ConstNode *lc = lhs->constNode(), *rc = rhs->constNode();
if (lc && rc) {
ExprNode *expr = nullptr;
ExprNode* expr = nullptr;
switch (op) {
case AND:expr = new IntConstNode(lc->intValue() & rc->intValue()); break;
case OR: expr = new IntConstNode(lc->intValue() | rc->intValue()); break;
case XOR:expr = new IntConstNode(lc->intValue() ^ rc->intValue()); break;
case SHL:expr = new IntConstNode(lc->intValue() << rc->intValue()); break;
case SHR:expr = new IntConstNode((unsigned)lc->intValue() >> rc->intValue()); break;
case SAR:expr = new IntConstNode(lc->intValue() >> rc->intValue()); break;
case AND:
expr = new IntConstNode(lc->intValue() & rc->intValue());
break;
case OR:
expr = new IntConstNode(lc->intValue() | rc->intValue());
break;
case XOR:
expr = new IntConstNode(lc->intValue() ^ rc->intValue());
break;
case SHL:
expr = new IntConstNode(lc->intValue() << rc->intValue());
break;
case SHR:
expr = new IntConstNode((unsigned)lc->intValue() >> rc->intValue());
break;
case SAR:
expr = new IntConstNode(lc->intValue() >> rc->intValue());
break;
}
delete this;
return expr;
@@ -355,13 +438,30 @@ ExprNode *BinExprNode::semant(Environ *e) {
return this;
}
TNode *BinExprNode::translate(Codegen *g) {
TNode *l = lhs->translate(g);
TNode *r = rhs->translate(g);
int n = 0;
TNode* BinExprNode::translate(Codegen* g)
{
TNode* l = lhs->translate(g);
TNode* r = rhs->translate(g);
int n = 0;
switch (op) {
case AND:n = IR_AND; break; case OR:n = IR_OR; break; case XOR:n = IR_XOR; break;
case SHL:n = IR_SHL; break; case SHR:n = IR_SHR; break; case SAR:n = IR_SAR; break;
case AND:
n = IR_AND;
break;
case OR:
n = IR_OR;
break;
case XOR:
n = IR_XOR;
break;
case SHL:
n = IR_SHL;
break;
case SHR:
n = IR_SHR;
break;
case SAR:
n = IR_SAR;
break;
}
return new TNode(n, l, r);
}
@@ -369,7 +469,8 @@ TNode *BinExprNode::translate(Codegen *g) {
///////////////////////////
// arithmetic expression //
///////////////////////////
ExprNode *ArithExprNode::semant(Environ *e) {
ExprNode* ArithExprNode::semant(Environ* e)
{
lhs = lhs->semant(e);
rhs = rhs->semant(e);
if (lhs->sem_type->structType() || rhs->sem_type->structType()) {
@@ -377,7 +478,8 @@ ExprNode *ArithExprNode::semant(Environ *e) {
}
if (lhs->sem_type == Type::string_type || rhs->sem_type == Type::string_type) {
//one side is a string - only + operator...
if (op != '+') ex("Operator cannot be applied to strings");
if (op != '+')
ex("Operator cannot be applied to strings");
sem_type = Type::string_type;
} else if (op == '^' || lhs->sem_type == Type::float_type || rhs->sem_type == Type::float_type) {
//It's ^, or one side is a float
@@ -386,8 +488,8 @@ ExprNode *ArithExprNode::semant(Environ *e) {
//must be 2 ints
sem_type = Type::int_type;
}
lhs = lhs->castTo(sem_type, e);
rhs = rhs->castTo(sem_type, e);
lhs = lhs->castTo(sem_type, e);
rhs = rhs->castTo(sem_type, e);
ConstNode *lc = lhs->constNode(), *rc = rhs->constNode();
if (rc && (op == '/' || op == MOD)) {
if ((sem_type == Type::int_type && !rc->intValue()) || (sem_type == Type::float_type && !rc->floatValue())) {
@@ -395,25 +497,47 @@ ExprNode *ArithExprNode::semant(Environ *e) {
}
}
if (lc && rc) {
ExprNode *expr = nullptr;
ExprNode* expr = nullptr;
if (sem_type == Type::string_type) {
expr = new StringConstNode(lc->stringValue() + rc->stringValue());
} else if (sem_type == Type::int_type) {
switch (op) {
case '+':expr = new IntConstNode(lc->intValue() + rc->intValue()); break;
case '-':expr = new IntConstNode(lc->intValue() - rc->intValue()); break;
case '*':expr = new IntConstNode(lc->intValue()*rc->intValue()); break;
case '/':expr = new IntConstNode(lc->intValue() / rc->intValue()); break;
case MOD:expr = new IntConstNode(lc->intValue() % rc->intValue()); break;
case '+':
expr = new IntConstNode(lc->intValue() + rc->intValue());
break;
case '-':
expr = new IntConstNode(lc->intValue() - rc->intValue());
break;
case '*':
expr = new IntConstNode(lc->intValue() * rc->intValue());
break;
case '/':
expr = new IntConstNode(lc->intValue() / rc->intValue());
break;
case MOD:
expr = new IntConstNode(lc->intValue() % rc->intValue());
break;
}
} else {
switch (op) {
case '+':expr = new FloatConstNode(lc->floatValue() + rc->floatValue()); break;
case '-':expr = new FloatConstNode(lc->floatValue() - rc->floatValue()); break;
case '*':expr = new FloatConstNode(lc->floatValue()*rc->floatValue()); break;
case '/':expr = new FloatConstNode(lc->floatValue() / rc->floatValue()); break;
case MOD:expr = new FloatConstNode(fmod(lc->floatValue(), rc->floatValue())); break;
case '^':expr = new FloatConstNode(pow(lc->floatValue(), rc->floatValue())); break;
case '+':
expr = new FloatConstNode(lc->floatValue() + rc->floatValue());
break;
case '-':
expr = new FloatConstNode(lc->floatValue() - rc->floatValue());
break;
case '*':
expr = new FloatConstNode(lc->floatValue() * rc->floatValue());
break;
case '/':
expr = new FloatConstNode(lc->floatValue() / rc->floatValue());
break;
case MOD:
expr = new FloatConstNode(fmod(lc->floatValue(), rc->floatValue()));
break;
case '^':
expr = new FloatConstNode(pow(lc->floatValue(), rc->floatValue()));
break;
}
}
delete this;
@@ -422,25 +546,49 @@ ExprNode *ArithExprNode::semant(Environ *e) {
return this;
}
TNode *ArithExprNode::translate(Codegen *g) {
TNode *l = lhs->translate(g);
TNode *r = rhs->translate(g);
TNode* ArithExprNode::translate(Codegen* g)
{
TNode* l = lhs->translate(g);
TNode* r = rhs->translate(g);
if (sem_type == Type::string_type) {
return call("__bbStrConcat", l, r);
}
int n = 0;
if (sem_type == Type::int_type) {
switch (op) {
case '+':n = IR_ADD; break; case '-':n = IR_SUB; break;
case '*':n = IR_MUL; break; case '/':n = IR_DIV; break;
case MOD:return call("__bbMod", l, r);
case '+':
n = IR_ADD;
break;
case '-':
n = IR_SUB;
break;
case '*':
n = IR_MUL;
break;
case '/':
n = IR_DIV;
break;
case MOD:
return call("__bbMod", l, r);
}
} else {
switch (op) {
case '+':n = IR_FADD; break; case '-':n = IR_FSUB; break;
case '*':n = IR_FMUL; break; case '/':n = IR_FDIV; break;
case MOD:return fcall("__bbFMod", l, r);
case '^':return fcall("__bbFPow", l, r);
case '+':
n = IR_FADD;
break;
case '-':
n = IR_FSUB;
break;
case '*':
n = IR_FMUL;
break;
case '/':
n = IR_FDIV;
break;
case MOD:
return fcall("__bbFMod", l, r);
case '^':
return fcall("__bbFPow", l, r);
}
}
return new TNode(n, l, r);
@@ -449,11 +597,13 @@ TNode *ArithExprNode::translate(Codegen *g) {
/////////////////////////
// relation expression //
/////////////////////////
ExprNode *RelExprNode::semant(Environ *e) {
ExprNode* RelExprNode::semant(Environ* e)
{
lhs = lhs->semant(e);
rhs = rhs->semant(e);
if (lhs->sem_type->structType() || rhs->sem_type->structType()) {
if (op != '=' && op != NE) ex("Illegal operator for custom type objects");
if (op != '=' && op != NE)
ex("Illegal operator for custom type objects");
opType = lhs->sem_type != Type::null_type ? lhs->sem_type : rhs->sem_type;
} else if (lhs->sem_type == Type::string_type || rhs->sem_type == Type::string_type) {
opType = Type::string_type;
@@ -462,38 +612,74 @@ ExprNode *RelExprNode::semant(Environ *e) {
} else {
opType = Type::int_type;
}
sem_type = Type::int_type;
lhs = lhs->castTo(opType, e);
rhs = rhs->castTo(opType, e);
sem_type = Type::int_type;
lhs = lhs->castTo(opType, e);
rhs = rhs->castTo(opType, e);
ConstNode *lc = lhs->constNode(), *rc = rhs->constNode();
if (lc && rc) {
ExprNode *expr = nullptr;
ExprNode* expr = nullptr;
if (opType == Type::string_type) {
switch (op) {
case '<':expr = new IntConstNode(lc->stringValue() < rc->stringValue()); break;
case '=':expr = new IntConstNode(lc->stringValue() == rc->stringValue()); break;
case '>':expr = new IntConstNode(lc->stringValue() > rc->stringValue()); break;
case LE: expr = new IntConstNode(lc->stringValue() <= rc->stringValue()); break;
case NE: expr = new IntConstNode(lc->stringValue() != rc->stringValue()); break;
case GE: expr = new IntConstNode(lc->stringValue() >= rc->stringValue()); break;
case '<':
expr = new IntConstNode(lc->stringValue() < rc->stringValue());
break;
case '=':
expr = new IntConstNode(lc->stringValue() == rc->stringValue());
break;
case '>':
expr = new IntConstNode(lc->stringValue() > rc->stringValue());
break;
case LE:
expr = new IntConstNode(lc->stringValue() <= rc->stringValue());
break;
case NE:
expr = new IntConstNode(lc->stringValue() != rc->stringValue());
break;
case GE:
expr = new IntConstNode(lc->stringValue() >= rc->stringValue());
break;
}
} else if (opType == Type::float_type) {
switch (op) {
case '<':expr = new IntConstNode(lc->floatValue() < rc->floatValue()); break;
case '=':expr = new IntConstNode(lc->floatValue() == rc->floatValue()); break;
case '>':expr = new IntConstNode(lc->floatValue() > rc->floatValue()); break;
case LE: expr = new IntConstNode(lc->floatValue() <= rc->floatValue()); break;
case NE: expr = new IntConstNode(lc->floatValue() != rc->floatValue()); break;
case GE: expr = new IntConstNode(lc->floatValue() >= rc->floatValue()); break;
case '<':
expr = new IntConstNode(lc->floatValue() < rc->floatValue());
break;
case '=':
expr = new IntConstNode(lc->floatValue() == rc->floatValue());
break;
case '>':
expr = new IntConstNode(lc->floatValue() > rc->floatValue());
break;
case LE:
expr = new IntConstNode(lc->floatValue() <= rc->floatValue());
break;
case NE:
expr = new IntConstNode(lc->floatValue() != rc->floatValue());
break;
case GE:
expr = new IntConstNode(lc->floatValue() >= rc->floatValue());
break;
}
} else {
switch (op) {
case '<':expr = new IntConstNode(lc->intValue() < rc->intValue()); break;
case '=':expr = new IntConstNode(lc->intValue() == rc->intValue()); break;
case '>':expr = new IntConstNode(lc->intValue() > rc->intValue()); break;
case LE: expr = new IntConstNode(lc->intValue() <= rc->intValue()); break;
case NE: expr = new IntConstNode(lc->intValue() != rc->intValue()); break;
case GE: expr = new IntConstNode(lc->intValue() >= rc->intValue()); break;
case '<':
expr = new IntConstNode(lc->intValue() < rc->intValue());
break;
case '=':
expr = new IntConstNode(lc->intValue() == rc->intValue());
break;
case '>':
expr = new IntConstNode(lc->intValue() > rc->intValue());
break;
case LE:
expr = new IntConstNode(lc->intValue() <= rc->intValue());
break;
case NE:
expr = new IntConstNode(lc->intValue() != rc->intValue());
break;
case GE:
expr = new IntConstNode(lc->intValue() >= rc->intValue());
break;
}
}
delete this;
@@ -502,127 +688,157 @@ ExprNode *RelExprNode::semant(Environ *e) {
return this;
}
TNode *RelExprNode::translate(Codegen *g) {
TNode *l = lhs->translate(g);
TNode *r = rhs->translate(g);
TNode* RelExprNode::translate(Codegen* g)
{
TNode* l = lhs->translate(g);
TNode* r = rhs->translate(g);
return compare(op, l, r, opType);
}
////////////////////
// New expression //
////////////////////
ExprNode *NewNode::semant(Environ *e) {
ExprNode* NewNode::semant(Environ* e)
{
sem_type = e->findType(ident);
if (!sem_type) ex("custom type name not found");
if (sem_type->structType() == 0) ex("type is not a custom type");
if (!sem_type)
ex("custom type name not found");
if (sem_type->structType() == 0)
ex("type is not a custom type");
return this;
}
TNode *NewNode::translate(Codegen *g) {
TNode* NewNode::translate(Codegen* g)
{
return call("__bbObjNew", global("_t" + ident));
}
////////////////////
// First of class //
////////////////////
ExprNode *FirstNode::semant(Environ *e) {
ExprNode* FirstNode::semant(Environ* e)
{
sem_type = e->findType(ident);
if (!sem_type) ex("custom type name name not found");
if (!sem_type)
ex("custom type name name not found");
return this;
}
TNode *FirstNode::translate(Codegen *g) {
TNode* FirstNode::translate(Codegen* g)
{
return call("__bbObjFirst", global("_t" + ident));
}
///////////////////
// Last of class //
///////////////////
ExprNode *LastNode::semant(Environ *e) {
ExprNode* LastNode::semant(Environ* e)
{
sem_type = e->findType(ident);
if (!sem_type) ex("custom type name not found");
if (!sem_type)
ex("custom type name not found");
return this;
}
TNode *LastNode::translate(Codegen *g) {
TNode* LastNode::translate(Codegen* g)
{
return call("__bbObjLast", global("_t" + ident));
}
////////////////////
// Next of object //
////////////////////
ExprNode *AfterNode::semant(Environ *e) {
ExprNode* AfterNode::semant(Environ* e)
{
expr = expr->semant(e);
if (expr->sem_type == Type::null_type) ex("'After' cannot be used on 'Null'");
if (expr->sem_type->structType() == 0) ex("'After' must be used with a custom type object");
if (expr->sem_type == Type::null_type)
ex("'After' cannot be used on 'Null'");
if (expr->sem_type->structType() == 0)
ex("'After' must be used with a custom type object");
sem_type = expr->sem_type;
return this;
}
TNode *AfterNode::translate(Codegen *g) {
TNode *t = expr->translate(g);
if (g->debug) t = jumpf(t, "__bbNullObjEx");
TNode* AfterNode::translate(Codegen* g)
{
TNode* t = expr->translate(g);
if (g->debug)
t = jumpf(t, "__bbNullObjEx");
return call("__bbObjNext", t);
}
////////////////////
// Prev of object //
////////////////////
ExprNode *BeforeNode::semant(Environ *e) {
ExprNode* BeforeNode::semant(Environ* e)
{
expr = expr->semant(e);
if (expr->sem_type == Type::null_type) ex("'Before' cannot be used with 'Null'");
if (expr->sem_type->structType() == 0) ex("'Before' must be used with a custom type object");
if (expr->sem_type == Type::null_type)
ex("'Before' cannot be used with 'Null'");
if (expr->sem_type->structType() == 0)
ex("'Before' must be used with a custom type object");
sem_type = expr->sem_type;
return this;
}
TNode *BeforeNode::translate(Codegen *g) {
TNode *t = expr->translate(g);
if (g->debug) t = jumpf(t, "__bbNullObjEx");
TNode* BeforeNode::translate(Codegen* g)
{
TNode* t = expr->translate(g);
if (g->debug)
t = jumpf(t, "__bbNullObjEx");
return call("__bbObjPrev", t);
}
/////////////////
// Null object //
/////////////////
ExprNode *NullNode::semant(Environ *e) {
ExprNode* NullNode::semant(Environ* e)
{
sem_type = Type::null_type;
return this;
}
TNode *NullNode::translate(Codegen *g) {
TNode* NullNode::translate(Codegen* g)
{
return new TNode(IR_CONST, 0, 0, 0);
}
/////////////////
// Object cast //
/////////////////
ExprNode *ObjectCastNode::semant(Environ *e) {
expr = expr->semant(e);
expr = expr->castTo(Type::int_type, e);
ExprNode* ObjectCastNode::semant(Environ* e)
{
expr = expr->semant(e);
expr = expr->castTo(Type::int_type, e);
sem_type = e->findType(type_ident);
if (!sem_type) ex("custom type name not found");
if (!sem_type->structType()) ex("type is not a custom type");
if (!sem_type)
ex("custom type name not found");
if (!sem_type->structType())
ex("type is not a custom type");
return this;
}
TNode *ObjectCastNode::translate(Codegen *g) {
TNode *t = expr->translate(g);
t = call("__bbObjFromHandle", t, global("_t" + sem_type->structType()->ident));
TNode* ObjectCastNode::translate(Codegen* g)
{
TNode* t = expr->translate(g);
t = call("__bbObjFromHandle", t, global("_t" + sem_type->structType()->ident));
return t;
}
///////////////////
// Object Handle //
///////////////////
ExprNode *ObjectHandleNode::semant(Environ *e) {
ExprNode* ObjectHandleNode::semant(Environ* e)
{
expr = expr->semant(e);
if (!expr->sem_type->structType()) ex("'ObjectHandle' must be used with an object");
if (!expr->sem_type->structType())
ex("'ObjectHandle' must be used with an object");
sem_type = Type::int_type;
return this;
}
TNode *ObjectHandleNode::translate(Codegen *g) {
TNode *t = expr->translate(g);
TNode* ObjectHandleNode::translate(Codegen* g)
{
TNode* t = expr->translate(g);
return call("__bbObjToHandle", t);
}