CELL * p_nth(CELL * params) { CELL * list; CELL * cell; CELL * (*implicitIndexFunc)(CELL *, CELL *); SYMBOL * symbolRef; cell = getEvalDefault(params->next, &list); /* list or string to be indexed */ symbolRef = symbolCheck; params = copyCell(params); /* indices */ pushResult(params); if(isList(list->type)) implicitIndexFunc = implicitIndexList; else if(list->type == CELL_ARRAY) implicitIndexFunc = implicitIndexArray; else if(list->type == CELL_STRING) { list = implicitIndexString(list, params); if((symbolCheck = symbolRef)) { pushResult(list); pushResultFlag = FALSE; } return(list); } else return(errorProcExt(ERR_LIST_EXPECTED, list)); cell = (*implicitIndexFunc)(list, params); symbolCheck = symbolRef; pushResultFlag = FALSE; return(cell); }
exp expression(int *i,int isAssignment){ int tempResult[BUFSIZ]; int tindex = 0,k; int operatorNum = 0; exp expressionResult; expressionResult.expression = (char *)malloc(sizeof(char)*BUFSIZ); expressionResult.result = (char *)malloc(sizeof(char)*20); while(!(wordIndex[*i] >= 28 && wordIndex[*i] <= 37)){ if (wordIndex[*i] == 10 || wordIndex[*i] == 20) { tempResult[tindex++]= (*i); } else { if (opTop != 0) { int x; switch(compareOp(wordIndex[*i])){ case 0: break; case 1: x=opPop();operatorNum++; tempResult[tindex++]= x; if (opTop != 0 && wordIndex[opStack[opTop-1]]<=23) { x=opPop();operatorNum++; tempResult[tindex++]= x; } break; case 3: break; case 4: while(wordIndex[(x=opPop())] != 26){ tempResult[tindex++]= x;operatorNum++; };(*i)++;continue; default:break; } } opPush((*i)); } (*i)++; } while(opTop){ tempResult[tindex++] = opPop();operatorNum++; } if (tindex == 1) { if (isAssignment) { sprintf(expressionResult.expression,"(%d)\t=\t%s\t-\t",finalIndex++,wordResult[tempResult[0]]); } else { sprintf(expressionResult.result,"%s",wordResult[tempResult[0]]); } } else { for (k = 0; k < tindex; ++k) { if (!(22 <= wordIndex[tempResult[k]] && wordIndex[tempResult[k]] <= 25)) { pushResult(wordResult[tempResult[k]]); } else { char *arg2=popResult(); char *arg1=popResult(); char *result=newtemp(); char temp[BUFSIZ]; sprintf(temp,"(%d)\t%s\t%s\t%s\t%s\n",finalIndex++,wordResult[tempResult[k]],arg1,arg2,result); sprintf(expressionResult.expression, "%s%s",expressionResult.expression,temp); pushResult(result); if (k == tindex-1) { if (isAssignment) { sprintf(temp, "(%d)\t=\t%s\t-\t",finalIndex++,wordResult[tempResult[0]]); sprintf(expressionResult.expression,"%s(%d)\t=\t%s\t-\t",expressionResult.expression,finalIndex++,result); } else strcat(expressionResult.result, result); } } } } (*i) ++;// Point at next element after ';' return expressionResult; }
CELL * p_replace(CELL * params) { CELL * keyCell; CELL * repCell; CELL * funcCell = NULL; CELL * list; CELL * cell; CELL * newList; char * keyStr; char * buff; char * newBuff; UINT cnt; size_t newLen; long options; UINT * resultIdxSave; SYMBOL * refSymbol; keyCell = copyCell(evaluateExpression(params)); pushResult(keyCell); params = getEvalDefault(params->next, &cell); newList = cell; refSymbol = symbolCheck; if(symbolCheck && (isProtected(symbolCheck->flags) || isBuiltin(symbolCheck->flags))) return(errorProcExt2(ERR_SYMBOL_PROTECTED, stuffSymbol(symbolCheck))); cnt = 0; resultIdxSave = resultStackIdx; if(isList(cell->type)) { cell->aux = (UINT)nilCell; /* undo last element optimization */ list = (CELL *)cell->contents; if(params != nilCell) { repCell = params; if(params->next != nilCell) funcCell = evaluateExpression(params->next); } else repCell = NULL; COMPARE_START: if(compareFunc(keyCell, list, funcCell) == 0) { if(repCell != NULL) { /* take out usage of sysSymbol0] in 10.2 should only be used for regex replacements then $it doesn't need to be a copy */ deleteList((CELL*)sysSymbol[0]->contents); itSymbol->contents = (UINT)copyCell(list); sysSymbol[0]->contents = itSymbol->contents; cell->contents = (UINT)copyCell(evaluateExpression(repCell)); cell = (CELL*)cell->contents; cell->next = list->next; } else /* remove mode */ cell->contents = (UINT)list->next; list->next = nilCell; deleteList(list); cnt++; if(repCell != NULL) list = cell; else /* remove mode */ { list = (CELL*)cell->contents; if(list != nilCell) goto COMPARE_START; } } while(list->next != nilCell) { if(compareFunc(keyCell, list->next, funcCell) == 0) { cell = list->next; /* cell = old elmnt */ if(repCell != NULL) { /* take out usage of sysSymbol0] in 10.2 should only be used for regex replacements */ deleteList((CELL*)sysSymbol[0]->contents); itSymbol->contents = (UINT)copyCell(cell); sysSymbol[0]->contents = itSymbol->contents; list->next = copyCell(evaluateExpression(repCell)); list = list->next; } list->next = cell->next; cell->next = nilCell; deleteList(cell); cnt++; } else list = list->next; cleanupResults(resultIdxSave); } deleteList((CELL*)sysSymbol[0]->contents); /* sysSymbol[0] should not be used here, introduce $count */ sysSymbol[0]->contents = (UINT)stuffInteger(cnt); itSymbol->contents = (UINT)nilCell; symbolCheck = refSymbol; pushResultFlag = FALSE; return(newList); } if(cell->type == CELL_STRING) { if(keyCell->type != CELL_STRING) return(errorProc(ERR_STRING_EXPECTED)); keyStr = (char *)keyCell->contents; buff = (char *)cell->contents; repCell = params; if(repCell == nilCell) return(errorProc(ERR_MISSING_ARGUMENT)); options = -1; if(repCell->next != nilCell) getInteger(repCell->next, (UINT*)&options); newBuff = replaceString(keyStr, keyCell->aux - 1, buff, (size_t)cell->aux -1, repCell, &cnt, options, &newLen); if(newBuff != NULL) { freeMemory(buff); cell->contents = (UINT)newBuff; cell->aux = newLen + 1; } deleteList((CELL*)sysSymbol[0]->contents); sysSymbol[0]->contents = (UINT)stuffInteger(cnt); symbolCheck = refSymbol; pushResultFlag = FALSE; return(cell); } return(errorProcExt(ERR_LIST_OR_STRING_EXPECTED, cell)); }
CELL * findAllList(CELL * pattern, CELL * list, CELL * exprCell) { CELL * result = nilCell; CELL * cell = NULL; CELL * exprRes; CELL * match; CELL * funcCell; int errNo; UINT * resultIdxSave; funcCell = evaluateExpression(exprCell->next); resultIdxSave = resultStackIdx; if(funcCell == nilCell && !isList(pattern->type)) return(errorProcExt(ERR_LIST_EXPECTED, pattern)); while(list != nilCell) { if(funcCell == nilCell) { /* match only takes lists*/ if(!isList(list->type)) goto CONTINUE_NEXT; match = patternMatchL((CELL *)pattern->contents, (CELL *)list->contents, TRUE); if(match == NULL || match == nilCell) goto CONTINUE_NEXT; deleteList(match); } else { cleanupResults(resultIdxSave); if(compareFunc(pattern, list, funcCell) != 0) goto CONTINUE_NEXT; } /* take out sysSymbol in future, should only be used in regex */ deleteList((CELL*)sysSymbol[0]->contents); sysSymbol[0]->contents = (UINT)copyCell(list); itSymbol->contents = (UINT)list; if(exprCell != nilCell) { if((exprRes = evaluateExpressionSafe(exprCell, &errNo)) == NULL) { pushResult(result); /* push for later deletion */ longjmp(errorJump, errNo); } } else exprRes = list; exprRes = copyCell(exprRes); if(result == nilCell) { cell = exprRes; result = makeCell(CELL_EXPRESSION, (UINT)cell); } else { cell->next = exprRes; cell = cell->next; } CONTINUE_NEXT: list = list->next; } if(result == nilCell) return(getCell(CELL_EXPRESSION)); itSymbol->contents = (UINT)nilCell; return(result); }
CELL * findAllString(char * pattern, char * str, size_t size, CELL * params) { long options = 0; ssize_t findPos = -1; int len; int offset = 0; CELL * result = nilCell; CELL * cell = NULL; CELL * exprCell; CELL * exprRes; UINT * resultIdxSave; int errNo; int lastPos = -1; exprCell = params; if((params = params->next) != nilCell) getInteger(params, (UINT *)&options); resultIdxSave = resultStackIdx; while( (findPos = searchBufferRegex(str, offset, pattern, (int)size, options, &len)) != -1) { if(exprCell != nilCell) { itSymbol->contents = sysSymbol[0]->contents; if((exprRes = evaluateExpressionSafe(exprCell, &errNo)) == NULL) { pushResult(result); /* push for later deletion */ longjmp(errorJump, errNo); } exprRes = copyCell(exprRes); } else exprRes = stuffStringN(str + findPos, len); if(lastPos == findPos) { ++findPos; pushResult(exprRes); goto FINDALL_CONTINUE; } lastPos = findPos; if(result == nilCell) { cell = exprRes; result = makeCell(CELL_EXPRESSION, (UINT)cell); } else { cell->next = exprRes; cell = cell->next; } FINDALL_CONTINUE: offset = (findPos + len); cleanupResults(resultIdxSave); } if(result == nilCell) return(getCell(CELL_EXPRESSION)); itSymbol->contents = (UINT)nilCell; return(result); }
void SchemeMachine::performTask(){ Task * task = tasks.pop(last_line); int n; switch(task->getType()){ case Task::EVALUATE : { EvalTask * evtask; SchObjectRef * ref; int step; evtask = static_cast<EvalTask *>(task); ref = new SchObjectRef(*evtask->ref); last_line = (*ref)->getLine(); step = evtask->step; delete task; (*ref)->evaluate(*this, step); delete ref; } break; case Task::CALL : { // tail recursion optimisation. if CALL and argument haz been evaluated --> del CallTask * ctask; ctask = static_cast<CallTask *>(task); int step = ctask->step; if(!tasks.isEmpty() && tasks.data[tasks.size-1]->getType() == Task::DEL_NAMES && ((*ctask->ref)->getType() != SchObject::SPECIAL || static_cast<SchSpecial *>(&**ctask->ref)->prepareArgs())) { // swap tasks Task * tmp = tasks.data[tasks.size-1]; // DEL_NAMES tasks.push(task); tasks.data[tasks.size-2] = tasks.data[tasks.size-1]; // DEL <- CALL tasks.data[tasks.size-1] = tmp; // CALL <- tmp } else { SchObjectRef * ref; ref = new SchObjectRef(*ctask->ref); last_line = (*ref)->getLine(); n = ctask->n; delete task; (*ref)->call(*this, n, step); delete ref; } } break; case Task::EXECUTE : { ExecTask * extask; int step; bool must_swap = false; extask = static_cast<ExecTask *>(task); if(!tasks.isEmpty() && tasks.data[tasks.size-1]->getType() == Task::DEL_NAMES){ if((*extask->ref)->getType() == SchObject::LIST){ // TODO must_swap = false; } else if((*extask->ref)->getType() != SchObject::SPECIAL){ must_swap = true; } else if(static_cast<SchSpecial *>(&**extask->ref)->prepareArgs()){ must_swap = true; } } if(must_swap) { // swap tasks Task * tmp = tasks.data[tasks.size-1]; // DEL_NAMES tasks.push(task); tasks.data[tasks.size-2] = tasks.data[tasks.size-1]; // DEL <- CALL tasks.data[tasks.size-1] = tmp; // CALL <- tmp } else { SchObjectRef * ref; ref = new SchObjectRef(*extask->ref); last_line = (*ref)->getLine(); step = extask->step; n = extask->n; delete task; (*ref)->execute(*this, n, step); delete ref; } } break; case Task::ALIAS : { AliasTask * altask; altask = static_cast<AliasTask *>(task); global_names.push(altask->id, *(altask->ref)); delete task; } break; case Task::ADD_NAMES : { AddNamesTask * atask; local_names_t * tmp; atask = static_cast<AddNamesTask *>(task); tmp = (typeof(tmp)) malloc (sizeof(*tmp)); tmp->current = atask->map; tmp->prev = local_names; local_names = tmp; delete task; } break; case Task::DEL_NAMES : { delete task; if(local_names == NULL){ throw LocalNamespaceUnderflowError(last_line); } else { local_names_t * tmp = local_names->prev; delete local_names->current; delete local_names; local_names = tmp; } } break; case Task::PRINT : { int N; SchObjectRef ** refs; N = static_cast<PrintTask *>(task)->N; refs = results.pop(N, last_line); for(int i = N-1; i >= 0; --i){ (*refs[i])->print(); } printf("\n"); delete task; } break; case Task::PUSH_RESULT : { SchObjectRef * ref; ref = new SchObjectRef( * static_cast<PushResultTask *>(task)->ref ); delete task; pushResult(*ref); delete ref; } break; case Task::NETWORK : { NetworkTask * ntask = static_cast<NetworkTask *>(task); int quantity = ntask->quantity, price = ntask->price, pid=ntask->player_id; if(ntask->gtype == NetworkTask::PERFORM){ client->perform(ntask->subtype, quantity, price); } else { int res = client->getInfo(ntask->gtype, ntask->subtype, pid, quantity, price); pushResult(SchObjectRef(new SchInteger(last_line, res))); } delete task; break; } default: throw RuntimeError(last_line); break; } }