コード例 #1
0
        // Replace clear loop [-] with single instruction
        public List <InstructionBase> OptimizeClearLoop(List <InstructionBase> instructions)
        {
            List <InstructionBase> optimized = new List <InstructionBase>();

            for (int i = 0; i < instructions.Count; i++)
            {
                InstructionBase instruction       = instructions[i];
                bool            optimizationFound = false;
                if (instruction is OpenInstruction && i < instructions.Count - 2)
                {
                    SubInstruction sub = instructions[i + 1] as SubInstruction;
                    if (sub?.X == 1 && sub.Offset == 0 && instructions[i + 2] is CloseInstruction)
                    {
                        Debug.WriteLine("Clear loop found");
                        optimizationFound = true;
                        optimized.Add(new ClearInstruction());
                        i += 2;
                    }
                }
                if (!optimizationFound)
                {
                    optimized.Add(instruction);
                }
            }

            return(optimized);
        }
コード例 #2
0
 public SubInstruction GetSubInstruction()
 {
     if (this.SourceSubInstruction == null)
     {
         this.SourceSubInstruction = this.SourceInstruction.GetSubInstruction(this);
     }
     return(this.SourceSubInstruction);
 }
コード例 #3
0
        public override KeyValuePair <string, Expression>?GetExpression <TSource>(Type sourceType, ParameterExpression rootParameter, IEnumerable <TSource> source)
        {
            // 1. Parse the instruction.
            var fieldNames   = Parameter.Split(',');
            var instructions = fieldNames.Select(s =>
            {
                return(InstructionHelper.ExtractInstruction(s));
            }).Where(s => s.HasValue);

            if (instructions.Count() == 0)
            {
                throw new ArgumentException("the parameter cannot be empty");
            }

            if (instructions.Any(i => !_orderByInstructions.Contains(i.Value.Key)))
            {
                throw new ArgumentException("At least one instruction is not supported");
            }

            var onInstruction    = instructions.FirstOrDefault(i => i.Value.Key == _onInstruction);
            var orderInstruction = instructions.FirstOrDefault(i => i.Value.Key == _orderInstruction);

            if (onInstruction == null)
            {
                throw new ArgumentException("The 'on' instruction must be specified");
            }

            var fnName = "OrderBy";

            if (orderInstruction != null && orderInstruction.Value.Value == "desc")
            {
                fnName = "OrderByDescending";
            }

            // 2. Construct the selector.
            ParameterExpression arg      = Expression.Parameter(sourceType, "x");
            MemberExpression    property = Expression.Property(arg, onInstruction.Value.Value);
            var selector = Expression.Lambda(property, new ParameterExpression[] { arg });

            // 3. Call the order function and return the result.
            var enumarableType = typeof(Queryable);
            var method         = enumarableType.GetMethods()
                                 .Where(m => m.Name == fnName && m.IsGenericMethodDefinition)
                                 .Where(m =>
            {
                var parameters = m.GetParameters().ToList();
                return(parameters.Count == 2);
            }).Single().MakeGenericMethod(sourceType, property.Type);

            if (SubInstruction != null)
            {
                var subExpr = SubInstruction.GetExpression(sourceType, rootParameter, source);
                var call    = Expression.Call(method, subExpr.Value.Value, selector);
                return(new KeyValuePair <string, Expression>(Name, call));
            }

            return(new KeyValuePair <string, Expression>(Name, Expression.Call(method, rootParameter, selector)));
        }
コード例 #4
0
 public void EmitSub(Type type, bool @checked)
 {
     if (@checked)
     {
         Emit(SubOvfInstruction.Create(type));
     }
     else
     {
         Emit(SubInstruction.Create(type));
     }
 }
コード例 #5
0
        public void Execute_Underflow()
        {
            reg[17] = 0x0;
            reg[18] = 0x1;
            target  = new SubInstruction(16, 17, 18);

            target.Execute(ref pc, mem, reg);

            Assert.AreEqual(0xFFFFFFFF, reg[16]);
            Assert.AreEqual(0x4, pc);
        }
コード例 #6
0
        public void Execute_NegativeNumber()
        {
            reg[17] = 0x3;
            reg[18] = 0xFFFFFFFF;
            target  = new SubInstruction(16, 17, 18);

            target.Execute(ref pc, mem, reg);

            Assert.AreEqual(0x4, reg[16]);
            Assert.AreEqual(0x4, pc);
        }
コード例 #7
0
            public ParsedInstruction(uint Opcode)
            {
                this.Opcode = Opcode;
                this.INSTR  = (byte  )((Opcode >> 26) & 0x03F);  // (bits 31:26)
                this.ZCRI   = (byte  )((Opcode >> 22) & 0x00F);  // (bits 25:22)
                this.CON    = (byte  )((Opcode >> 18) & 0x00F);  // (bits 21:18)
                this.DEST   = (ushort)((Opcode >> 9) & 0x1FF);   // (bits 17:09)
                this.SRC    = (ushort)(Opcode & 0x1FF);          // (bits 08:00)

                this.SourceInstruction    = Instructions[this.INSTR];
                this.SourceSubInstruction = null;
            }
コード例 #8
0
        private Operand MakeVariableAssignment(VariableAssignmentNode node, ILGenerator generator)
        {
            SymbolOperand leftHandSide  = node.Accessor.Visit(generator) as SymbolOperand;
            Operand       rightHandSide = node.Right.Visit(generator);

            // If right-hand side exists and has a type, do some type checking

            /*if (rightHandSide.Type != leftHandSide.Type)
             *  throw new AstWalkerException($"Cannot convert {rightHandSide.Type} to {leftHandSide.Type} ('{leftHandSide.Name}')");*/

            if (node.Operator.Type == TokenType.Assignment)
            {
                generator.Emmit(new StoreInstruction(leftHandSide, rightHandSide));
                return(leftHandSide);
            }


            Instruction instr = null;

            switch (node.Operator.Type)
            {
            case TokenType.IncrementAndAssign:
                instr = new AddInstruction(leftHandSide, leftHandSide, rightHandSide);
                break;

            case TokenType.DecrementAndAssign:
                instr = new SubInstruction(leftHandSide, leftHandSide, rightHandSide);
                break;

            case TokenType.MultAndAssign:
                instr = new MultInstruction(leftHandSide, leftHandSide, rightHandSide);
                break;

            case TokenType.DivideAndAssign:
                instr = new DivInstruction(leftHandSide, leftHandSide, rightHandSide);
                break;

            default:
                throw new InvalidInstructionException($"Unsupported operation: {node.Operator.Value} ({node.Operator.Type})");
            }

            generator.Emmit(instr);

            return(leftHandSide);
        }
コード例 #9
0
        public override KeyValuePair <string, Expression>?GetExpression <TSource>(Type sourceType, ParameterExpression rootParameter, IEnumerable <TSource> source)
        {
            const string condExpression = "(\\w|-|_|@)* (eq|neq|co|sw|ew|lt|le|gt|ge) ('|\")((\\w|-|_|@)| |\\d|:|\\/)*('|\")";
            const string expression     = "((\\w|-|_|@)* (eq|neq|co|sw|ew|lt|le|gt|ge) (('|\")((\\w|-|_|@)| |\\d|:|\\/)*('|\")( and | or ){0,1}))+";
            var          match          = Regex.Match(Parameter, expression);

            if (string.IsNullOrWhiteSpace(match.Value) || match.Value != Parameter)
            {
                throw new InvalidOperationException($"the parameter {Parameter} is not correct");
            }

            Type       sourceQueryableType = null;
            Expression subExpression       = null;

            if (SubInstruction != null)
            {
                var subExpr = SubInstruction.GetExpression(sourceType, rootParameter, source);
                subExpression = subExpr.Value.Value;
                sourceType    = subExpression.Type.GetGenericArguments().First();
            }

            var conds      = Regex.Matches(Parameter, condExpression);
            var ops        = Regex.Split(Regex.Replace(Parameter, condExpression, ""), " *(and|or) *").Where(s => !string.IsNullOrWhiteSpace(s));
            var conditions = new List <string>();
            int ind        = 0;

            foreach (Match cond in conds)
            {
                conditions.Add(cond.Value);
                if (ops.Count() - 1 < ind)
                {
                    continue;
                }

                conditions.Add(ops.ElementAt(ind));
                ind++;
            }

            var        arg        = Expression.Parameter(sourceType, "x");
            Expression binaryExpr = null;

            if (conditions.Count() != 1)
            {
                Expression     rightOperand = null;
                ExpressionType type         = ExpressionType.AndAlso;
                for (var i = conditions.Count() - 1; i >= 0; i--)
                {
                    var str = conditions.ElementAt(i);
                    if ((i + 1) % 2 == 0)
                    {
                        if (str == "or")
                        {
                            type = ExpressionType.Or;
                        }
                        else
                        {
                            type = ExpressionType.AndAlso;
                        }
                    }
                    else
                    {
                        var expr = BuildCondition(str, arg);
                        if (rightOperand == null)
                        {
                            rightOperand = expr;
                        }
                        else
                        {
                            rightOperand = Expression.MakeBinary(type, expr, rightOperand);
                        }
                    }
                }

                binaryExpr = rightOperand;
            }
            else
            {
                binaryExpr = BuildCondition(conditions.First(), arg);
            }

            sourceQueryableType = typeof(IQueryable <>).MakeGenericType(sourceType);
            var selector       = Expression.Lambda(binaryExpr, new ParameterExpression[] { arg });
            var enumarableType = typeof(Queryable);
            var genericMethod  = enumarableType.GetMethods()
                                 .Where(m => m.Name == "Where" && m.IsGenericMethodDefinition)
                                 .Where(m => m.GetParameters().Count() == 2).First().MakeGenericMethod(sourceType);

            if (subExpression != null)
            {
                var call = Expression.Call(genericMethod, subExpression, selector);
                return(new KeyValuePair <string, Expression>(Name, call));
            }

            return(new KeyValuePair <string, Expression>(Name, Expression.Call(genericMethod, rootParameter, selector)));
        }
コード例 #10
0
 public void EmitSub(Type type, bool @checked)
 {
     Emit(@checked ? SubOvfInstruction.Create(type) : SubInstruction.Create(type));
 }
コード例 #11
0
        public void ToString_Formatted()
        {
            target = new SubInstruction(16, 17, 18);

            Assert.AreEqual("SUB $s0, $s1, $s2", target.ToString());
        }
コード例 #12
0
        public Operand Visit(ILGenerator generator, BinaryNode binary)
        {
            Operand left  = binary.Left.Visit(generator);
            Operand right = binary.Right.Visit(generator);

            SymbolOperand tmpname = generator.SymbolTable.NewTempSymbol(OperandType.Auto);

            Instruction instr = null;

            switch (binary.Operator.Type)
            {
            case TokenType.Addition:
                instr = new AddInstruction(tmpname, left, right);
                break;

            case TokenType.Minus:
                instr = new SubInstruction(tmpname, left, right);
                break;

            case TokenType.Multiplication:
                instr = new MultInstruction(tmpname, left, right);
                break;

            case TokenType.Division:
                instr = new DivInstruction(tmpname, left, right);
                break;


            case TokenType.Or:
                instr = new OrInstruction(tmpname, left, right);
                break;

            case TokenType.And:
                instr = new AndInstruction(tmpname, left, right);
                break;


            case TokenType.GreatThan:
                instr = new CgtInstruction(tmpname, left, right);
                break;

            case TokenType.GreatThanEqual:
                instr = new CgteInstruction(tmpname, left, right);
                break;

            case TokenType.LessThan:
                instr = new CltInstruction(tmpname, left, right);
                break;

            case TokenType.LessThanEqual:
                instr = new ClteInstruction(tmpname, left, right);
                break;


            case TokenType.Equal:
            case TokenType.NotEqual:     // Use NOT instruction
                instr = new CeqInstruction(tmpname, left, right);
                break;
            }

            generator.Emmit(new VarInstruction(tmpname, null));
            generator.Emmit(instr);

            if (binary.Operator.Type == TokenType.NotEqual)
            {
                SymbolOperand notname = generator.SymbolTable.NewTempSymbol(OperandType.Auto);
                generator.Emmit(new VarInstruction(notname, null));
                generator.Emmit(new NotInstruction(notname, tmpname));
                return(notname);
            }

            return(tmpname);
        }
コード例 #13
0
        public override KeyValuePair <string, Expression>?GetExpression <TSource>(Type sourceType, ParameterExpression rootParameter, IEnumerable <TSource> source)
        {
            IEnumerable <string> fieldNames = null;

            if (!string.IsNullOrWhiteSpace(Parameter) && Parameter != _starSelector)
            {
                fieldNames = Parameter.GetParameters();
            }
            else
            {
                fieldNames = sourceType.GetProperties().Select(m => m.Name).ToArray();
            }

            // 1. Get sub expression.
            Expression subExpr    = null;
            Type       targetType = sourceType;

            if (SubInstruction != null)
            {
                var kvp = SubInstruction.GetExpression(sourceType, rootParameter, source).Value;
                subExpr    = kvp.Value;
                targetType = subExpr.Type.GetGenericArguments().First();
                if (string.IsNullOrWhiteSpace(Parameter))
                {
                    return(kvp);
                }
            }

            // x
            var arg = Expression.Parameter(targetType, "x");
            // f
            var finalSelectArg        = Expression.Parameter(typeof(IQueryable <>).MakeGenericType(targetType), "f");
            LambdaExpression selector = null;
            Type             type     = null;

            if (fieldNames.Count() == 1)
            {
                var field = fieldNames.First();
                MemberExpression property = Expression.Property(arg, field);
                selector = Expression.Lambda(property, new ParameterExpression[] { arg });
                type     = property.Type;
            }
            else
            {
                var sourceProperties = fieldNames.ToDictionary(name => name, name => sourceType.GetProperty(name));
                var anonType         = ReflectionHelper.CreateNewAnonymousType(sourceType, fieldNames);
                var exprNew          = ExpressionBuilder.BuildNew(fieldNames, sourceType, anonType, arg);
                selector = Expression.Lambda(exprNew, new ParameterExpression[] { arg });
                type     = anonType.AsType();
            }

            var enumarableType = typeof(Queryable);
            var selectMethod   = enumarableType.GetMethods()
                                 .Where(m => m.Name == "Select" && m.IsGenericMethodDefinition)
                                 .Where(m =>
            {
                var parameters = m.GetParameters().ToList();
                return(parameters.Count == 2);
            }).First().MakeGenericMethod(targetType, type);

            if (SubInstruction != null)
            {
                return(new KeyValuePair <string, Expression>(Name, Expression.Call(typeof(Queryable), "Select", new Type[] { targetType, type }, subExpr, selector)));
            }

            return(new KeyValuePair <string, Expression>(Name, Expression.Call(typeof(Queryable), "Select", new Type[] { targetType, type }, Expression.Constant(source), selector)));
        }
コード例 #14
0
ファイル: Parser.cs プロジェクト: yoanndw/ArdaansASM
        private bool GenerateNode(out OneOperandNode node)
        {
            node = null;

            InstructionToken instructionToken;

            if (this.ExpectInstructionToken(out instructionToken))
            {
                Instructions instruction = instructionToken.Instruction;
                switch (instruction)
                {
                case Instructions.Mov:
                {
                    Token operand1;
                    Token operand2;
                    if (this.ExpectTwoOperands(out operand1, out operand2))
                    {
                        node = new MovInstruction(this.rawInput, instructionToken, operand1, operand2);
                    }
                    else
                    {
                        this.LogExpectedTwoOperandsError(instructionToken);
                        return(false);
                    }
                }
                break;

                case Instructions.Add:
                {
                    Token operand1;
                    Token operand2;
                    if (this.ExpectTwoOperands(out operand1, out operand2))
                    {
                        node = new AddInstruction(this.rawInput, instructionToken, operand1, operand2);
                    }
                    else
                    {
                        this.LogExpectedTwoOperandsError(instructionToken);
                        return(false);
                    }
                }
                break;

                case Instructions.Sub:
                {
                    Token operand1;
                    Token operand2;
                    if (this.ExpectTwoOperands(out operand1, out operand2))
                    {
                        node = new SubInstruction(this.rawInput, instructionToken, operand1, operand2);
                    }
                    else
                    {
                        this.LogExpectedTwoOperandsError(instructionToken);
                        return(false);
                    }
                }
                break;

                case Instructions.Mul:
                {
                    Token operand1;
                    Token operand2;
                    if (this.ExpectTwoOperands(out operand1, out operand2))
                    {
                        node = new MulInstruction(this.rawInput, instructionToken, operand1, operand2);
                    }
                    else
                    {
                        this.LogExpectedTwoOperandsError(instructionToken);
                        return(false);
                    }
                }
                break;

                case Instructions.Div:
                {
                    Token operand1;
                    Token operand2;
                    if (this.ExpectTwoOperands(out operand1, out operand2))
                    {
                        node = new DivInstruction(this.rawInput, instructionToken, operand1, operand2);
                    }
                    else
                    {
                        this.LogExpectedTwoOperandsError(instructionToken);
                        return(false);
                    }
                }
                break;

                case Instructions.Cmp:
                {
                    Token operand1;
                    Token operand2;
                    if (this.ExpectTwoOperands(out operand1, out operand2))
                    {
                        node = new CmpInstruction(this.rawInput, instructionToken, operand1, operand2);
                    }
                    else
                    {
                        this.LogExpectedTwoOperandsError(instructionToken);
                        return(false);
                    }
                }
                break;

                case Instructions.Inc:
                {
                    Token operand;
                    if (this.ExpectOneOperand(out operand))
                    {
                        node = new IncInstruction(this.rawInput, instructionToken, operand);
                    }
                    else
                    {
                        this.LogExpectedOneOperandError(instructionToken);
                        return(false);
                    }
                }
                break;

                case Instructions.Dec:
                {
                    Token operand;
                    if (this.ExpectOneOperand(out operand))
                    {
                        node = new DecInstruction(this.rawInput, instructionToken, operand);
                    }
                    else
                    {
                        this.LogExpectedOneOperandError(instructionToken);
                        return(false);
                    }
                }
                break;

                case Instructions.Jmp:
                {
                    Token operand;
                    if (this.ExpectOneOperand(out operand))
                    {
                        node = new JmpInstruction(this.rawInput, instructionToken, operand);
                    }
                    else
                    {
                        this.LogExpectedOneOperandError(instructionToken);
                        return(false);
                    }
                }
                break;

                case Instructions.Jeq:
                {
                    Token operand;
                    if (this.ExpectOneOperand(out operand))
                    {
                        node = new JeqInstruction(this.rawInput, instructionToken, operand);
                    }
                    else
                    {
                        this.LogExpectedOneOperandError(instructionToken);
                        return(false);
                    }
                }
                break;

                case Instructions.Jne:
                {
                    Token operand;
                    if (this.ExpectOneOperand(out operand))
                    {
                        node = new JneInstruction(this.rawInput, instructionToken, operand);
                    }
                    else
                    {
                        this.LogExpectedOneOperandError(instructionToken);
                        return(false);
                    }
                }
                break;

                case Instructions.Jsm:
                {
                    Token operand;
                    if (this.ExpectOneOperand(out operand))
                    {
                        node = new JsmInstruction(this.rawInput, instructionToken, operand);
                    }
                    else
                    {
                        this.LogExpectedOneOperandError(instructionToken);
                        return(false);
                    }
                }
                break;

                case Instructions.Jns:
                {
                    Token operand;
                    if (this.ExpectOneOperand(out operand))
                    {
                        node = new JnsInstruction(this.rawInput, instructionToken, operand);
                    }
                    else
                    {
                        this.LogExpectedOneOperandError(instructionToken);
                        return(false);
                    }
                }
                break;
                }
            }

            return(true);
        }