📄 compiler.cpp
字号:
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)) { 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 (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); } else if (fd->type != dbField::tpStructure) { expr = new dbExprNode((expr != NULL ? dbvmLoadBool : dbvmLoadSelfBool) + fd->type, fd, expr); } lex = scan(); }}dbExprNode* dbCompiler::term() { dbFieldDescriptor* fd; dbTableDescriptor* refTable; int cop; int pos = currPos; dbBinding* bp; dbExprNode* expr = NULL; dbUserFunction* func; if ((cop = scan()) == tkn_where) { if (firstPos == 0) { firstPos = currPos; } cop = scan(); // just ignore 'where' keyword } switch (cop) { case tkn_eof: case tkn_order: case tkn_start: lex = cop; return new dbExprNode(dbvmVoid); case tkn_current: lex = scan(); return field(new dbExprNode(dbvmCurrent), table, NULL); case tkn_ident: for (bp = bindings; bp != NULL; bp = bp->next) { if (name == bp->name) { bp->used = true; lex = scan(); return new dbExprNode(dbvmVariable, (dbExprNode*)0, bp->index); } } if ((fd = table->findSymbol(name)) == NULL) { if ((func = dbUserFunction::find(name)) != NULL) { pos = currPos; expr = term(); int argType = func->getParameterType(); int nParams = func->getNumberOfParameters(); if (nParams > 1) { if (expr->type != tpList) { error("Too few paramters for user defined function"); } dbExprNode* params[3]; do { if (nParams == 0) { error("Too many parameters for user defined function"); } dbExprNode* param = expr->operand[1]; if (param->type != tpInteger && param->type != tpReal && param->type != tpString && param->type != tpReference && param->type != tpRawBinary && param->type != tpBoolean) { error("User function should receive parameters of boolean, integer, real, string, reference or user defined type", pos); } params[--nParams] = param; expr = expr->operand[0]; } while (expr != NULL); if (nParams != 0) { error("Too few parameters for user defined function"); } expr = new dbExprNode(dbvmFuncInt2Bool + func->type, func->fptr, params[0], params[1], params[2]); } else { if (argType == tpReal && expr->type == tpInteger) { expr = int2real(expr); } else if (argType == tpList) { if (expr->type != tpInteger && expr->type != tpReal && expr->type != tpString && expr->type != tpReference && expr->type != tpRawBinary && expr->type != tpBoolean) { error("User function should receive parameter of boolean, integer, real, string, reference or user defined type", pos); } } else if (argType != expr->type) { error("Incompatible function argument", pos); } expr = new dbExprNode(dbvmFuncInt2Bool + func->type, func->fptr, expr); } return field(expr, NULL, NULL); } error("Field not found", pos); } if (fd->type == dbField::tpRawBinary) { expr = new dbExprNode(dbvmLoadSelfRawBinary, fd); } else if (fd->type != dbField::tpStructure) { expr = new dbExprNode(dbvmLoadSelfBool + fd->type, fd); } lex = scan(); return field(expr, NULL, fd); case tkn_exists: if (scan() == tkn_ident) { dbBinding var; var.next = bindings; var.name = name; var.used = false; var.index = nFreeVars++; bindings = &var; if (nFreeVars >= maxFreeVars) { error("Too many nested EXISTS clauses\n"); } pos = currPos; if (scan() != tkn_col) { error("':' expected", pos); } expr = term(); if (expr->type != tpBoolean) { error("Expresion in EXISTS clause should be of boolean type"); } if (var.used) { expr = new dbExprNode(dbvmExists, expr, nFreeVars-1); } nFreeVars -= 1; assert(bindings == &var); bindings = var.next; return expr; } else { error("Free variable name expected"); } break; case tkn_first: lex = scan(); return field(new dbExprNode(dbvmFirst), table, NULL); case tkn_last: lex = scan(); return field(new dbExprNode(dbvmLast), table, NULL); case tkn_false: expr = new dbExprNode(dbvmLoadFalse); break; case tkn_true: expr = new dbExprNode(dbvmLoadTrue); break; case tkn_null: expr = new dbExprNode(dbvmLoadNull); break; case tkn_iconst: expr = new dbExprNode(dbvmLoadIntConstant, ivalue); break; case tkn_fconst: expr = new dbExprNode(dbvmLoadRealConstant, fvalue); break; case tkn_sconst: expr = new dbExprNode(dbvmLoadStringConstant, svalue); lex = scan(); return field(expr, NULL, NULL); case tkn_var: expr = new dbExprNode(dbvmLoadVarBool + varType - dbQueryElement::qVarBool, varPtr); refTable = varRefTable; lex = scan(); return field(expr, refTable, NULL); case tkn_abs: case tkn_length: case tkn_lower: case tkn_upper: case tkn_integer: case tkn_real: case tkn_string: pos = currPos; expr = term(); switch (cop) { case tkn_abs: if (expr->type == tpInteger) { cop = dbvmAbsInt; } else if (expr->type == tpReal) { cop = dbvmAbsReal; } else { error("ABS function can be applied only " "to integer or real expression", pos); } break; case tkn_length: if (expr->type == tpArray) { cop = dbvmLength; } else if (expr->type == tpString) { cop = dbvmStringLength; } else { error("LENGTH function is defined only for arrays and strings", pos); } break; case tkn_integer: if (expr->type == tpReal) { cop = dbvmRealToInt; } else { error("INTEGER function can be applied only to " "expression of real type", pos); } break; case tkn_real: if (expr->type == tpInteger) { cop = dbvmIntToReal; } else { error("REAL function can be applied only to " "expression of integer type", pos); } break; case tkn_string: if (expr->type == tpInteger) { cop = dbvmIntToString; } else if (expr->type == tpReal) { cop = dbvmRealToString; } else { error("STRING function can be applied only " "to integer or real expression", pos); } break; case tkn_lower: if (expr->type != tpString) { error("LOWER function can be applied only to string argument", pos); } else { cop = dbvmLowerString; } break; case tkn_upper: if (expr->type != tpString) { error("UPPER function can be applied only to string argument", pos); } else { cop = dbvmUpperString; } break; default: assert(false); } return field(new dbExprNode(cop, expr), NULL, NULL); case tkn_lpar: { expr = disjunction(); dbExprNode* list = NULL; while (lex == tkn_comma) { list = new dbExprNode(dbvmList, list, expr); expr = disjunction(); } if (lex != tkn_rpar) { error("')' expected");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -