Example #1
0
        /// <summary>
        ///     Translates a member reference, e.g. a field called "_value".
        /// </summary>
        public override StringBuilder VisitMemberReferenceExpression(MemberReferenceExpression memberRefExpr)
        {
            var result = new StringBuilder();

            if (!(memberRefExpr.Target is ThisReferenceExpression))
            {
                result = memberRefExpr.Target.AcceptVisitor(this);
                if (result != null && result.Length > 0)
                {
                    result.Dot();
                }
            }

            var memberName = memberRefExpr.MemberName;

            if (memberRefExpr.Target is BaseReferenceExpression)
            {
                memberName = memberName.Replace("xsl", "gl_");
            }

            // save member reference
            var memberRef = memberRefExpr.Annotation <IMemberDefinition>();

            if (result != null && memberRef != null)
            {
                var instr = GetInstructionFromStmt(memberRefExpr.GetParent <Statement>());
                RefVariables.Add(new VariableDesc {
                    Definition = memberRef, Instruction = instr
                });
            }

            return(result != null?result.Append(memberName) : new StringBuilder());
        }
Example #2
0
        /// <summary>
        ///     Translates an assignment statement, e.g. "x = a + b".
        /// </summary>
        public override StringBuilder VisitAssignmentExpression(AssignmentExpression assignmentExpr)
        {
            var result = assignmentExpr.Left.AcceptVisitor(this);

            // assignment operator type mapping
            var opAssignment = new Dictionary <AssignmentOperatorType, string>
            {
                { AssignmentOperatorType.Assign, String.Empty },
                { AssignmentOperatorType.Add, "+" },
                { AssignmentOperatorType.BitwiseAnd, "&" },
                { AssignmentOperatorType.BitwiseOr, "|" },
                { AssignmentOperatorType.Divide, "/" },
                { AssignmentOperatorType.ExclusiveOr, "^" },
                { AssignmentOperatorType.Modulus, "%" },
                { AssignmentOperatorType.Multiply, "*" },
                { AssignmentOperatorType.ShiftLeft, "<<" },
                { AssignmentOperatorType.ShiftRight, ">>" },
                { AssignmentOperatorType.Subtract, "-" },
            };

            result.Assign(opAssignment[assignmentExpr.Operator]);
            var rightRes = assignmentExpr.Right.AcceptVisitor(this);

            // add value to RefVariables if this is an "constant initialization"
            if (assignmentExpr.Operator == AssignmentOperatorType.Assign)
            {
                if (assignmentExpr.Left.IsType <MemberReferenceExpression>())
                {
                    var left      = (MemberReferenceExpression)assignmentExpr.Left;
                    var memberRef = left.Annotation <IMemberDefinition>();

                    if (RefVariables.Any(var => var.Definition == memberRef))
                    {
                        var refVar = RefVariables.Last(var => var.Definition == memberRef);

                        if (assignmentExpr.Right.IsType <ObjectCreateExpression>() ||
                            assignmentExpr.Right.IsType <PrimitiveExpression>() ||
                            assignmentExpr.Right.IsType <ArrayCreateExpression>())
                        {
                            RefVariables[RefVariables.IndexOf(refVar)].Value = rightRes;
                        }
                        else
                        {
                            RefVariables[RefVariables.IndexOf(refVar)].Value = "Exception";
                        }
                    }
                }
            }

            return(result.Append(rightRes));
        }
Example #3
0
        public void Validate()
        {
            //Test 1: Depending on Statement type the number of RefVars is fixed
            switch (statementType)
            {
            case Common.StatementType.FullAssignment:
                if (RefVariables.Count < 1 || RefVariables.Count > 3)
                {
                    throw new ValidatorException("Number of referenced variables does not match statement type in instruction " + ID);
                }
                break;

            case Common.StatementType.UnaryAssignment:
            case Common.StatementType.PointerAssignment:
            case Common.StatementType.ConditionalJump:
                if (RefVariables.Count < 1 || RefVariables.Count > 2)
                {
                    throw new ValidatorException("Number of referenced variables does not match statement type in instruction " + ID);
                }
                break;

            case Common.StatementType.Copy:
                if (RefVariables.Count < 1 || RefVariables.Count > 2)
                {
                    throw new ValidatorException("Number of referenced variables does not match statement type in instruction " + ID);
                }
                if (RefVariables.First().pointer != RefVariables.Last().pointer)
                {
                    throw new ValidatorException("You are trying to copy a pointer value to a non-pointer variable (or vice-versa) in COPY instruction " + ID);
                }
                break;

            case Common.StatementType.UnconditionalJump:
            case Common.StatementType.NoOperation:
                if (RefVariables.Count != 0)
                {
                    throw new ValidatorException("Number of referenced variables does not match statement type in instruction " + ID);
                }
                break;

            case Common.StatementType.Procedural:
                if (RefVariables.Count > 1)
                {
                    throw new ValidatorException("Number of referenced variables does not match statement type in instruction " + ID);
                }
                break;

            case Common.StatementType.IndexedAssignment:
                if (RefVariables.Count < 2 || RefVariables.Count > 3)
                {
                    throw new ValidatorException("Number of referenced variables does not match statement type in instruction " + ID);
                }
                break;

            default:
                throw new ValidatorException("Invalid statement type in instruction " + ID);
            }

            // Test 2: TAC text by Regexp
            switch (statementType)
            {
            case Common.StatementType.FullAssignment:
                // var := var op var OR var:= var op number
                if (Regex.IsMatch(TACtext, @"^[vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12} := [vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12} [-+*/%] ([vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12})$", RegexOptions.None)
                    | Regex.IsMatch(TACtext, @"^[vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12} := [vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12} [-+*/%] ([-+]?\d+)$", RegexOptions.None))
                {
                    break;
                }
                else
                {
                    throw new ValidatorException("The instruction Text value does not match its StatementType property. Instruction: " + ID);
                }

            case Common.StatementType.UnaryAssignment:
                // var := op var
                if (Regex.IsMatch(TACtext, @"^[vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12} := [-!] [vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}$", RegexOptions.None))
                {
                    break;
                }
                else
                {
                    throw new ValidatorException("The instruction Text value does not match its StatementType property. Instruction: " + ID);
                }

            case Common.StatementType.Copy:
                // var := var OR var := number
                if (Regex.IsMatch(TACtext, @"^[vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12} := [vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}$", RegexOptions.None) |
                    Regex.IsMatch(TACtext, @"^[vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12} := ([-+]?\d+)$", RegexOptions.None))
                {
                    break;
                }
                else
                {
                    throw new ValidatorException("The instruction Text value does not match its StatementType property. Instruction: " + ID);
                }

            case Common.StatementType.UnconditionalJump:
                // goto ID_GUID
                if (Regex.IsMatch(TACtext, @"^goto ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}$", RegexOptions.None))
                {
                    break;
                }
                else
                {
                    throw new ValidatorException("The instruction Text value does not match its StatementType property. Instruction: " + ID);
                }

            case Common.StatementType.ConditionalJump:
                // if var relop var goto ID_GUID OR if var relop number goto ID_GUID
                if (Regex.IsMatch(TACtext, @"^if [vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12} (?:==|!=|>|<|>=|<=) [vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12} goto ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}$", RegexOptions.None) |
                    Regex.IsMatch(TACtext, @"^if [vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12} (?:==|!=|>|<|>=|<=) ([-+]?\d+) goto ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}$", RegexOptions.None))
                {
                    break;
                }
                else
                {
                    throw new ValidatorException("The instruction Text value does not match its StatementType property. Instruction: " + ID);
                }

            case Common.StatementType.Procedural:
                // param var OR param number
                if (Regex.IsMatch(TACtext, @"^param [vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}$", RegexOptions.None) |
                    Regex.IsMatch(TACtext, @"^param ([-+]?\d+)$", RegexOptions.None) |
                    // call some_string decimal
                    Regex.IsMatch(TACtext, @"^call \w+ \d+$", RegexOptions.None) |
                    // call ID_GUID decimal
                    Regex.IsMatch(TACtext, @"^call ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12} \d+$", RegexOptions.None) |
                    // return
                    Regex.IsMatch(TACtext, @"^return$", RegexOptions.None) |
                    // return number
                    Regex.IsMatch(TACtext, @"^return ([-+]?\d+)$", RegexOptions.None) |
                    // return var
                    Regex.IsMatch(TACtext, @"^return [vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}$", RegexOptions.None) |
                    // retrieve var
                    Regex.IsMatch(TACtext, @"^retrieve [vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}$", RegexOptions.None) |
                    // enter ID_GUID
                    Regex.IsMatch(TACtext, @"^enter ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}$", RegexOptions.None) |
                    // leave ID_GUID
                    Regex.IsMatch(TACtext, @"^leave ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}$", RegexOptions.None)
                    )
                {
                    break;
                }
                else
                {
                    throw new ValidatorException("The instruction Text value does not match its StatementType property. Instruction: " + ID);
                }

            case Common.StatementType.IndexedAssignment:
                // var := var[number] OR var[number] := var OR var[number] = number;
                //if (Regex.IsMatch(TACtext, @"^[vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12} := [vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12} \[\d+\]$", RegexOptions.None) |
                //    Regex.IsMatch(TACtext, @"^[vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12} \[\d+\] := [vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}$", RegexOptions.None) |
                //    Regex.IsMatch(TACtext, @"^[vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12} \[\d+\] := ([-+]?\d+)$", RegexOptions.None))
                //    break;
                //else
                //    throw new ValidatorException("The instruction Text value does not match its StatementType property. Instruction: " + ID);
                throw new ValidatorException("The 'IndexedAssignment' statement type is not supported. Please use 'PointerAssignment' instead. Instruction: " + ID);

            case Common.StatementType.PointerAssignment:
                // var := & var
                if (Regex.IsMatch(TACtext, @"^[vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12} := & [vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}$", RegexOptions.None) |
                    // var := * var
                    Regex.IsMatch(TACtext, @"^[vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12} := \* [vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}$", RegexOptions.None) |
                    // * var := var
                    Regex.IsMatch(TACtext, @"^\* [vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12} := [vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}$", RegexOptions.None) |
                    // * var = number
                    Regex.IsMatch(TACtext, @"^\* [vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12} := ([-+]?\d+)$", RegexOptions.None))
                {
                    break;
                }
                else
                {
                    throw new ValidatorException("The instruction Text value does not match its StatementType property. Instruction: " + ID);
                }

            case Common.StatementType.NoOperation:
                if (Regex.IsMatch(TACtext, @"^nop$", RegexOptions.None))
                {
                    break;
                }
                else
                {
                    throw new ValidatorException("The instruction Text value does not match its StatementType property. Instruction: " + ID);
                }

            default:
                break;
            }

            // Test 3: RETRIEVE instruction must be preceeded by CALL
            int num = parent.Instructions.BinarySearch(this);

            if (Regex.IsMatch(TACtext, @"^retrieve [vtcfp]_ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}$", RegexOptions.None))
            {
                if (num == 0)
                {
                    throw new ValidatorException("The first instruction in a basic block cannot be 'retrieve'. Instruction: " + ID);
                }
                else
                if (!(
                        Regex.IsMatch(parent.Instructions[num - 1].TACtext, @"^call \w+ \d+$", RegexOptions.None) ||
                        Regex.IsMatch(parent.Instructions[num - 1].TACtext, @"^call ID_[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12} \d+$", RegexOptions.None)
                        ))
                {
                    throw new ValidatorException("Instruction 'retrieve' must be directly preceeded by instruction 'call'. Instruction: " + ID);
                }
            }
        }