📄 compiler.cpp
字号:
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, fd, expr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -