예제 #1
0
        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);
        }
예제 #2
0
 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));
 }
예제 #3
0
        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);
        }
예제 #4
0
        // 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);
        }
예제 #5
0
        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);
        }