private NovelExpression UnfoldArguments(NovelExpression expression, ref List <NovelInstruction> instructions) { //Get the term var term = expression.Term; for (int i = 0; i < term.Count; i++) { int functionEndIndex = -1; int functionElements = 2; //Look for function start operator if (term[i] is NovelFunctionStartOperator && term[i - 1] is NovelExpressionFunctionCall) { //Check if inside function are only comma characters bool onlyCommas = true; for (int j = i + 1; j < term.Count; j++) { var test = term[j]; functionElements++; //Read until novel function end if (term[j] is NovelFunctionEndOperator) { functionEndIndex = j; break; } //If its an operator if (term[j] is NovelExpressionOperator) { //If its different than comma if (!(term[j] is NovelCommaOperator)) { onlyCommas = false; break; } } } if (onlyCommas) { //Fill function with arguments var function = term[i - 1] as NovelExpressionFunctionCall; for (int j = i; j < functionEndIndex; j++) { if (term[j] is NovelExpressionOperand) { function.Arguments.Add(term[j] as NovelExpressionOperand); } } //TODO //here i have number of arguments in function //so i can check if its the right number int newIndex = ParsedScript.DelegateFunctionList. ContainsFunction(function.Name, function.Arguments.Count); //If found new delegated function if (newIndex > -1) { function.Offset = newIndex; } else { throw new NovelException("Could not find delegated method " + function.Name + " with " + function.Arguments.Count() + " arguments.", "", 0); } //Now create new expression var lastStackOperator = Variables.GetStackVariables(); var temporaryVariable = new NovelExpressionVariable("temp_" + lastStackOperator, lastStackOperator); Variables.AddVaraible(temporaryVariable.Name); //instructions.Add(new NovelExpandStack(1)); var newExpression = new NovelExpression(); //newExpression.Term.Add(temporaryVariable); newExpression.Term.Add(function); //newExpression.Term.Add(new NovelAssignOperator()); instructions.Add(newExpression); //Remove from expression for (int j = 0; j < functionElements; j++) { expression.Term.RemoveAt(i - 1); } if (expression.Term.Count > 0) { expression.Term.Insert(i - 1, temporaryVariable); } i -= 1; } } } return(expression); }
private NovelExpression UnfoldOperations(NovelExpression expression, ref List <NovelInstruction> instructions) { //Get the term var term = expression.Term; //Look for for (int i = 0; i < term.Count; i++) { var part = term[i]; //Look for operator different //comma //fnc start //fnc end //fnc call if (part is NovelExpressionOperator) { if (!(part is NovelExpressionFunctionCall) && !(part is NovelCommaOperator) && !(part is NovelFunctionStartOperator) && !(part is NovelFunctionEndOperator)) { //If its one argument operator if (part is NovelNegationOperator && term[i - 1] is NovelExpressionOperand) { var operand = term[i - 1] as NovelExpressionOperand; var lastStackOperator = Variables.GetStackVariables(); var temporaryVariable = new NovelExpressionVariable("temp_" + lastStackOperator, lastStackOperator); Variables.AddVaraible(temporaryVariable.Name); instructions.Add(new NovelExpandStack(1)); var newExpression = new NovelExpression(); newExpression.Term.Add(temporaryVariable); newExpression.Term.Add(operand); newExpression.Term.Add(part); newExpression.Term.Add(new NovelAssignOperator()); instructions.Add(newExpression); //Replace last operation with temporary variable expression.Term.RemoveAt(i - 1); expression.Term.RemoveAt(i - 1); //Don't put temporary variable to expression if its empty if (expression.Term.Count > 0) { expression.Term.Insert(i - 1, temporaryVariable); } i -= 1; } //Get the two operands if its not negation else { //If its the end of expression if (part is NovelAssignOperator && expression.Term.Count == 3 && term[i - 1] is NovelExpressionOperand && term[i - 2] is NovelExpressionOperand) { var newExpression = new NovelExpression(); newExpression.Term.Add(term[i - 2]); newExpression.Term.Add(term[i - 1]); newExpression.Term.Add(part); instructions.Add(newExpression); expression.Term.Clear(); } //If both previous parts in term are operands else if ( term[i - 1] is NovelExpressionOperand && term[i - 2] is NovelExpressionOperand) { var operandLeft = term[i - 2] as NovelExpressionOperand; var operandRight = term[i - 1] as NovelExpressionOperand; var lastStackOperator = Variables.GetStackVariables(); var temporaryVariable = new NovelExpressionVariable("temp_" + lastStackOperator, lastStackOperator); Variables.AddVaraible(temporaryVariable.Name); instructions.Add(new NovelExpandStack(1)); //Create new operation of two operands //and assign the result to temporary variable var newExpression = new NovelExpression(); newExpression.Term.Add(temporaryVariable); newExpression.Term.Add(operandLeft); newExpression.Term.Add(operandRight); newExpression.Term.Add(part); newExpression.Term.Add(new NovelAssignOperator()); instructions.Add(newExpression); //Replace last operation with temporary variable expression.Term.RemoveAt(i - 2); expression.Term.RemoveAt(i - 2); expression.Term.RemoveAt(i - 2); if (expression.Term.Count > 0) { expression.Term.Insert(i - 2, temporaryVariable); } i -= 2; } } } } } return(expression); }