// 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); }
public SubInstruction GetSubInstruction() { if (this.SourceSubInstruction == null) { this.SourceSubInstruction = this.SourceInstruction.GetSubInstruction(this); } return(this.SourceSubInstruction); }
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))); }
public void EmitSub(Type type, bool @checked) { if (@checked) { Emit(SubOvfInstruction.Create(type)); } else { Emit(SubInstruction.Create(type)); } }
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); }
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); }
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; }
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); }
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))); }
public void EmitSub(Type type, bool @checked) { Emit(@checked ? SubOvfInstruction.Create(type) : SubInstruction.Create(type)); }
public void ToString_Formatted() { target = new SubInstruction(16, 17, 18); Assert.AreEqual("SUB $s0, $s1, $s2", target.ToString()); }
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); }
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))); }
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); }