📄 compiler.cpp
字号:
memcpy(str, str+1, w-str-1);
str[w-str-1] = '\0';
right->svalue.len -= 2;
left = new dbExprNode(dbvmInString, right, left);
} else {
left = new dbExprNode(dbvmLikeString, left, right);
}
} else {
left = new dbExprNode(dbvmLikeString, left, right);
}
}
} else if (cop == tkn_overlaps) {
if (left->type == tpRectangle && right->type == tpRectangle) {
if (IS_CONSTANT(left->cop)) {
left = new dbExprNode(dbvmOverlapsRectangle, right, left);
} else {
left = new dbExprNode(dbvmOverlapsRectangle, left, right);
}
} else if (left->type == tpList && right->type == tpRectangle) {
left = new dbExprNode(dbvmOverlapsRectangle, right, rectangleConstant(left));
} else if (left->type == tpRectangle && right->type == tpList) {
left = new dbExprNode(dbvmOverlapsRectangle, left, rectangleConstant(right));
} else {
error("operands of OVERLAPS operator should be of rectangle type", leftPos);
}
} else {
if (left->type == tpReal || right->type == tpReal) {
if (left->type == tpInteger) {
left = int2real(left);
} else if (left->type != tpReal) {
error("operands of relation operator should be of "
"intger, real or string type", leftPos);
}
if (right->type == tpInteger) {
right = int2real(right);
} else if (right->type != tpReal) {
error("operands of relation operator should be of "
"intger, real or string type", rightPos);
}
left = new dbExprNode(dbvmEqReal + cop - tkn_eq, left, right);
} else if (left->type == tpInteger && right->type == tpInteger) {
left = new dbExprNode(dbvmEqInt + cop - tkn_eq, left, right);
} else if (left->type == tpString && right->type == tpString) {
left = new dbExprNode(dbvmEqString + cop-tkn_eq, left, right);
} else if (left->type == tpRectangle && right->type == tpRectangle) {
left = new dbExprNode(dbvmEqRectangle + cop-tkn_eq, left, right);
} else if (left->type == tpList && right->type == tpRectangle) {
left = new dbExprNode(dbvmEqRectangle + cop-tkn_eq, rectangleConstant(left), right);
} else if (left->type == tpRectangle && right->type == tpList) {
left = new dbExprNode(dbvmEqRectangle + cop-tkn_eq, left, rectangleConstant(right));
} else if ((left->type == tpReference || left->type == tpInteger)
&& (right->type == tpReference || right->type == tpInteger))
{
if (cop != tkn_eq && cop != tkn_ne) {
error("References can be checked only for equality",
rightPos);
}
if (left->type == tpInteger) {
left = new dbExprNode(dbvmIntToReference, left);
} else if (right->type == tpInteger) {
right = new dbExprNode(dbvmIntToReference, right);
}
left = new dbExprNode(dbvmEqReference+cop-tkn_eq, left, right);
} else if (left->type == tpBoolean && right->type == tpBoolean) {
if (cop != tkn_eq && cop != tkn_ne) {
error("Boolean variables can be checked only for equality",
rightPos);
}
left = new dbExprNode(dbvmEqBool + cop - tkn_eq, left, right);
} else if (left->type == tpRawBinary && right->type == tpRawBinary) {
int rawBinarySize = 0;
void* rawBinaryComparator = NULL;
if ((left->cop == dbvmLoadSelfRawBinary || left->cop == dbvmLoadRawBinary)
&& left->ref.field != NULL)
{
rawBinarySize = left->ref.field->dbsSize;
rawBinaryComparator = (void*)left->ref.field->comparator;
} else if ((right->cop == dbvmLoadSelfRawBinary || right->cop == dbvmLoadRawBinary)
&& right->ref.field != NULL)
{
rawBinarySize = right->ref.field->dbsSize;
rawBinaryComparator = (void*)right->ref.field->comparator;
} else {
error("Operations with raw binary types should include at least one record field");
}
left = new dbExprNode(dbvmEqBinary + cop - tkn_eq, left, right, rawBinarySize);
left->func.fptr = rawBinaryComparator;
} else {
error("operands of relation operator should be of "
"integer, real or string type", rightPos);
}
//
// Optimization for applying indices: if operation is
// commuatative and left operand is constant then swap operands
//
if (IS_CONSTANT(left->operand[0]->cop)) {
right = left->operand[1];
left->operand[1] = left->operand[0];
left->operand[0] = right;
left->cop = dbExprNode::commutativeOperator[left->cop];
}
}
if (notOp) {
left = new dbExprNode(dbvmNotBool, left);
}
}
return left;
}
dbExprNode* dbCompiler::addition()
{
int leftPos = currPos;
dbExprNode* left = multiplication();
while (lex == tkn_add || lex == tkn_sub) {
int cop = lex;
int rightPos = currPos;
dbExprNode* right = multiplication();
if (left->type == tpReal || right->type == tpReal) {
if (left->type == tpInteger) {
left = int2real(left);
} else if (left->type != tpReal) {
error("operands of arithmetic operators should be of "
"integer or real type", leftPos);
}
if (right->type == tpInteger) {
right = int2real(right);
} else if (right->type != tpReal) {
error("operands of arithmetic operator should be of "
"integer or real type", rightPos);
}
left = new dbExprNode(cop==tkn_add ? dbvmAddReal : dbvmSubReal,
left, right);
} else if (left->type == tpInteger && right->type == tpInteger) {
left = new dbExprNode(cop==tkn_add ? dbvmAddInt : dbvmSubInt,
left, right);
} else if (left->type == tpRectangle || right->type == tpRectangle) {
if (cop == tkn_add) {
if (left->type == tpRectangle || right->type == tpRectangle) {
left = new dbExprNode(dbvmAddRectangle, left, right);
} else if (left->type == tpRectangle || right->type == tpList) {
left = new dbExprNode(dbvmAddRectangle, left, rectangleConstant(right));
} else if (right->type == tpRectangle || left->type == tpList) {
left = new dbExprNode(dbvmAddRectangle, rectangleConstant(left), right);
} else {
error("Rectangle can be added only with rectangle", rightPos);
}
} else {
error("Operation - is not defined for rectangles", rightPos);
}
} else if (left->type == tpString && right->type == tpString) {
if (cop == tkn_add) {
left = new dbExprNode(dbvmStringConcat, left, right);
} else {
error("Operation - is not defined for strings", rightPos);
}
} else {
error("operands of arithmentic operator should be of "
"integer or real type", rightPos);
}
leftPos = rightPos;
}
return left;
}
dbExprNode* dbCompiler::multiplication()
{
int leftPos = currPos;
dbExprNode* left = power();
while (lex == tkn_mul || lex == tkn_div) {
int cop = lex;
int rightPos = currPos;
dbExprNode* right = power();
if (left->type == tpReal || right->type == tpReal) {
if (left->type == tpInteger) {
left = int2real(left);
} else if (left->type != tpReal) {
error("operands of arithmetic operators should be of "
"integer or real type", leftPos);
}
if (right->type == tpInteger) {
right = int2real(right);
} else if (right->type != tpReal) {
error("operands of arithmetic operator should be of "
"integer or real type", rightPos);
}
left = new dbExprNode(cop==tkn_mul ? dbvmMulReal : dbvmDivReal,
left, right);
} else if (left->type == tpInteger && right->type == tpInteger) {
left = new dbExprNode(cop==tkn_mul ? dbvmMulInt : dbvmDivInt,
left, right);
} else {
error("operands of arithmentic operator should be of "
"integer or real type", rightPos);
}
leftPos = rightPos;
}
return left;
}
dbExprNode* dbCompiler::power()
{
int leftPos = currPos;
dbExprNode* left = userDefinedOperator();
if (lex == tkn_power) {
int rightPos = currPos;
dbExprNode* right = power();
if (left->type == tpReal || right->type == tpReal) {
int cop = dbvmPowerReal;
if (left->type == tpInteger) {
left = int2real(left);
} else if (left->type != tpReal) {
error("operands of arithmetic operators should be of "
"integer or real type", leftPos);
}
if (right->type == tpInteger) {
cop = dbvmPowerRealInt;
} else if (right->type != tpReal) {
error("operands of arithmetic operator should be of "
"integer or real type", rightPos);
}
left = new dbExprNode(cop, left, right);
} else if (left->type == tpInteger && right->type == tpInteger) {
left = new dbExprNode(dbvmPowerInt, left, right);
} else {
error("operands of arithmentic operator should be of "
"integer or real type", rightPos);
}
}
return left;
}
dbExprNode* dbCompiler::userDefinedOperator()
{
dbExprNode* left = term();
while (lex == tkn_ident) {
dbUserFunction* func = dbUserFunction::find(name);
if (func != NULL) {
int nParams = func->getNumberOfParameters();
if (nParams != 2) {
error("Only function with two arguments can be used as operator", currPos);
}
int rightPos = currPos;
dbExprNode* right = term();
if ((left->type != tpInteger && left->type != tpReal && left->type != tpString
&& left->type != tpReference && left->type != tpRawBinary && left->type != tpBoolean)
|| (right->type != tpInteger && right->type != tpReal && right->type != tpString
&& right->type != tpReference && right->type != tpRawBinary && right->type != tpBoolean))
{
error("User function should receive parameter of boolean, integer, real, string, reference or user defined type", rightPos);
}
left = new dbExprNode(dbvmFuncInt2Bool + func->type, func->fptr, left, right);
} else {
break;
}
}
return left;
}
dbExprNode* dbCompiler::field(dbExprNode* expr, dbTableDescriptor* refTable,
dbFieldDescriptor* fd)
{
int pos;
while (true) {
switch (lex) {
case tkn_dot:
pos = currPos;
if (scan() != tkn_ident) {
error("identifier expected", pos);
}
if (fd != NULL && fd->type == dbField::tpStructure) {
if ((fd = fd->find(name)) == NULL) {
error("Field not found");
}
} else {
assert(expr != NULL);
if (expr->type != tpReference) {
error("Left operand of '.' should be "
"structure or reference", pos);
}
if (refTable == NULL) {
refTable = fd->refTable;
}
if (refTable == NULL) {
refTable = fd->refTable;
}
if (refTable == NULL || (fd = refTable->findSymbol(name)) == NULL) {
error("Field not found");
}
refTable = NULL;
expr = new dbExprNode(dbvmDeref, expr);
}
break;
case tkn_lbr:
if (expr == NULL ||
(expr->type != tpArray && expr->type != tpString && expr->type != tpRectangle))
{
error("Index can be applied only to arrays");
} else {
dbExprNode* index = disjunction();
if (lex != tkn_rbr) {
error("']' expected");
}
if (index->type != tpInteger && index->type != tpFreeVar) {
error("Index should have integer type");
}
if (expr->type == tpString) {
lex = scan();
return new dbExprNode(dbvmCharAt, expr, index);
} if (expr->type == tpRectangle) {
lex = scan();
return new dbExprNode(dbvmRectangleCoord, expr, index);
}
if (fd == NULL) {
// variable of array of reference type
expr = new dbExprNode(dbvmGetAt,expr,index,sizeof(oid_t));
} else {
if (refTable == NULL) {
refTable = fd->refTable;
}
fd = fd->components;
expr = new dbExprNode(dbvmGetAt, expr, index, fd->dbsSize);
}
}
break;
default:
if (expr == NULL) {
error("'.' expected");
}
return expr;
}
if (fd == NULL) {
expr = new dbExprNode(dbvmLoadReference, expr, 0);
} else if (fd->type == dbField::tpRawBinary) {
expr = new dbExprNode(expr != NULL ? dbvmLoadRawBinary : dbvmLoadSelfRawBinary,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -