// indices of commands will be incremented automatically public ICAssignment(OperationType op, EVariable result, ETerminal operand1, ETerminal operand2) { this.op = op; this.result = result; this.operand1 = operand1; this.operand2 = operand2; }
public Numeric GetValue(ETerminal terminal) { if (terminal is ENumericLiteral) { // literal can be accessed only once, no need to copy return(((ENumericLiteral)terminal).GetValue()); } else { // for variable, make a copy of the numeric, such that modification of the numeric in operations does not affect the original date return(new Numeric((Numeric)vTable[((EVariable)terminal).name])); } }
public static ICSequence TransformICIfElse(ICIfElse icie, Program program) { ICSequence codesToExe = new ICSequence(); if (icie.codesIf.Count != 0) { ETerminal temp1 = icie.condition; // add (icie.condition & icie.outerCondition) command if (!ReferenceEquals(icie.outerCondition, null)) { temp1 = new EVariable(program, "$ICIE_1_" + icie.index); codesToExe.Add(new ICAssignment(OperationType.AND, (EVariable)temp1, icie.condition, icie.outerCondition, icie.index)); } foreach (var entry in icie.codesIf.GetCodes()) { // if statement is Assignment and result is a temporarily variable, no need to transform if (entry is ICAssignment && ((ICAssignment)entry).result.isTemporary) { codesToExe.Add(entry); continue; } codesToExe.AddRange(TransformIntermediateCode(temp1, entry, program)); } } if (icie.codesElse.Count != 0) { EVariable temp2 = new EVariable(program, "$ICIE_2_" + icie.index); // add (!icie.condition) comamnd codesToExe.Add(new ICAssignment(OperationType.NOT, temp2, icie.condition, null, icie.index)); var temp3 = temp2; // add (!icie.condition) && icie.outerCondition if (!ReferenceEquals(icie.outerCondition, null)) { temp3 = new EVariable(program, "$ICIE_3_" + icie.index); codesToExe.Add(new ICAssignment(OperationType.AND, temp3, temp2, icie.outerCondition, icie.index)); } foreach (var entry in icie.codesElse.GetCodes()) { // if statement is Assignment and result is a temporarily variable, no need to transform if (entry is ICAssignment && ((ICAssignment)entry).result.isTemporary) { codesToExe.Add(entry); continue; } codesToExe.AddRange(TransformIntermediateCode(temp3, entry, program)); } } return(codesToExe); }
public static bool IsEqual(ETerminal term1, ETerminal term2) { //if(term1 is ETemporaryVariable && term2 is ETemporaryVariable) //{ // return Object.ReferenceEquals(term1, term2); //} //else if (term1 is EVariable && term2 is EVariable) { return(((EVariable)term1).name == ((EVariable)term2).name); } else { return(false); } }
// tranform intermediate code at runtime public static ICSequence TransformIntermediateCode(ETerminal condition, IntermediateCode code, Program program) { ICSequence re = new ICSequence(); if (code is ICAssignment) { ICAssignment ica = (ICAssignment)code; if (ReferenceEquals(condition, null)) { re.Add(code); } else { EVariable result = ica.result, temp1 = new EVariable(program, "$ICA_1_" + code.index), temp2 = new EVariable(program, "$ICA_2_" + code.index), temp3 = new EVariable(program, "$ICA_3_" + code.index), temp4 = new EVariable(program, "$ICA_4_" + code.index); ICAssignment // condition * newResult + !condition * oldResult // Command index is the same as the old command // such that EVH and KH can receive the correct message. // Commands generated at runtime cannot be run in parallel. newCode = new ICAssignment(ica.op, temp1, ica.operand1, ica.operand2, code.index), notCondition = new ICAssignment(OperationType.NOT, temp2, condition, null, code.index), term1Exp = new ICAssignment(OperationType.Multiplication, temp3, condition, temp1, code.index), term2Exp = new ICAssignment(OperationType.Multiplication, temp4, temp2, result, code.index), term3Exp = new ICAssignment(OperationType.Addition, result, temp3, temp4, code.index); re.AddRange(new ICAssignment[] { newCode, notCondition, term1Exp, term2Exp, term3Exp }); } } else if (code is ICIfElse) { // for if-else statement, simply set the outerCondition ICIfElse icie = (ICIfElse)code; icie.outerCondition = condition; re.Add(icie); } else if (code is ICWhile) { ICWhile icw = (ICWhile)code; // outerCondition && while condition. This command will be executed very time condition codes are evaluated if (!ReferenceEquals(condition, null)) { EVariable temp1 = new EVariable(program, "&ICW_1_" + code.index); icw.conditionCodes.Add(new ICAssignment(OperationType.AND, temp1, icw.condition, condition, icw.conditionCodes[icw.conditionCodes.Count - 1].index)); icw.condition = temp1; } ICSequence icwCodes = new ICSequence(); foreach (var entry in icw.codes.GetCodes()) { // if statement is Assignment and result is a temporarily variable, no need to transform if (entry is ICAssignment && ((ICAssignment)entry).result.isTemporary) { icwCodes.Add(entry); continue; } icwCodes.AddRange(TransformIntermediateCode(icw.condition, entry, program)); } icw.codes = icwCodes; re.Add(icw); } return(re); }
public static ICSequence TranslateStatement(Statement stat, Program program) { ICSequence re = new ICSequence(); if (stat is SSequence) { SSequence ss = (SSequence)stat; foreach (var entry in ss.GetStatementsList()) { re.AddRange(TranslateStatement(/*condition, */ entry, program)); } } else if (stat is SAssignment) { SAssignment sa = (SAssignment)stat; System.Diagnostics.Debug.Assert(sa.result is EVariable); EVariable result = (EVariable)sa.result; //if(condition != null) //{ // Expression // notExp = new EBinaryOperation(new ENumericLiteral("1", 0), condition, OperationType.Substraction), // term1Exp = new EBinaryOperation(condition, sa.value, OperationType.Multiplication), // term2Exp = new EBinaryOperation(notExp, result, OperationType.Multiplication), // newExp = new EBinaryOperation(term1Exp, term2Exp, OperationType.Addition); // re.AddRange(TranslateExpression(newExp, result)); //} //else //{ if (sa.value is ETerminal) { re.Add(new ICAssignment(OperationType.None, result, (ETerminal)sa.value, null)); } else { re.AddRange(TranslateExpression(sa.value, result, program)); } //} } else if (stat is SIfElse) { SIfElse sie = (SIfElse)stat; ETerminal cond = null; ICIfElse icie = new ICIfElse(); icie.prob = sie.prob; icie.revealCond = sie.revealCond; if (sie.condition is ETerminal) { cond = (ETerminal)sie.condition; } else { cond = new EVariable(program); icie.conditionCodes.AddRange(TranslateExpression(sie.condition, (EVariable)cond, program)); } icie.condition = cond; if (!ReferenceEquals(sie.statIf, null)) { icie.codesIf.AddRange(TranslateStatement(sie.statIf, program)); } if (!ReferenceEquals(sie.statElse, null)) { icie.codesElse.AddRange(TranslateStatement(sie.statElse, program)); } re.Add(icie); } else if (stat is SReturn) { SReturn sr = (SReturn)stat; foreach (var exp in sr.exps) { if (exp is EVariable) { program.vReturn.Add(((EVariable)exp).name); } else { var place = new EVariable(program); re.AddRange(TranslateExpression(exp, place, program)); program.vReturn.Add(place.name); } } } else if (stat is SWhile) { SWhile sw = (SWhile)stat; ICWhile icw = new ICWhile(); ETerminal cond = null; if (sw.condition is ETerminal) { cond = (ETerminal)sw.condition; } else { cond = new EVariable(program); icw.conditionCodes.AddRange(TranslateExpression(sw.condition, (EVariable)cond, program)); } icw.condition = cond; icw.codes.AddRange(TranslateStatement(/*cond, */ sw.stat, program)); re.Add(icw); } return(re); }