BOOL instrAssign(unsigned argc, char *argv[]) { ADDR adr, tadr; REG val, tval; REG datamask = ONES(41); unsigned i, slot; BOOL ret = YES; Bundle bndl; InstID instID; Operands ops; EncodedInst inst; if (!evalExpr(argv[0], HEXEXP, &adr)) return NO; if ((slot = SLOT(adr)) > 2) { cmdErr("Illegal slot field in instruction address\n"); return NO; } if (adr != (tadr = adr & ~(ADDR)0x3)) { adr = tadr; cmdWarn("Non slot-aligned address. Aligned to 0x%llx\n", adr); } badr = adr & ~(ADDR)0xf; /* bundle-align address */ for (i = 1; i < argc; i++, slot++) { if (slot >= SLOTS_PER_BUNDLE) { slot = 0; badr += 16; } if (asm_inst(argv[i], &instID, &ops, &inst) != AsmOK) { if (evalExpr(argv[i], HEXEXP, &val)) { if (val != (tval = val & datamask)) { val = tval; cmdWarn("Data larger than 41 bits. Truncated to 0x%llx\n", val); } inst.bits = val; inst.unit = No_Unit; inst.valid_extra_bits = 0; } else break; } if (!memMIRd(badr, (DWORD *)&bndl)) { cmdWarn("Assignment failed\n"); continue; } if (!instrReplace(&bndl, badr, slot, &inst)) { cmdWarn("That instruction not allowed in that slot\n"); continue; } (void)memMIWrt(badr, (DWORD *)&bndl); if (inst.valid_extra_bits) slot++; } if (i != argc) { cmdErr("Some values could not be assigned\n"); ret = NO; } prgwUpdate(); datwUpdate(); return ret; }
static int parseExpr(ej_t *ep, int state, int flags) { char_t *lhs, *rhs; int rel, tid; a_assert(ep); setString(B_L, &ep->result, T("")); rhs = lhs = NULL; rel = 0; tid = 0; do { /* * This loop will handle an entire expression list. We call parse * to evalutate each term which returns the result in ep->result. */ if (tid == TOK_LOGICAL) { if ((state = parse(ep, STATE_RELEXP, flags)) != STATE_RELEXP_DONE) { state = STATE_ERR; break; } } else { if ((state = parse(ep, STATE_EXPR, flags)) != STATE_EXPR_DONE) { state = STATE_ERR; break; } } if (rel > 0) { setString(B_L, &rhs, ep->result); if (tid == TOK_LOGICAL) { if (evalCond(ep, lhs, rel, rhs) < 0) { state = STATE_ERR; break; } } else { if (evalExpr(ep, lhs, rel, rhs) < 0) { state = STATE_ERR; break; } } } setString(B_L, &lhs, ep->result); if ((tid = ejLexGetToken(ep, state)) == TOK_EXPR || tid == TOK_INC_DEC || tid == TOK_LOGICAL) { rel = (int) *ep->token; } else { ejLexPutbackToken(ep, tid, ep->token); state = STATE_RELEXP_DONE; } } while (state == STATE_EXPR_DONE); if (rhs) { bfree(B_L, rhs); } if (lhs) { bfree(B_L, lhs); } return state; }
static int parseStmt(ej_t *ep, int state, int flags) { ejfunc_t func; ejfunc_t *saveFunc; ejinput_t condScript, endScript, bodyScript, incrScript; char *value, *identifier; int done, expectSemi, thenFlags, elseFlags, tid, cond, forFlags; int ejVarType; a_assert(ep); /* * Set these to NULL, else we try to free them if an error occurs. */ endScript.putBackToken = NULL; bodyScript.putBackToken = NULL; incrScript.putBackToken = NULL; condScript.putBackToken = NULL; expectSemi = 0; saveFunc = NULL; for (done = 0; !done; ) { tid = ejLexGetToken(ep, state); switch (tid) { default: ejLexPutbackToken(ep, TOK_EXPR, ep->token); done++; break; case TOK_ERR: state = STATE_ERR; done++; break; case TOK_EOF: state = STATE_EOF; done++; break; case TOK_NEWLINE: break; case TOK_SEMI: /* * This case is when we discover no statement and just a lone ';' */ if (state != STATE_STMT) { ejLexPutbackToken(ep, tid, ep->token); } done++; break; case TOK_ID: /* * This could either be a reference to a variable or an assignment */ identifier = NULL; setString(B_L, &identifier, ep->token); /* * Peek ahead to see if this is an assignment */ tid = ejLexGetToken(ep, state); if (tid == TOK_ASSIGNMENT) { if (parse(ep, STATE_RELEXP, flags) != STATE_RELEXP_DONE) { clearString(&identifier); goto error; } if (flags & FLAGS_EXE) { if ( state == STATE_DEC ) { ejSetLocalVar(ep->eid, identifier, ep->result); } else { ejVarType = ejGetVar(ep->eid, identifier, &value); if (ejVarType > 0) { ejSetLocalVar(ep->eid, identifier, ep->result); } else { ejSetGlobalVar(ep->eid, identifier, ep->result); } } } } else if (tid == TOK_INC_DEC ) { value = NULL; if (flags & FLAGS_EXE) { ejVarType = ejGetVar(ep->eid, identifier, &value); if (ejVarType < 0) { ejError(ep, T("Undefined variable %s\n"), identifier); goto error; } setString(B_L, &ep->result, value); if (evalExpr(ep, value, (int) *ep->token, T("1")) < 0) { state = STATE_ERR; break; } if (ejVarType > 0) { ejSetLocalVar(ep->eid, identifier, ep->result); } else { ejSetGlobalVar(ep->eid, identifier, ep->result); } } } else { /* * If we are processing a declaration, allow undefined vars */ value = NULL; if (state == STATE_DEC) { if (ejGetVar(ep->eid, identifier, &value) > 0) { ejError(ep, T("Variable already declared"), identifier); clearString(&identifier); goto error; } ejSetLocalVar(ep->eid, identifier, NULL); } else { if ( flags & FLAGS_EXE ) { if (ejGetVar(ep->eid, identifier, &value) < 0) { ejError(ep, T("Undefined variable %s\n"), identifier); clearString(&identifier); goto error; } } } setString(B_L, &ep->result, value); ejLexPutbackToken(ep, tid, ep->token); } clearString(&identifier); if (state == STATE_STMT) { expectSemi++; } done++; break; case TOK_LITERAL: /* * Set the result to the literal (number or string constant) */ setString(B_L, &ep->result, ep->token); if (state == STATE_STMT) { expectSemi++; } done++; break; case TOK_FUNCTION: /* * We must save any current ep->func value for the current stack frame */ if (ep->func) { saveFunc = ep->func; } memset(&func, 0, sizeof(ejfunc_t)); setString(B_L, &func.fname, ep->token); ep->func = &func; setString(B_L, &ep->result, T("")); if (ejLexGetToken(ep, state) != TOK_LPAREN) { freeFunc(&func); goto error; } if (parse(ep, STATE_ARG_LIST, flags) != STATE_ARG_LIST_DONE) { freeFunc(&func); ep->func = saveFunc; goto error; } /* * Evaluate the function if required */ if (flags & FLAGS_EXE && evalFunction(ep) < 0) { freeFunc(&func); ep->func = saveFunc; goto error; } freeFunc(&func); ep->func = saveFunc; if (ejLexGetToken(ep, state) != TOK_RPAREN) { goto error; } if (state == STATE_STMT) { expectSemi++; } done++; break; case TOK_IF: if (state != STATE_STMT) { goto error; } if (ejLexGetToken(ep, state) != TOK_LPAREN) { goto error; } /* * Evaluate the entire condition list "(condition)" */ if (parse(ep, STATE_COND, flags) != STATE_COND_DONE) { goto error; } if (ejLexGetToken(ep, state) != TOK_RPAREN) { goto error; } /* * This is the "then" case. We need to always parse both cases and * execute only the relevant case. */ if (*ep->result == '1') { thenFlags = flags; elseFlags = flags & ~FLAGS_EXE; } else { thenFlags = flags & ~FLAGS_EXE; elseFlags = flags; } /* * Process the "then" case. Allow for RETURN statement */ switch (parse(ep, STATE_STMT, thenFlags)) { case STATE_RET: return STATE_RET; case STATE_STMT_DONE: break; default: goto error; } /* * check to see if there is an "else" case */ ejRemoveNewlines(ep, state); tid = ejLexGetToken(ep, state); if (tid != TOK_ELSE) { ejLexPutbackToken(ep, tid, ep->token); done++; break; } /* * Process the "else" case. Allow for return. */ switch (parse(ep, STATE_STMT, elseFlags)) { case STATE_RET: return STATE_RET; case STATE_STMT_DONE: break; default: goto error; } done++; break; case TOK_FOR: /* * Format for the expression is: * * for (initial; condition; incr) { * body; * } */ if (state != STATE_STMT) { goto error; } if (ejLexGetToken(ep, state) != TOK_LPAREN) { goto error; } /* * Evaluate the for loop initialization statement */ if (parse(ep, STATE_EXPR, flags) != STATE_EXPR_DONE) { goto error; } if (ejLexGetToken(ep, state) != TOK_SEMI) { goto error; } /* * The first time through, we save the current input context just * to each step: prior to the conditional, the loop increment and the * loop body. */ ejLexSaveInputState(ep, &condScript); if (parse(ep, STATE_COND, flags) != STATE_COND_DONE) { goto error; } cond = (*ep->result != '0'); if (ejLexGetToken(ep, state) != TOK_SEMI) { goto error; } /* * Don't execute the loop increment statement or the body first time */ forFlags = flags & ~FLAGS_EXE; ejLexSaveInputState(ep, &incrScript); if (parse(ep, STATE_EXPR, forFlags) != STATE_EXPR_DONE) { goto error; } if (ejLexGetToken(ep, state) != TOK_RPAREN) { goto error; } /* * Parse the body and remember the end of the body script */ ejLexSaveInputState(ep, &bodyScript); if (parse(ep, STATE_STMT, forFlags) != STATE_STMT_DONE) { goto error; } ejLexSaveInputState(ep, &endScript); /* * Now actually do the for loop. Note loop has been rotated */ while (cond && (flags & FLAGS_EXE) ) { /* * Evaluate the body */ ejLexRestoreInputState(ep, &bodyScript); switch (parse(ep, STATE_STMT, flags)) { case STATE_RET: return STATE_RET; case STATE_STMT_DONE: break; default: goto error; } /* * Evaluate the increment script */ ejLexRestoreInputState(ep, &incrScript); if (parse(ep, STATE_EXPR, flags) != STATE_EXPR_DONE) { goto error; } /* * Evaluate the condition */ ejLexRestoreInputState(ep, &condScript); if (parse(ep, STATE_COND, flags) != STATE_COND_DONE) { goto error; } cond = (*ep->result != '0'); } ejLexRestoreInputState(ep, &endScript); done++; break; case TOK_VAR: if (parse(ep, STATE_DEC_LIST, flags) != STATE_DEC_LIST_DONE) { goto error; } done++; break; case TOK_COMMA: ejLexPutbackToken(ep, TOK_EXPR, ep->token); done++; break; case TOK_LPAREN: if (state == STATE_EXPR) { if (parse(ep, STATE_RELEXP, flags) != STATE_RELEXP_DONE) { goto error; } if (ejLexGetToken(ep, state) != TOK_RPAREN) { goto error; } return STATE_EXPR_DONE; } done++; break; case TOK_RPAREN: ejLexPutbackToken(ep, tid, ep->token); return STATE_EXPR_DONE; case TOK_LBRACE: /* * This handles any code in braces except "if () {} else {}" */ if (state != STATE_STMT) { goto error; } /* * Parse will return STATE_STMT_BLOCK_DONE when the RBRACE is seen */ do { state = parse(ep, STATE_STMT, flags); } while (state == STATE_STMT_DONE); /* * Allow return statement. */ if (state == STATE_RET) { return state; } if (ejLexGetToken(ep, state) != TOK_RBRACE) { goto error; } return STATE_STMT_DONE; case TOK_RBRACE: if (state == STATE_STMT) { ejLexPutbackToken(ep, tid, ep->token); return STATE_STMT_BLOCK_DONE; } goto error; case TOK_RETURN: if (parse(ep, STATE_RELEXP, flags) != STATE_RELEXP_DONE) { goto error; } if (flags & FLAGS_EXE) { while ( ejLexGetToken(ep, state) != TOK_EOF ); done++; return STATE_RET; } break; } } if (expectSemi) { tid = ejLexGetToken(ep, state); if (tid != TOK_SEMI && tid != TOK_NEWLINE) { goto error; } /* * Skip newline after semi-colon */ ejRemoveNewlines(ep, state); } /* * Free resources and return the correct status */ doneParse: if (tid == TOK_FOR) { ejLexFreeInputState(ep, &condScript); ejLexFreeInputState(ep, &incrScript); ejLexFreeInputState(ep, &endScript); ejLexFreeInputState(ep, &bodyScript); } if (state == STATE_STMT) { return STATE_STMT_DONE; } else if (state == STATE_DEC) { return STATE_DEC_DONE; } else if (state == STATE_EXPR) { return STATE_EXPR_DONE; } else if (state == STATE_EOF) { return state; } else { return STATE_ERR; } /* * Common error exit */ error: state = STATE_ERR; goto doneParse; }
/*--------------------------------------------------------------------------- * value$Assign - Assign the user specified value to the user-specifed * internal symbol. *---------------------------------------------------------------------------*/ BOOL valAssign(unsigned argc, char *argv[]) { struct isym *psym, sym; REG val; if (!(psym = isymVLkp(argv[0]))) { cmdErr("Unrecognized symbol name: %s\n", argv[0]); return NO; } sym = *psym; if (!evalExpr(argv[1], psym->dbase, &val)) return NO; switch (sym.type) { case SINGLE_SYM: if (sym.setFn) { if (!sym.setFn(0, val)) { cmdErr("Attempt to modify symbol failed\n"); return NO; } } else { cmdWarn("Ignored attempt to write a Read-Only symbol\n"); return NO; } break; case REGSET_SYM: if (sym.setFn) { if (!sym.setFn(0, sym.ndx, val)) { cmdErr("Attempt to modify symbol failed\n"); return NO; } } else { cmdWarn("Ignored attempt to write a Read-Only symbol\n"); return NO; } break; case BITF_SYM: if (sym.setFn) { REG oldval = sym.getFn(0), mask; mask = ONES(sym.len) << (sym.start - (sym.len - 1)); val <<= sym.start - (sym.len - 1); val = (oldval & ~mask) | (val & mask); if (!sym.setFn(0, val)) { cmdErr("Attempt to modify symbol failed\n"); return NO; } } else { cmdWarn("Ignored attempt to write a Read-Only symbol\n"); return NO; } break; case RS_BITF_SYM: if (sym.setFn) { REG oldval = sym.getFn(0, sym.ndx), mask; mask = ONES(sym.len) << (sym.start - (sym.len - 1)); val <<= sym.start - (sym.len - 1); val = (oldval & ~mask) | (val & mask); if (!sym.setFn(0, sym.ndx, val)) { cmdErr("Attempt to modify symbol failed\n"); return NO; } } else { cmdWarn("Ignored attempt to write a Read-Only symbol\n"); return NO; } break; default: break; } setDerivedState(1); prgwPCRedraw(); datwUpdate(); regwUpdate(); return YES; }
_Bool evalExpr(expr* ex) { if (!ex) return 0; switch (ex->oper) { case 0: return ex->sym->truth; case NOT: return !(evalExpr(ex->args[0])); case AND: return evalExpr(ex->args[0]) && evalExpr(ex->args[1]); case OR: return evalExpr(ex->args[0]) || evalExpr(ex->args[1]); case XOR: { _Bool a = evalExpr(ex->args[0]), b = evalExpr(ex->args[1]); return (a || b) && !(a && b); } case THEN: return !evalExpr(ex->args[0]) || evalExpr(ex->args[1]); case EQ: return evalExpr(ex->args[0]) == evalExpr(ex->args[1]); case ':': return ex->sym->truth = evalExpr(ex->args[0]); default: return 0; /* And/or do something else? */ } }
RC next(RM_ScanHandle *scan, Record *record) { // Setup mgmt data RM_ScanHandleMgmtData *shMgmtData = scan->mgmtData; RM_TableMgmtData *tableMgmtData = scan->rel->mgmtData; Value *result = (Value *)malloc(sizeof(Value)); // Do we have any tuples in the table to scan? if (tableMgmtData->numTuples == 0) { return RC_RM_NO_MORE_TUPLES; } do { // Have we already started a scan? if (shMgmtData->numScans == 0) { shMgmtData->rid.page = 1; shMgmtData->rid.slot = 0; RC pinPageResult; if (pinPageResult = pinPage(&tableMgmtData->bufferPool, &shMgmtData->pageHandle, shMgmtData->rid.page) != RC_OK) { return pinPageResult; } shMgmtData->page = (RM_Page*)shMgmtData->pageHandle.data; } // Scan until reach last tuple else if (shMgmtData->numScans < tableMgmtData->numTuples) { int pageSize = (int)(PAGE_SIZE - ((&((RM_Page*)0)->data) - ((char*)0))); int totalSlots = pageSize / getRecordSize(scan->rel->schema); shMgmtData->rid.slot++; if (shMgmtData->rid.slot == totalSlots) { shMgmtData->rid.page++; shMgmtData->rid.slot = 0; RC pinPageResult; if (pinPageResult = pinPage(&tableMgmtData->bufferPool, &shMgmtData->pageHandle, shMgmtData->rid.page) != RC_OK) { return pinPageResult; } shMgmtData->page = (RM_Page*)shMgmtData->pageHandle.data; } } // Scan over and nothing found else { return RC_RM_NO_MORE_TUPLES; } char *slotOffset = ((char*)&(shMgmtData->page)->data) + shMgmtData->rid.slot * getRecordSize(scan->rel->schema); int recordSize = getRecordSize(scan->rel->schema) - 1; memcpy(record->data, slotOffset + 1, recordSize); record->id.page = shMgmtData->rid.page; record->id.slot = shMgmtData->rid.slot; shMgmtData->numScans++; if (shMgmtData->cond != NULL) { evalExpr(record, (scan->rel)->schema, shMgmtData->cond, &result); } } while (!result->v.boolV); return RC_OK; }
/* * This fucntion is used along with the startScan function, * call to this method returns the tuples that satisfy the scan condition */ RC next (RM_ScanHandle *scan, Record *record) { Value *result; RID rid; //initialize the page and slot number from the data Structure RM_ScanMgmt rid.page = ((RM_ScanMgmt *)scan->mgmtData)->currentPage; rid.slot = ((RM_ScanMgmt *)scan->mgmtData)->currentSlot; //if the scan condition is passed as NULL, return all the tuples from the table if(((RM_ScanMgmt *)scan->mgmtData)->condn == NULL) { //loop until end of the table while(rid.page > 0 && rid.page < totalPages) { //get the record getRecord (scan->rel, rid, ((RM_ScanMgmt *)scan->mgmtData)->currentRecord); record->data = ((RM_ScanMgmt *)scan->mgmtData)->currentRecord->data; record->id = ((RM_ScanMgmt *)scan->mgmtData)->currentRecord->id; ((RM_ScanMgmt *)scan->mgmtData)->currentPage = ((RM_ScanMgmt *)scan->mgmtData)->currentPage + 1; //assign the new page scan details rid.page = ((RM_ScanMgmt *)scan->mgmtData)->currentPage; rid.slot = ((RM_ScanMgmt *)scan->mgmtData)->currentSlot; return RC_OK; } } else //if specific scan condition is supplied { //loop until end of the entire table, scan for each record while(rid.page > 0 && rid.page < totalPages) { //get record getRecord (scan->rel, rid, ((RM_ScanMgmt *)scan->mgmtData)->currentRecord); //Evaluate the Expression evalExpr (((RM_ScanMgmt *)scan->mgmtData)->currentRecord, scan->rel->schema, ((RM_ScanMgmt *)scan->mgmtData)->condn, &result); //if result is satisfied, i.e. scan returns the attributes needed i.e. Boolean Attrbiute & v.boolV as 1 if(result->dt == DT_BOOL && result->v.boolV) { record->data = ((RM_ScanMgmt *)scan->mgmtData)->currentRecord->data; record->id = ((RM_ScanMgmt *)scan->mgmtData)->currentRecord->id; ((RM_ScanMgmt *)scan->mgmtData)->currentPage = ((RM_ScanMgmt *)scan->mgmtData)->currentPage + 1; return RC_OK; } else //scan the next record, until the record is found { //increment the page to next page ((RM_ScanMgmt *)scan->mgmtData)->currentPage = ((RM_ScanMgmt *)scan->mgmtData)->currentPage + 1; //rid as next page id rid.page = ((RM_ScanMgmt *)scan->mgmtData)->currentPage; rid.slot = ((RM_ScanMgmt *)scan->mgmtData)->currentSlot; } } } //re-init to point to first page ((RM_ScanMgmt *)scan->mgmtData)->currentPage = 1; //if all records scanned return no more tuples found, i.e. scan is completed return RC_RM_NO_MORE_TUPLES; }
void Game::oop_evalVar() { debug(DBG_OPCODES, "Game::oop_evalVar()"); int var = _objectScript.fetchNextWord(); assert(var >= 0 && var < NUM_VARS); evalExpr(&_varsTable[var]); }
int32 Script::evalInt() { evalExpr(0); return getResultInt(); }
const char *Script::evalString() { evalExpr(0); return getResultStr(); }
RC evalExpr (Record *record, Schema *schema, Expr *expr, Value **result) { Value *lIn = NULL; Value *rIn = NULL; MAKE_VALUE(*result, DT_INT, -1); switch(expr->type) { case EXPR_OP: { printf("\n ~~~~ expr->expr.op 1"); Operator *op = expr->expr.op; printf("\n ~~~~ expr->expr.op 2"); bool twoArgs = (op->type != OP_BOOL_NOT); // lIn = (Value *) malloc(sizeof(Value)); // rIn = (Value *) malloc(sizeof(Value)); printf("\n ~~~~ expr->expr.op 3"); CHECK(evalExpr(record, schema, op->args[0], &lIn)); printf("\n ~~~~ expr->expr.op 4"); if (twoArgs) CHECK(evalExpr(record, schema, op->args[1], &rIn)); printf("\n ~~~~ expr->expr.op 5"); switch(op->type) { case OP_BOOL_NOT: CHECK(boolNot(lIn, *result)); printf("\n ~~~~ expr->expr.op 6"); break; case OP_BOOL_AND: CHECK(boolAnd(lIn, rIn, *result)); printf("\n ~~~~ expr->expr.op 7"); break; case OP_BOOL_OR: CHECK(boolOr(lIn, rIn, *result)); printf("\n ~~~~ expr->expr.op 8"); break; case OP_COMP_EQUAL: CHECK(valueEquals(lIn, rIn, *result)); printf("\n ~~~~ expr->expr.op 9"); break; case OP_COMP_SMALLER: CHECK(valueSmaller(lIn, rIn, *result)); printf("\n ~~~~ expr->expr.op 10"); break; default: break; } printf("\n ~~~~ expr->expr.op 11"); // cleanup freeVal(lIn); if (twoArgs) freeVal(rIn); } break; case EXPR_CONST: CPVAL(*result,expr->expr.cons); break; case EXPR_ATTRREF: free(*result); printf("\n ~~~~ expr->expr.op 14"); CHECK(getAttr(record, schema, expr->expr.attrRef, result)); printf("\n ~~~~ expr->expr.op 15"); break; } printf("\n ~~~~ expr->expr.op 12"); return RC_OK; }
/** * This API allows conditional updates of the records * * rel = Table handle * cond = Conditional expression to be matched * op = Function pointer pointing to update function to be called in case a matching record is found */ RC updateScan(RM_TableData *rel, Expr *cond, void (*op)(Schema*, Record *)) { //Sanity Checks if (rel == NULL) { THROW(RC_INVALID_HANDLE, "Table handle is invalid"); } // Get total number of pages this table has int pages = ((RM_TableMgmtData *) rel->mgmtData)->pageCount; RID firstFreeSlot = ((RM_TableMgmtData *) rel->mgmtData)->firstFreeSlot; int i, j, tuplesRead, slot; RID id; Value *result; Record* r; BM_PageHandle *pageData = (BM_PageHandle *) malloc(sizeof(BM_PageHandle)); if (pageData == NULL) { THROW(RC_NOT_ENOUGH_MEMORY, "Not enough memory available for resource allocation"); } j = 0; tuplesRead = 0; // loop through pages and get the desired records for (i = 1; i < pages; i++) { slot = 0; id.page = i; while (slot < ((RM_TableMgmtData *) rel->mgmtData)->slotCapacityPage) { createRecord(&r, rel->schema); id.slot = slot; RC rc = readRecord(rel, id, &r); if (rc != RC_OK) { THROW(RC_REC_MGR_DELETE_REC_FAILED, "Delete record failed"); } // ignore the deleted records (tombstones) and free slots if ((!(r->nullMap & (1 << 15)) || ((firstFreeSlot.page == i) && (firstFreeSlot.slot == slot)))) { // check if record satisfies the given condition evalExpr(r, rel->schema, cond, &result); if (result->v.boolV) { op(rel->schema, r); updateRecord(rel, r); j++; tuplesRead++; } freeVal(result); } freeRecord(r); slot++; } } free(pageData); //All OK return RC_OK; }
/** * Starts scan to fetch records with matching condition * * rel = table handle * scan = scan handle * cond = condition to be matched */ RC startScan(RM_TableData *rel, RM_ScanHandle *scan, Expr *cond) { //Sanity Checks if (rel == NULL) { THROW(RC_INVALID_HANDLE, "Table handle is invalid"); } // Get total number of pages this table has int pages = ((RM_TableMgmtData *) rel->mgmtData)->pageCount; int tupleCount = ((RM_TableMgmtData *) rel->mgmtData)->tupleCount; RID firstFreeSlot = ((RM_TableMgmtData *) rel->mgmtData)->firstFreeSlot; int i, j, tuplesRead, slot; RID id; Value* result; Record** r; BM_PageHandle *pageData = (BM_PageHandle *) malloc(sizeof(BM_PageHandle)); RM_ScanIterator *iter = (RM_ScanIterator*) malloc(sizeof(RM_ScanIterator)); if (pageData == NULL) { THROW(RC_NOT_ENOUGH_MEMORY, "Not enough memory available for resource allocation"); } scan->rel = rel; iter->totalRecords = 0; iter->lastRecordRead = -1; iter->records = (Record**) malloc(sizeof(Record*) * tupleCount); scan->mgmtData = (RM_ScanIterator*) iter; r = iter->records; for (i = 0; i < tupleCount; ++i) { r[i] = NULL; } j = 0; tuplesRead = 0; //Loop through pages and get the desired records for (i = 1; i < pages; i++) { slot = 0; id.page = i; while (slot < ((RM_TableMgmtData *) rel->mgmtData)->slotCapacityPage) { createRecord(&r[j], rel->schema); id.slot = slot; RC rc = readRecord(rel, id, &r[j]); if (rc != RC_OK) { THROW(RC_REC_MGR_DELETE_REC_FAILED, "Delete record failed"); } // ignore the deleted records (tombstones) if (!(r[j]->nullMap & (1 << 15)) && !(firstFreeSlot.page == i && firstFreeSlot.slot == slot)) { evalExpr(r[j], rel->schema, cond, &result); if (result->v.boolV) { j++; tuplesRead++; } freeVal(result); } slot++; freeRecord(r[j]); } } iter->totalRecords = j; free(pageData); //All OK return RC_OK; }
void evaluate(RM_ScanHandle *scan, Record *record, Value **value, expressionSearch *recSearch) { if (true) { evalExpr(record, scan->rel->schema, recSearch->condition, &(*value)); } }
AsmStatus asm_inst(const char *str, InstID *instID, OperandsPtr ops, EncodedInstPtr inst) { char *tok, *isp, *p, instStr[80], buf[BUFSIZ]; unsigned long long val; unsigned op_num = 0, equal = 0, mem, indirect; SymInfoPtr symInfo, indSymInfo; AsmIdPtr asmID; AsmState state = AsmStart; (void)strcpy(buf, str); instStr[0] = '\0'; isp = instStr; for (tok = strtok(buf, " \t"); (tok); tok = strtok(NULL, " \t,")) { /* XXX - add support for labels & tags */ /* XXX - deal with buffer overruns */ if (tok[0] == '/' && tok[1] == '/') /* comment */ break; switch (state) { case AsmStart: case AsmPred: if (tok[0] == '(' && tok[1] == 'p') { /* qp/bp */ ops->qp = (unsigned char)strtoul(&tok[2], &p, 10); if (p == &tok[2]) return AsmBadQP; state = AsmMnem; } else if (tok[0] == ';' && tok[1] == ';') { /* stop */ if (tok[2] == '\0') { inst->stop = SB_Stop; return AsmStop; } else return AsmBadInst; } else if ((p = strchr(tok, ':'))) { /* label/tag */ *p = '\0'; if (tok[0] == '[') /* tag */ tok++; symInsertX(asmST, tok, encoderIP(), &labelInfo); } else { /* assume mnemonic */ ops->qp = 0; (void)strcpy(instStr, tok); isp += strlen(tok); state = AsmOperands; } break; case AsmMnem: (void)strcpy(instStr, tok); isp += strlen(tok); state = AsmOperands; break; case AsmOperands: mem = indirect = 0; if (tok[0] == '=') { if (equal) return AsmBadEquals; else { equal = 1; if (op_num == 0) state = AsmAssign; continue; } } if (op_num == 0) { *isp++ = '_'; *isp = '\0'; } if ((p = strchr(tok, '['))){ /* mem/indirect reg file */ if (p == tok) { /* mem */ mem = 1; tok++; if ((p = strchr(tok, ']'))) *p = '\0'; else return AsmBadOperand + op_num; } else { /* indirect reg file */ /* XXX - finish this */ indirect = 1; *p = '\0'; if (symNameLookupX(asmST, tok, &val, (void *)&indSymInfo)) { (void)strcat(instStr, tok); isp += strlen(tok); tok = p + 1; if ((p = strchr(tok, ']'))) *p = '\0'; else return AsmBadOperand + op_num; } else return AsmBadOperand + op_num; } } /* XXX - add expression evaluation & symbol lookup */ val = strtoull(tok, &p, 0); if (p != tok) { ops->u.op[op_num].bits = val; ops->u.op[op_num].type = EM_OPTYPE_IMM; *isp++ = 'I'; *isp = '\0'; } else if (symNameLookupX(asmST, tok, &ops->u.op[op_num].bits, (void *)&symInfo)) { ops->u.op[op_num].type = symInfo->opType; if (mem) { ops->u.op[op_num].type = EM_OPTYPE_MEM; *isp++ = 'M'; *isp = '\0'; } else if (indirect) { ops->u.op[op_num].type = indSymInfo->opType; } else if (symInfo->symType) { *isp++ = symInfo->symType; *isp = '\0'; } else { (void)strcat(instStr, tok); isp += strlen(tok); } } else if (evalExpr(tok, HEXEXP, &ops->u.op[op_num].bits)) { ops->u.op[op_num].type = EM_OPTYPE_IMM; *isp++ = 'I'; *isp = '\0'; } else return AsmBadOperand + op_num; op_num++; break; case AsmAssign: val = strtoull(tok, &p, 0); if (p != tok) symInsertX(asmST, instStr, val, &immInfo); else if (symNameLookupX(asmST, tok, &val, (void *)&symInfo)) symInsertX(asmST, instStr, val, symInfo); else if (symNameLookup(tok, &val, (void *)&symInfo)) symInsertX(asmST, instStr, val, &labelInfo); else return AsmBadAssign; break; } } /* check for blank/comment/assignment line */ if (state == AsmStart || state == AsmAssign) return AsmNoInst; /* pad out remaining operands */ while (op_num < MAX_OPERANDS) ops->u.op[op_num++].type = EM_OPTYPE_NONE; if (!(asmID = inst_lookup(instStr))) return AsmBadInst; *instID = asmID->id; return (AsmStatus)encode_inst(asmID->id, ops, inst); }