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 void Translate() { IntermediateCode.ResetCount(); EVariable.ResetCount(); foreach (var stat in stats.GetStatementsList()) { icList.AddRange(TranslateStatement(stat, this)); } icList.Add(new ICAssignment(OperationType.Return, null, null, null)); }
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); }
// 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 TranslateExpression(Expression exp, EVariable place, Program program) { System.Diagnostics.Debug.Assert(!(exp is ETerminal)); ICSequence re = new ICSequence(); if (exp is EBinaryOperation) { EBinaryOperation ebo = (EBinaryOperation)exp; ETerminal place1, place2; ICSequence code1 = null, code2 = null; if (!(ebo.Operand1 is ETerminal)) { place1 = new EVariable(program); code1 = TranslateExpression(ebo.Operand1, (EVariable)place1, program); } else { place1 = (ETerminal)ebo.Operand1; } if (!(ebo.Operand2 is ETerminal)) { place2 = new EVariable(program); code2 = TranslateExpression(ebo.Operand2, (EVariable)place2, program); } else { place2 = (ETerminal)ebo.Operand2; } IntermediateCode lastIC = new ICAssignment(ebo.Operation, place, place1, place2); if (!ReferenceEquals(code1, null)) { re.AddRange(code1); //addDependency(code1[code1.Count - 1], lastIC, DependencyType.Flow); } if (!ReferenceEquals(code2, null)) { re.AddRange(code2); //addDependency(code2[code2.Count - 1], lastIC, DependencyType.Flow); } re.Add(lastIC); } else if (exp is EUnaryOperation) { EUnaryOperation euo = (EUnaryOperation)exp; ETerminal place1; ICSequence code1 = null; if (!(euo.Operand is ETerminal)) { place1 = new EVariable(program); code1 = TranslateExpression(euo.Operand, (EVariable)place1, program); } else { place1 = (ETerminal)euo.Operand; } IntermediateCode lastIC = new ICAssignment(euo.Operation, place, place1, null); if (!ReferenceEquals(code1, null)) { re.AddRange(code1); //addDependency(code1[code1.Count - 1], lastIC, DependencyType.Flow); } re.Add(lastIC); } return(re); }