📄 compiler.cpp
字号:
CtkObject CtkLandExpr::getRvalue(CtkFrame* frame)
{
CtkObject result;
if (left->testCondition(frame)) {
MAKE_INTEGER(result, right->testCondition(frame));
} else {
MAKE_INTEGER(result, 0);
}
PUSH_CS(frame->thread, result);
return result;
}
CtkObject CtkLorExpr::getRvalue(CtkFrame* frame)
{
CtkObject result;
if (left->testCondition(frame)) {
MAKE_INTEGER(result, 1);
} else {
MAKE_INTEGER(result, right->testCondition(frame));
}
PUSH_CS(frame->thread, result);
return result;
}
void CtkAssignExpr::compile(CtkCompiler* compiler, CompileCtx) {
left->compile(compiler, CC_LVALUE);
right->compile(compiler, CC_RVALUE);
if (!left->isLvalue()) {
compiler->error("Left operand should be L-Value", left);
}
}
CtkObject CtkAssignExpr::getRvalue(CtkFrame* frame)
{
CtkObject value = right->getRvalue(frame);
left->assign(frame, value);
return value;
}
CtkObject CtkSetAddExpr::getRvalue(CtkFrame* frame)
{
CtkObject rvalue = right->getRvalue(frame);
CtkObject lvalue = left->getLvalue(frame);
if (lvalue.type == CTK_ARRAY && rvalue.type == CTK_ARRAY) {
CtkMemoryManager::instance.beginAccess(frame->thread);
ctkAddArray((CtkArray*)lvalue.u.ptr, (CtkArray*)rvalue.u.ptr);
POP4(frame->thread);
PUSH(frame->thread, lvalue);
CtkMemoryManager::instance.endAccess(frame->thread);
} else if (lvalue.type == CTK_INTEGER && rvalue.type == CTK_INTEGER) {
lvalue.u.ivalue += rvalue.u.ivalue;
left->setLvalue(frame, lvalue);
TOP(frame->thread).u.ivalue = lvalue.u.ivalue;
} else if (lvalue.type == CTK_REAL && rvalue.type == CTK_INTEGER) {
lvalue.u.rvalue += rvalue.u.ivalue;
left->setLvalue(frame, lvalue);
TOP(frame->thread).u.rvalue = lvalue.u.rvalue;
TOP(frame->thread).type = CTK_REAL;
} else if (lvalue.type == CTK_INTEGER && rvalue.type == CTK_REAL) {
lvalue.u.rvalue = lvalue.u.ivalue + rvalue.u.rvalue;
lvalue.type = CTK_REAL;
left->setLvalue(frame, lvalue);
TOP(frame->thread).u.rvalue = lvalue.u.rvalue;
TOP(frame->thread).type = CTK_REAL;
} else if (lvalue.type == CTK_REAL && rvalue.type == CTK_REAL) {
lvalue.u.rvalue += rvalue.u.rvalue;
left->setLvalue(frame, lvalue);
TOP(frame->thread).u.rvalue = lvalue.u.rvalue;
} else if (lvalue.type == CTK_STRING && rvalue.type == CTK_STRING) {
CtkMemoryManager::instance.beginAccess(frame->thread);
int headLen = strlen(lvalue.u.svalue);
int tailLen = strlen(rvalue.u.svalue);
char* p = (char*)ctkAllocateObject(headLen + tailLen + 1, NULL);
memcpy(p, lvalue.u.svalue, headLen);
memcpy(p + headLen, rvalue.u.svalue, tailLen+1);
lvalue.u.svalue = p;
left->setLvalue(frame, lvalue);
POP(frame->thread);
PUSH(frame->thread, lvalue);
CtkMemoryManager::instance.endAccess(frame->thread);
} else {
THROW_EXCEPTION("Bad operands for += operator");
}
return lvalue;
}
CtkObject CtkSetSubExpr::getRvalue(CtkFrame* frame)
{
CtkObject rvalue = right->getRvalue(frame);
CtkObject lvalue = left->getLvalue(frame);
if (lvalue.type == CTK_ARRAY) {
CtkMemoryManager::instance.beginAccess(frame->thread);
if (rvalue.type == CTK_ARRAY) {
ctkSubArray((CtkArray*)lvalue.u.ptr, (CtkArray*)rvalue.u.ptr);
} else {
ctkDelArray((CtkArray*)lvalue.u.ptr, rvalue);
}
POP4(frame->thread);
PUSH(frame->thread, lvalue);
CtkMemoryManager::instance.endAccess(frame->thread);
} else if (lvalue.type == CTK_INTEGER && rvalue.type == CTK_INTEGER) {
lvalue.u.ivalue -= rvalue.u.ivalue;
left->setLvalue(frame, lvalue);
TOP(frame->thread).u.ivalue = lvalue.u.ivalue;
} else if (lvalue.type == CTK_REAL && rvalue.type == CTK_INTEGER) {
lvalue.u.rvalue -= rvalue.u.ivalue;
left->setLvalue(frame, lvalue);
TOP(frame->thread).u.rvalue = lvalue.u.rvalue;
TOP(frame->thread).type = CTK_REAL;
} else if (lvalue.type == CTK_INTEGER && rvalue.type == CTK_REAL) {
lvalue.u.rvalue = lvalue.u.ivalue - rvalue.u.rvalue;
lvalue.type = CTK_REAL;
left->setLvalue(frame, lvalue);
TOP(frame->thread).u.rvalue = lvalue.u.rvalue;
TOP(frame->thread).type = CTK_REAL;
} else if (lvalue.type == CTK_REAL && rvalue.type == CTK_REAL) {
lvalue.u.rvalue -= rvalue.u.rvalue;
left->setLvalue(frame, lvalue);
TOP(frame->thread).u.rvalue = lvalue.u.rvalue;
} else {
THROW_EXCEPTION("Bad operands for -= operator");
}
return lvalue;
}
CtkObject CtkSetMulExpr::getRvalue(CtkFrame* frame)
{
CtkObject rvalue = right->getRvalue(frame);
CtkObject lvalue = left->getLvalue(frame);
if (lvalue.type == CTK_INTEGER && rvalue.type == CTK_INTEGER) {
lvalue.u.ivalue *= rvalue.u.ivalue;
left->setLvalue(frame, lvalue);
TOP(frame->thread).u.ivalue = lvalue.u.ivalue;
} else if (lvalue.type == CTK_REAL && rvalue.type == CTK_INTEGER) {
lvalue.u.rvalue *= rvalue.u.ivalue;
left->setLvalue(frame, lvalue);
TOP(frame->thread).u.rvalue = lvalue.u.rvalue;
TOP(frame->thread).type = CTK_REAL;
} else if (lvalue.type == CTK_INTEGER && rvalue.type == CTK_REAL) {
lvalue.u.rvalue = lvalue.u.ivalue * rvalue.u.rvalue;
lvalue.type = CTK_REAL;
left->setLvalue(frame, lvalue);
TOP(frame->thread).u.rvalue = lvalue.u.rvalue;
TOP(frame->thread).type = CTK_REAL;
} else if (lvalue.type == CTK_REAL && rvalue.type == CTK_REAL) {
lvalue.u.rvalue *= rvalue.u.rvalue;
left->setLvalue(frame, lvalue);
TOP(frame->thread).u.rvalue = lvalue.u.rvalue;
} else {
THROW_EXCEPTION("Bad operands for *= operator");
}
return lvalue;
}
CtkObject CtkSetDivExpr::getRvalue(CtkFrame* frame)
{
CtkObject rvalue = right->getRvalue(frame);
CtkObject lvalue = left->getLvalue(frame);
if (rvalue.type == CTK_INTEGER) {
if (rvalue.u.ivalue == 0) {
THROW_EXCEPTION("Divided by zero");
}
if (lvalue.type == CTK_INTEGER) {
lvalue.u.ivalue /= rvalue.u.ivalue;
left->setLvalue(frame, lvalue);
TOP(frame->thread).u.ivalue = lvalue.u.ivalue;
} else if (lvalue.type == CTK_REAL) {
lvalue.u.rvalue /= rvalue.u.ivalue;
left->setLvalue(frame, lvalue);
TOP(frame->thread).u.rvalue = lvalue.u.rvalue;
TOP(frame->thread).type = CTK_REAL;
} else {
THROW_EXCEPTION("Bad operands for /= operator");
}
} else if (rvalue.type == CTK_REAL) {
if (rvalue.u.rvalue == 0.0) {
THROW_EXCEPTION("Divided by zero");
}
if (lvalue.type == CTK_INTEGER) {
lvalue.u.rvalue = lvalue.u.ivalue / rvalue.u.rvalue;
lvalue.type = CTK_REAL;
left->setLvalue(frame, lvalue);
TOP(frame->thread).u.rvalue = lvalue.u.rvalue;
TOP(frame->thread).type = CTK_REAL;
} else if (lvalue.type == CTK_REAL) {
lvalue.u.rvalue /= rvalue.u.rvalue;
left->setLvalue(frame, lvalue);
TOP(frame->thread).u.rvalue = lvalue.u.rvalue;
} else {
THROW_EXCEPTION("Bad operands for /= operator");
}
} else {
THROW_EXCEPTION("Bad operands for /= operator");
}
return lvalue;
}
CtkObject CtkSetModExpr::getRvalue(CtkFrame* frame)
{
CtkObject rvalue = right->getRvalue(frame);
CtkObject lvalue = left->getLvalue(frame);
if (rvalue.type == CTK_INTEGER && lvalue.type == CTK_INTEGER) {
if (rvalue.u.ivalue == 0) {
THROW_EXCEPTION("Divided by zero");
}
lvalue.u.ivalue %= rvalue.u.ivalue;
left->setLvalue(frame, lvalue);
TOP(frame->thread).u.ivalue = lvalue.u.ivalue;
} else {
THROW_EXCEPTION("Bad operands for %= operator");
}
return lvalue;
}
CtkObject CtkSetOrExpr::getRvalue(CtkFrame* frame)
{
CtkObject rvalue = right->getRvalue(frame);
CtkObject lvalue = left->getLvalue(frame);
if (lvalue.type == CTK_INTEGER && rvalue.type == CTK_INTEGER) {
lvalue.u.ivalue |= rvalue.u.ivalue;
} else {
THROW_EXCEPTION("Bad operands for |= operator");
}
left->setLvalue(frame, lvalue);
TOP(frame->thread).u.ivalue = lvalue.u.ivalue;
return lvalue;
}
CtkObject CtkSetXorExpr::getRvalue(CtkFrame* frame)
{
CtkObject rvalue = right->getRvalue(frame);
CtkObject lvalue = left->getLvalue(frame);
if (lvalue.type == CTK_INTEGER && rvalue.type == CTK_INTEGER) {
lvalue.u.ivalue ^= rvalue.u.ivalue;
} else {
THROW_EXCEPTION("Bad operands for ^= operator");
}
left->setLvalue(frame, lvalue);
TOP(frame->thread).u.ivalue = lvalue.u.ivalue;
return lvalue;
}
CtkObject CtkSetAndExpr::getRvalue(CtkFrame* frame)
{
CtkObject rvalue = right->getRvalue(frame);
CtkObject lvalue = left->getLvalue(frame);
if (lvalue.type == CTK_INTEGER && rvalue.type == CTK_INTEGER) {
lvalue.u.ivalue &= rvalue.u.ivalue;
} else {
THROW_EXCEPTION("Bad operands for &= operator");
}
left->setLvalue(frame, lvalue);
TOP(frame->thread).u.ivalue = lvalue.u.ivalue;
return lvalue;
}
CtkObject CtkSetShlExpr::getRvalue(CtkFrame* frame)
{
CtkObject rvalue = right->getRvalue(frame);
CtkObject lvalue = left->getLvalue(frame);
if (lvalue.type == CTK_INTEGER && rvalue.type == CTK_INTEGER) {
lvalue.u.ivalue <<= rvalue.u.ivalue & (sizeof(ctk_integer)*8-1);
} else {
THROW_EXCEPTION("Bad operands for <<= operator");
}
left->setLvalue(frame, lvalue);
TOP(frame->thread).u.ivalue = lvalue.u.ivalue;
return lvalue;
}
CtkObject CtkSetShrExpr::getRvalue(CtkFrame* frame)
{
CtkObject rvalue = right->getRvalue(frame);
CtkObject lvalue = left->getLvalue(frame);
if (lvalue.type == CTK_INTEGER && rvalue.type == CTK_INTEGER) {
lvalue.u.ivalue = (ctk_unsigned_integer)lvalue.u.ivalue >> (rvalue.u.ivalue & (sizeof(ctk_integer)*8-1));
} else {
THROW_EXCEPTION("Bad operands for >>= operator");
}
left->setLvalue(frame, lvalue);
TOP(frame->thread).u.ivalue = lvalue.u.ivalue;
return lvalue;
}
void CtkCondExpr::compile(CtkCompiler* compiler, CompileCtx)
{
cond->compile(compiler);
trueExpr->compile(compiler);
falseExpr->compile(compiler);
}
CtkObject CtkCondExpr::getRvalue(CtkFrame* frame)
{
CtkObject result = cond->getRvalue(frame);
if (IS_TRUE(result)) {
POP(frame->thread);
result = trueExpr->getRvalue(frame);
} else {
POP(frame->thread);
result = falseExpr->getRvalue(frame);
}
return result;
}
void CtkUnaryExpr::compile(CtkCompiler* compiler, CompileCtx)
{
expr->compile(compiler);
}
CtkObject CtkNegExpr::getRvalue(CtkFrame* frame)
{
CtkObject result = expr->getRvalue(frame);
if (result.type == CTK_INTEGER) {
TOP(frame->thread).u.ivalue = result.u.ivalue = -result.u.ivalue;
} else if (result.type == CTK_REAL) {
TOP(frame->thread).u.rvalue = result.u.rvalue = -result.u.rvalue;
} else {
THROW_EXCEPTION("Bad operand for unary minus operator");
}
return result;
}
CtkObject CtkNotExpr::getRvalue(CtkFrame* frame)
{
CtkObject result = expr->getRvalue(frame);
if (result.type != CTK_INTEGER) {
THROW_EXCEPTION("Bad operand for ! operator");
}
TOP(frame->thread).u.ivalue = result.u.ivalue = !result.u.ivalue;
return result;
}
CtkObject CtkComExpr::getRvalue(CtkFrame* frame)
{
CtkObject result = expr->getRvalue(frame);
if (result.type != CTK_INTEGER) {
THROW_EXCEPTION("Bad operand for ~ operator");
}
TOP(frame->thread).u.ivalue = result.u.ivalue = ~result.u.ivalue;
return result;
}
void CtkPreIncExpr::compile(CtkCompiler* compiler, CompileCtx ctx)
{
CtkUnaryExpr::compile(compiler, ctx);
if (!expr->isLvalue()) {
compiler->error("Lvalue expected for ++ operator", expr);
}
}
CtkObject CtkPreIncExpr::getRvalue(CtkFrame* frame)
{
CtkObject result = expr->getLvalue(frame);
switch (result.type) {
case CTK_INTEGER:
result.u.ivalue += 1;
expr->setLvalue(frame, result);
break;
case CTK_REAL:
result.u.rvalue += 1.0;
expr->setLvalue(frame, result);
break;
default:
THROW_EXCEPTION("Bad operand for ++ operator");
}
PUSH_CHECK_CS(frame->thread, result);
return result;
}
void CtkPreDecExpr::compile(CtkCompiler* compiler, CompileCtx ctx)
{
CtkUnaryExpr::compile(compiler, ctx);
if (!expr->isLvalue()) {
compiler->error("Lvalue expected for -- operator", expr);
}
}
CtkObject CtkPreDecExpr::getRvalue(CtkFrame* frame)
{
CtkObject result = expr->getLvalue(frame);
switch (result.type) {
case CTK_INTEGER:
result.u.ivalue -= 1;
expr->setLvalue(frame, result);
break;
case CTK_REAL:
result.u.rvalue -= 1.0;
expr->setLvalue(frame, result);
break;
default:
THROW_EXCEPTION("Bad operand for ++ operator");
}
PUSH_CHECK_CS(frame->thread, result);
return result;
}
void CtkPostIncExpr::compile(CtkCompiler* compiler, CompileCtx ctx)
{
CtkUnaryExpr::compile(compiler, ctx);
if (!expr->isLvalue()) {
compiler->error("Lvalue expected for ++ operator", expr);
}
}
CtkObject CtkPostIncExpr::getRvalue(CtkFrame* frame)
{
CtkObject result = expr->getLvalue(frame);
CtkObject newResult = result;
switch (result.type) {
case CTK_INTEGER:
newResult.u.ivalue += 1;
expr->setLvalue(frame, newResult);
break;
case CTK_REAL:
newResult.u.rvalue += 1.0;
expr->setLvalue(frame, newResult);
break;
default:
THROW_EXCEPTION("Bad operand for ++ operator");
}
PUSH_CHECK_CS(frame->thread, result);
return result;
}
void CtkPostDecExpr::compile(CtkCompiler* compiler, CompileCtx ctx)
{
CtkUnaryExpr::compile(compiler, ctx);
if (!expr->isLvalue()) {
compiler->error("Lvalue expected for -- operator", expr);
}
}
CtkObject CtkPostDecExpr::getRvalue(CtkFrame* frame)
{
CtkObject result = expr->getLvalue(frame);
CtkObject newResult = result;
switch (result.type) {
case CTK_INTEGER:
newResult.u.ivalue -= 1;
expr->setLvalue(frame, newResult);
break;
case CTK_REAL:
newResult.u.rvalue -= 1.0;
expr->setLvalue(frame, newResult);
break;
default:
THROW_EXCEPTION("Bad operand for ++ operator");
}
PUSH_CHECK_CS(frame->thread, result);
return result;
}
CtkObject CtkEnvExpr::getRvalue(CtkFrame* frame)
{
CtkObject name = expr->getRvalue(frame);
char* value = getenv(TO_STRING(name));
CtkObject result;
if (value == NULL) {
result = ctkNull;
POP(frame->thread);
PUSH_CS(frame->thread, result);
} else {
CtkMemoryManager::instance.beginAccess(frame->thread);
result.u.svalue = (char*)ctkAllocateObject(strlen(value)+1, NULL);
TOP(frame->thread).u.svalue = result.u.svalue;
strcpy(result.u.svalue, value);
result.type = CTK_STRING;
CtkMemoryManager::instance.endAccess(frame->thread);
}
return result;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -