// New string operand (string literal void newStringOperand(char* value) { Operand operand; operand.type = opdtString; if (strcmp(value, "\"\\n\"") == 0) operand.value = -1; else operand.value = generateStringLiteral(value); pushOperandToStack(&operandStack, operand); }
frac* expressionSolver::solveExpression() { std::stack<frac*> postFixExprStack; std::stringstream exprstream(postFixedExpression); std::string currToken; while(exprstream>>currToken) { if(isOperator(currToken)) useOperator(currToken, postFixExprStack); else pushOperandToStack(currToken, postFixExprStack); } frac *result = postFixExprStack.top()->clone(); postFixExprStack.pop(); return result; }
// Push an operand to the stack void newOperand(OperandType type, int value) { Operand operand; operand.type = type; if (type == opdtVariable) { SymbolTableRow* symbol = getSymbol(value, symbolTableStack->integer); operand.value = symbol->address; operand.operandSymbolType = symbol->type; operandSymbolIndex = value; operandSymbolTable = symbolTableStack->integer; operandDimensionAccessCount = 0; } else { operand.value = value; operand.operandSymbolType = -1; } pushOperandToStack(&operandStack, operand); }
void evaluateNextOperation() { Operator operator = popOperatorFromStack(&operatorStack, &operatorFunctionIndex); if (operator != oprOpenParenthesis && operator != oprComma) { // Function call if (operator == oprFunctionCall) { SymbolTableRow* functionSymbol = getSymbol(operatorFunctionIndex, 0); SymbolTableId functionSymbolTable = functionSymbol->symbolTable; int parameterCount = functionSymbol->dimensionSizes->Integer; OperandStack* parameters = NULL; // Reverse parameters order for (int i = 0; i < parameterCount; i++) { pushOperandToStack(¶meters, popOperandFromStack(&operandStack)); } int parameterId = 0; SymbolTableRow* parameterSymbol = getSymbol(parameterId, functionSymbolTable); while (parameterSymbol->category == scParameter) { Operand parameter = popOperandFromStack(¶meters); generatePassingParameter(parameter, parameterSymbol->address, parameterSymbol->totalSize); parameterId++; parameterSymbol = getSymbol(parameterId, functionSymbolTable); } temporaryVariablesCounter++; generateFunctionCall(functionSymbol->address, cumulativeAddress + temporaryVariablesCounter, functionSymbol->totalSize); generateNewTemporaryVariable(); Operand result = { opdtTemporary, functionSymbol->type, cumulativeAddress + temporaryVariablesCounter }; pushOperandToStack(&operandStack, result); } // Scan else if (operator == oprScan) { OperandStack* inputVariables = NULL; while (operandStack != NULL) pushOperandToStack(&inputVariables, popOperandFromStack(&operandStack)); while (inputVariables != NULL) { Operand input = popOperandFromStack(&inputVariables); if (input.operandSymbolType == stString) { generateStringScan(input.value); } else if (input.operandSymbolType == stInt) { generateIntScan(input.value); } else if (input.operandSymbolType == stBoolean) { generateBooleanScan(input.value); } else { // Error: invalid type } } } // Print else if (operator == oprPrint) { OperandStack* outputOperands = NULL; while (operandStack != NULL) pushOperandToStack(&outputOperands, popOperandFromStack(&operandStack)); while (outputOperands != NULL) { Operand output = popOperandFromStack(&outputOperands); if (output.type == opdtString || output.operandSymbolType == stString) generateStringPrint(output); else if (output.type == opdtInteger || output.operandSymbolType == stInt) generateIntPrint(output); else if (output.type == opdtBoolean || output.operandSymbolType == stBoolean) generateBooleanPrint(output); } } // Operations else { Operand leftOperand; Operand rightOperand = popOperandFromStack(&operandStack); // Attribution if (operator == oprEqualSign) { // Pop left operand leftOperand = popOperandFromStack(&operandStack); if (leftOperand.type == opdtVariable) generateAttribution(leftOperand, rightOperand); else { // Error: invalid operation } } else { int resultType = -1; // Binary operators if (operator > oprMinus) { // Pop left operand leftOperand = popOperandFromStack(&operandStack); // If both operands are not temporary variables, create a new temporary variable temporaryVariablesCounter++; if (leftOperand.type != opdtTemporary && rightOperand.type != opdtTemporary) generateNewTemporaryVariable(); else temporaryVariablesCounter --; // Generate code switch (operator) { case oprAdd: case oprSubtract: case oprMultiply: case oprDivide: generateArithmeticOperation(operator, leftOperand, rightOperand, cumulativeAddress + temporaryVariablesCounter); resultType = stInt; break; case oprSmallerThan: case oprSmallerOrEqualThan: case oprBiggerThan: case oprBiggerOrEqualThan: generateRelationalComparison(operator, leftOperand, rightOperand, cumulativeAddress + temporaryVariablesCounter); resultType = stBoolean; break; case oprLogicAnd: case oprLogicOr: generateLogicalOperation(operator, leftOperand, rightOperand, cumulativeAddress + temporaryVariablesCounter); resultType = stBoolean; break; default: // Error: invalid operator break; } } // Unary operators else { // If operand is not a temporary variable, create a new temporary variable. temporaryVariablesCounter++; if (rightOperand.type != opdtTemporary) generateNewTemporaryVariable(); else temporaryVariablesCounter --; // Generate code switch (operator) { default: // Error: invalid operator break; } } // Push result operand to stack Operand result = { opdtTemporary, resultType, cumulativeAddress + temporaryVariablesCounter }; pushOperandToStack(&operandStack, result); } } } }