⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compiler.cpp

📁 C-Talk is interpreted scripting language with C-like syntax and dynamic type checking. Variables in
💻 CPP
📖 第 1 页 / 共 4 页
字号:

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 + -