📄 compiler.cpp
字号:
cop = dbvmEqBinary; if ((expr->cop == dbvmLoadSelfRawBinary || expr->cop == dbvmLoadRawBinary) && expr->ref.field != NULL) { rawBinarySize = expr->ref.field->dbsSize; rawBinaryComparator = (void*)expr->ref.field->comparator; } else if ((elem->cop == dbvmLoadSelfRawBinary || elem->cop == dbvmLoadRawBinary) && elem->ref.field != NULL) { rawBinarySize = elem->ref.field->dbsSize; rawBinaryComparator = (void*)elem->ref.field->comparator; } else { error("Operations with raw binary types should include at least one record field"); } } if (cop == dbvmVoid) { char buf[256]; sprintf(buf, "Expression %d in right part of IN operator have " "incompatible type", n); error(buf); } else { list->type = tpBoolean; if (list->operand[0] != NULL) { expr = new dbExprNode(cop, expr, elem, rawBinarySize); expr->func.fptr = rawBinaryComparator; list->operand[1] = expr; list->cop = dbvmOrBool; } else { list->operand[0] = expr; list->cop = cop; list->offs = rawBinarySize; list->func.fptr = rawBinaryComparator; } } return ++n;}dbExprNode* dbCompiler::comparison(){ int leftPos = currPos; dbExprNode *left, *right; left = addition(); int cop = lex; if (cop == tkn_eq || cop == tkn_ne || cop == tkn_gt || cop == tkn_ge || cop == tkn_le || cop == tkn_lt || cop == tkn_between || cop == tkn_like || cop == tkn_not || cop == tkn_is || cop == tkn_in) { int rightPos = currPos; bool notOp = false; if (cop == tkn_not) { notOp = true; cop = scan(); if (cop != tkn_like && cop != tkn_between && cop != tkn_in) { error("LIKE, BETWEEN or IN expected", rightPos); } rightPos = currPos; } else if (cop == tkn_is) { if (left->type != tpReference) { error("IS [NOT] NULL predicate can be applied only to " "references", rightPos); } rightPos = currPos; if ((cop = scan()) == tkn_null) { left = new dbExprNode(dbvmIsNull, left); } else if (cop == tkn_not) { rightPos = currPos; if (scan() == tkn_null) { left = new dbExprNode(dbvmNotBool, new dbExprNode(dbvmIsNull, left)); } else { error("NULL expected", rightPos); } } else { error("[NOT] NULL expected", rightPos); } lex = scan(); return left; } right = addition(); if (cop == tkn_in) { int type; switch (right->type) { case tpArray: type = (right->cop == dbvmLoadVarArray || right->cop == dbvmLoadVarArrayPtr) ? dbField::tpReference : right->ref.field->components->type; if ((left->type == tpBoolean && type == dbField::tpBool) || (left->type == tpInteger && (type == dbField::tpInt1 || type == dbField::tpInt2 || type == dbField::tpInt4 || type == dbField::tpInt8)) || (left->type == tpReal && (type == dbField::tpReal4 || type == dbField::tpReal8)) || (left->type == tpString && type == dbField::tpString) || ((left->type == tpReference || left->type == tpInteger) && type == dbField::tpReference)) { if (left->type == tpInteger && type == dbField::tpReference) { left = new dbExprNode(dbvmIntToReference, left); } left = new dbExprNode(dbvmInArrayBool + type, left, right); } else { error("Type of selective expression of IN operator doesn't" " match type of the array"); } break; case tpString: if (left->type == tpString) { left = new dbExprNode(dbvmInString, left, right); } else { error("Left operand of IN expression hasn't string type"); } break; case tpList: compare(left, right); left = right; break; default: error("List of expressions or array expected", rightPos); } } else if (cop == tkn_between) { int andPos = currPos; if (lex != tkn_and) { error("AND expected"); } dbExprNode* right2 = addition(); if (left->type == tpReal || right->type == tpReal || right2->type == tpReal) { if (left->type == tpInteger) { left = int2real(left); } else if (left->type != tpReal) { error("operand of BETWEEN operator should be of " "integer, real or string type", leftPos); } if (right->type == tpInteger) { right = int2real(right); } else if (right->type != tpReal) { error("operand of BETWEEN operator should be of " "integer, real or string type", rightPos); } if (right2->type == tpInteger) { right2 = int2real(right2); } else if (right2->type != tpReal) { error("operand of BETWEEN operator should be of " "integer, real or string type", andPos); } left = new dbExprNode(dbvmBetweenReal, left, right, right2); } else if (left->type == tpInteger && right->type == tpInteger && right2->type == tpInteger) { left = new dbExprNode(dbvmBetweenInt, left, right, right2); } else if (left->type == tpString && right->type == tpString && right2->type == tpString) { left = new dbExprNode(dbvmBetweenString, left, right, right2); } else if (left->type == tpRawBinary && right->type == tpRawBinary && right2->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 { error("Operations with raw binary types should include at least one record field"); } left = new dbExprNode(dbvmBetweenBinary, left, right, right2); left->offs = rawBinarySize; left->func.fptr = rawBinaryComparator; } else { error("operands of BETWEEN operator should be of " "integer, real or string type", rightPos); } } else if (cop == tkn_like) { if (left->type != tpString || right->type != tpString) { error("operands of LIKE operator should be of " "string type", rightPos); } if (lex == tkn_escape) { rightPos = currPos; if (scan() != tkn_sconst) { error("String literal espected after ESCAPE", rightPos); } lex = scan(); left = new dbExprNode(dbvmLikeEscapeString, left, right, new dbExprNode(dbvmLoadStringConstant, svalue)); } else { left = new dbExprNode(dbvmLikeString, left, right); } } 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 == 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 == 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); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -