private static void EmitChild(ExpressionElement child, Type resultType, FleeILGenerator ilg, IServiceProvider services) { child.Emit(ilg, services); bool converted = ImplicitConverter.EmitImplicitConvert(child.ResultType, resultType, ilg); Debug.Assert(converted, "convert failed"); }
/// <summary> /// Emit a short-circuited logical operation sequence /// The idea: Store all the leaf operands in a stack with the leftmost at the top and rightmost at the bottom. /// For each operand, emit it and try to find an end point for when it short-circuits. This means we go up through /// the stack of operators (ignoring siblings) until we find a different operation (then emit a branch to its right operand) /// or we reach the root (emit a branch to a true/false). /// Repeat the process for all operands and then emit the true/false/last operand end cases. /// </summary> /// <param name="ilg"></param> /// <param name="info"></param> /// <param name="services"></param> private void EmitLogical(FleeILGenerator ilg, ShortCircuitInfo info, IServiceProvider services) { // We always have an end label info.Branches.GetLabel(OurEndLabelKey, ilg); // Populate our data structures this.PopulateData(info); // Emit the sequence EmitLogicalShortCircuit(ilg, info, services); // Get the last operand ExpressionElement terminalOperand = (ExpressionElement)info.Operands.Pop(); // Emit it EmitOperand(terminalOperand, info, ilg, services); // And jump to the end Label endLabel = info.Branches.FindLabel(OurEndLabelKey); ilg.Emit(OpCodes.Br_S, endLabel); // Emit our true/false terminals EmitTerminals(info, ilg, endLabel); // Mark the end ilg.MarkLabel(endLabel); }
/// <summary> /// Emit elements into an array /// </summary> /// <param name="elements"></param> /// <param name="arrayElementType"></param> /// <param name="ilg"></param> /// <param name="services"></param> private static void EmitElementArrayLoad(ExpressionElement[] elements, Type arrayElementType, FleeILGenerator ilg, IServiceProvider services) { // Load the array length LiteralElement.EmitLoad(elements.Length, ilg); // Create the array ilg.Emit(OpCodes.Newarr, arrayElementType); // Store the new array in a unique local and remember the index LocalBuilder local = ilg.DeclareLocal(arrayElementType.MakeArrayType()); int arrayLocalIndex = local.LocalIndex; Utility.EmitStoreLocal(ilg, arrayLocalIndex); for (int i = 0; i <= elements.Length - 1; i++) { // Load the array Utility.EmitLoadLocal(ilg, arrayLocalIndex); // Load the index LiteralElement.EmitLoad(i, ilg); // Emit the element (with any required conversions) ExpressionElement element = elements[i]; element.Emit(ilg, services); ImplicitConverter.EmitImplicitConvert(element.ResultType, arrayElementType, ilg); // Store it into the array Utility.EmitArrayStore(ilg, arrayElementType); } // Load the array Utility.EmitLoadLocal(ilg, arrayLocalIndex); }
/// <summary> /// Emit a short-circuited logical operation sequence /// The idea: Store all the leaf operands in a stack with the leftmost at the top and rightmost at the bottom. /// For each operand, emit it and try to find an end point for when it short-circuits. This means we go up through /// the stack of operators (ignoring siblings) until we find a different operation (then emit a branch to its right operand) /// or we reach the root (emit a branch to a true/false). /// Repeat the process for all operands and then emit the true/false/last operand end cases. /// </summary> /// <param name="ilg"></param> /// <param name="info"></param> /// <param name="services"></param> private void EmitLogical(FleeILGenerator ilg, ShortCircuitInfo info, IServiceProvider services) { // We always have an end label Label endLabel = ilg.DefineLabel(); // Populate our data structures this.PopulateData(info); // Emit the sequence EmitLogicalShortCircuit(ilg, info, services); // Get the last operand ExpressionElement terminalOperand = (ExpressionElement)info.Operands.Pop(); // Emit it EmitOperand(terminalOperand, info, ilg, services); // only 1-3 opcodes, always a short branch ilg.EmitBranch(endLabel); // Emit our true/false terminals EmitTerminals(info, ilg, endLabel); // Mark the end ilg.MarkLabel(endLabel); }
public override Node ExitInExpression(Production node) { IList childValues = this.GetChildValues(node); if (childValues.Count == 1) { this.AddFirstChildValue(node); return(node); } ExpressionElement operand = (ExpressionElement)childValues[0]; childValues.RemoveAt(0); object second = childValues[0]; InElement op = default(InElement); if ((second) is IList) { op = new InElement(operand, (IList)second); } else { InvocationListElement il = new InvocationListElement(childValues, _myServices); op = new InElement(operand, il); } node.AddValue(op); return(node); }
public ConditionalElement(ExpressionElement condition, ExpressionElement whenTrue, ExpressionElement whenFalse) { _myCondition = condition; _myWhenTrue = whenTrue; _myWhenFalse = whenFalse; if ((!object.ReferenceEquals(_myCondition.ResultType, typeof(bool)))) { base.ThrowCompileException(CompileErrorResourceKeys.FirstArgNotBoolean, CompileExceptionReason.TypeMismatch); } // The result type is the type that is common to the true/false operands if (ImplicitConverter.EmitImplicitConvert(_myWhenFalse.ResultType, _myWhenTrue.ResultType, null) == true) { _myResultType = _myWhenTrue.ResultType; } else if (ImplicitConverter.EmitImplicitConvert(_myWhenTrue.ResultType, _myWhenFalse.ResultType, null) == true) { _myResultType = _myWhenFalse.ResultType; } else { base.ThrowCompileException(CompileErrorResourceKeys.NeitherArgIsConvertibleToTheOther, CompileExceptionReason.TypeMismatch, _myWhenTrue.ResultType.Name, _myWhenFalse.ResultType.Name); } }
protected Instruction(InstructionSet instructionSet, ExpressionElement argument, RealInstructionGetter realInstructionGetter) { if (realInstructionGetter != null) { RealInstruction = realInstructionGetter.GetRealInstruction(instructionSet, argument); } }
StringFormatText(string formatText, ExpressionElement[] args, string front, string back) { _formatText = formatText; _args = args; _front = front; _back = back; }
public override IDeepCopyable CopyTo(IDeepCopyable other) { var dest = other as Expression; if (dest == null) { throw new ArgumentException("Can only copy to an object of the same type", "other"); } base.CopyTo(dest); if (DescriptionElement != null) { dest.DescriptionElement = (Hl7.Fhir.Model.FhirString)DescriptionElement.DeepCopy(); } if (NameElement != null) { dest.NameElement = (Hl7.Fhir.Model.Id)NameElement.DeepCopy(); } if (LanguageElement != null) { dest.LanguageElement = (Hl7.Fhir.Model.Code)LanguageElement.DeepCopy(); } if (ExpressionElement != null) { dest.ExpressionElement = (Hl7.Fhir.Model.FhirString)ExpressionElement.DeepCopy(); } if (ReferenceElement != null) { dest.ReferenceElement = (Hl7.Fhir.Model.FhirUri)ReferenceElement.DeepCopy(); } return(dest); }
// Try to fold a negated constant int32. We have to do this so that parsing int32.MinValue will work public override Node ExitNegateExpression(Production node) { IList childValues = this.GetChildValues(node); // Get last child ExpressionElement childElement = (ExpressionElement)childValues[childValues.Count - 1]; // Is it an signed integer constant? if (object.ReferenceEquals(childElement.GetType(), typeof(Int32LiteralElement)) & childValues.Count == 2) { ((Int32LiteralElement)childElement).Negate(); // Add it directly instead of the negate element since it will already be negated node.AddValue(childElement); } else if (object.ReferenceEquals(childElement.GetType(), typeof(Int64LiteralElement)) & childValues.Count == 2) { ((Int64LiteralElement)childElement).Negate(); // Add it directly instead of the negate element since it will already be negated node.AddValue(childElement); } else { // No so just add a regular negate this.AddUnaryOp(node, typeof(NegateElement)); } return(node); }
private RuleModelLight GetRule(ExpressionElement expression, Dictionary <Langue, string> names, RuleType type, bool isEnable) => new RuleModelLight() { Expression = expression.Expression, Type = type.ToString(), Name = string.Join(" | ", names.Select(z => $"{z.Key.Description()} : {z.Value}")), IsEnable = isEnable };
public static bool AreEqual(ExpressionElement first, ExpressionElement second) { if (!ExpressionComparer.AreEqual(first.Expression, second.Expression)) { return(false); } return(true); }
internal void InitBoolOperator(ExpressionElement arg) { if (arg is BooleanLiteralElement) { var boolArg = (BooleanLiteralElement)arg; @operator = (boolArg.Value) ? "isTrue" : "isFalse"; } }
// Initialize for between two expressions public BetweenElement(ExpressionElement operand, ExpressionElement from, ExpressionElement to) { _operand = operand; _from = from; _to = to; // TODO: Validate parameter types }
public BindingNode(ExpressionElement expressionElement, ILhsTupleExpression <object> compiledExpression, Type resultType, ITupleSource source) { ExpressionElement = expressionElement; _compiledExpression = compiledExpression; ResultType = resultType; Source = source; Source.Attach(this); }
// Initialize for searching a list of values public InElement(ExpressionElement operand, IList listElements) { _myOperand = operand; ExpressionElement[] arr = new ExpressionElement[listElements.Count]; listElements.CopyTo(arr, 0); _myArguments = new List <ExpressionElement>(arr); }
public ILhsExpression <TResult> CompileLhsExpression <TResult>(ExpressionElement element, List <Declaration> declarations) { if (element.Imports.Count() == 1 && Equals(element.Imports.Single(), declarations.Last())) { return(CompileLhsFactExpression <TResult>(element)); } return(CompileLhsTupleFactExpression <TResult>(element, declarations)); }
private static bool AreParameterPositionsEqual( List <Declaration> firstDeclarations, ExpressionElement firstElement, List <Declaration> secondDeclarations, ExpressionElement secondElement) { var parameterMap1 = IndexMap.CreateMap(firstElement.Imports, firstDeclarations); var parameterMap2 = IndexMap.CreateMap(secondElement.Imports, secondDeclarations); return(Equals(parameterMap1, parameterMap2)); }
public ILhsFactExpression <TResult> CompileLhsFactExpression <TResult>(ExpressionElement element) { var optimizedExpression = ExpressionOptimizer.Optimize <Func <Fact, TResult> >( element.Expression, IndexMap.Unit, tupleInput: false, factInput: true); var @delegate = optimizedExpression.Compile(); var argumentMap = new ArgumentMap(IndexMap.Unit, 1); var expression = new LhsFactExpression <TResult>(element.Expression, @delegate, argumentMap); return(expression); }
// Initialize for searching a list of values public InElement(ExpressionElement operand, IList listElements) { MyOperand = operand; ExpressionElement[] arr = new ExpressionElement[listElements.Count]; listElements.CopyTo(arr, 0); MyArguments = new List <ExpressionElement>(arr); this.ResolveForListSearch(); }
public ILhsExpression <TResult> CompileLhsTupleFactExpression <TResult>(ExpressionElement element, List <Declaration> declarations) { var factMap = IndexMap.CreateMap(element.Imports, declarations); var optimizedExpression = ExpressionOptimizer.Optimize <Func <Tuple, Fact, TResult> >( element.Expression, factMap, tupleInput: true, factInput: true); var @delegate = ExpressionCompiler.Compile(optimizedExpression); var argumentMap = new ArgumentMap(factMap, element.Expression.Parameters.Count); var expression = new LhsExpression <TResult>(element.Expression, @delegate, argumentMap); return(expression); }
public override ParseResult Parse() { var element = new ExpressionElement(); element .Add(ParseElement(ElementCategory.Term)) .Add(ParseZeroOrMore(AdditionalTermParser.IsValid, ElementCategory.AdditionalExpressionTerm)); return(new ParseResult(ConsumedTokensCount, element)); }
// Evaluates value of group, e.g. (2+4*4) = 18 // A group is an expression without any sub-groups (expressions in paretheses) float EvaluateGroup(List <ExpressionElement> groupElements, List <float> groupValues) { int valueIndex = 0; // resolve multiplication and division for (int i = 0; i < groupElements.Count; i++) { ExpressionElement element = groupElements[i]; if (element == ExpressionElement.Value) { valueIndex++; } else if (element == ExpressionElement.Multiply || element == ExpressionElement.Divide) { float valueA = groupValues[valueIndex - 1]; float valueB = groupValues[valueIndex]; float result_dm = (element == ExpressionElement.Multiply) ? valueA * valueB : valueA / valueB; groupValues[valueIndex - 1] = result_dm; groupValues.RemoveAt(valueIndex); groupElements.RemoveRange(i - 1, 2); i--; } } // Sum up remaining terms valueIndex = 0; float result = 0; for (int i = 0; i < groupElements.Count; i++) { ExpressionElement element = groupElements[i]; if (element == ExpressionElement.Value) { int sign = 1; // Backtrack through operators up to last value to figure out if should be addition or subtraction // This deals with multiple operators like x-(-y) = x+y for (int j = i - 1; j >= 0; j--) { if (groupElements[j] == ExpressionElement.Value) { break; } if (groupElements[j] == ExpressionElement.Minus) { sign *= -1; } } result += groupValues[valueIndex] * sign; valueIndex++; } } return(result); }
private static void EmitOperand(ExpressionElement operand, ShortCircuitInfo info, FleeILGenerator ilg, IServiceProvider services) { // Is this operand the target of a label? if (info.HasLabel(operand) == true) { // Yes, so mark it Label leftLabel = info.FindLabel(operand); ilg.MarkLabel(leftLabel); } // Emit the operand operand.Emit(ilg, services); }
private void SetupArrayIndexer() { _myIndexerElement = _myIndexerElements[0]; if (_myIndexerElements.Count > 1) { base.ThrowCompileException(CompileErrorResourceKeys.MultiArrayIndexNotSupported, CompileExceptionReason.TypeMismatch); } else if (ImplicitConverter.EmitImplicitConvert(_myIndexerElement.ResultType, typeof(Int32), null) == false) { base.ThrowCompileException(CompileErrorResourceKeys.ArrayIndexersMustBeOfType, CompileExceptionReason.TypeMismatch, typeof(Int32).Name); } }
private void DetachExpressionHandlers(ExpressionElement expressionBlock) { if (expressionBlock != null) { expressionBlock.PropertyChanged += ViewModel_PropertyChanged; if (expressionBlock is CompositeElement) { (expressionBlock as CompositeElement).Children.CollectionChanged -= ViewModel_PropertyChanged; (expressionBlock as CompositeElement).HeaderElements.CollectionChanged -= ViewModel_PropertyChanged; (expressionBlock as CompositeElement).Children.ToList().ForEach(DetachExpressionHandlers); (expressionBlock as CompositeElement).HeaderElements.ToList().ForEach(DetachExpressionHandlers); } } }
/// <summary> /// Emit the arguments to a regular method call /// </summary> /// <param name="parameters"></param> /// <param name="elements"></param> /// <param name="ilg"></param> /// <param name="services"></param> private void EmitRegularFunctionInternal(ParameterInfo[] parameters, ExpressionElement[] elements, FleeILGenerator ilg, IServiceProvider services) { Debug.Assert(parameters.Length == elements.Length, "argument count mismatch"); // Emit each element and any required conversions to the actual parameter type for (int i = 0; i <= parameters.Length - 1; i++) { ExpressionElement element = elements[i]; ParameterInfo pi = parameters[i]; element.Emit(ilg, services); bool success = ImplicitConverter.EmitImplicitConvert(element.ResultType, pi.ParameterType, ilg); Debug.Assert(success, "conversion failed"); } }
private void HandleFirstElement(IList elements, IServiceProvider services) { ExpressionElement first = (ExpressionElement)elements[0]; // If the first element is not a member element, then we assume it is an expression and replace it with the correct member element if (!(first is MemberElement)) { ExpressionMemberElement actualFirst = new ExpressionMemberElement(first); elements[0] = actualFirst; } else { this.ResolveNamespaces(elements, services); } }
private void BuildSelectionNode(ReteBuilderContext context, ExpressionElement element) { SelectionNode node = context.CurrentAlphaNode .ChildNodes.OfType <SelectionNode>() .FirstOrDefault(sn => ExpressionElementComparer.AreEqual(sn.ExpressionElement, element)); if (node == null) { var compiledExpression = ExpressionCompiler.CompileLhsFactExpression <bool>(element); node = new SelectionNode(element, compiledExpression); context.CurrentAlphaNode.ChildNodes.Add(node); } node.NodeInfo.Add(context.Rule, element); context.CurrentAlphaNode = node; }
internal void InitStringValueOrSecondField(ExpressionElement arg) { if (arg is StringLiteralElement) { @value = ((StringLiteralElement)arg).Value; } else if (arg is InvocationListElement) { var invocation = ((InvocationListElement)arg).Tail; secondField = ((IdentifierElement)invocation).MemberName.Replace("_", ""); } else { throw new NotImplementedException(); } }
internal ExpressionElement Parse(string expression, IServiceProvider services) { lock (_mySyncRoot) { System.IO.StringReader sr = new System.IO.StringReader(expression); ExpressionParser parser = this.Parser; parser.Reset(sr); parser.Tokenizer.Reset(sr); FleeExpressionAnalyzer analyzer = (FleeExpressionAnalyzer)parser.Analyzer; analyzer.SetServices(services); Node rootNode = DoParse(); analyzer.Reset(); ExpressionElement topElement = (ExpressionElement)rootNode.Values[0]; return(topElement); } }
internal StringFormatText(string formatText, ExpressionElement[] args) { _formatText = formatText; _args = args; }
internal DisableBracketsText(ExpressionElement core) { _core = core; }
/// <summary> /// Associates the given tree elements. /// </summary> /// <param name="elements">The elements.</param> /// <param name="elementCount">The element count.</param> /// <returns></returns> private ExpressionTree AssociateElements(ExpressionElement[] elements, int elementCount) { if(elementCount == 2) { throw new Exception("Invalid expression element count"); } // handle special case if(elementCount == 1) { if(elements[0].Type == ElementType.Implication) { return null; } else if(elements[0].Type == ElementType.Tree) { return (ExpressionTree)elements[0].Element; } else { ExpressionTree tree = new ExpressionTree(); tree.Root = new FilterNode((FilterBase)elements[0].Element); return tree; } } // normal case // middle element should be an Implication if(elements[1].Type != ElementType.Implication) { return null; } ExpressionTree parent = new ExpressionTree(); ExpressionElement left = elements[0]; ExpressionElement right = elements[2]; FilterImplication implication = (FilterImplication)elements[1].Element; // build the tree if(left.Type == ElementType.Tree && right.Type == ElementType.Filter) { parent = ExpressionTreeBuilder.AssociateTreeWithFilter((ExpressionTree)left.Element, (FilterBase)right.Element, implication, TreeDirection.Left); } else if(left.Type == ElementType.Filter && right.Type == ElementType.Tree) { parent = ExpressionTreeBuilder.AssociateTreeWithFilter((ExpressionTree)right.Element, (FilterBase)left.Element, implication, TreeDirection.Right); } else if(left.Type == ElementType.Tree && right.Type == ElementType.Tree) { parent = ExpressionTreeBuilder.AssociateTrees((ExpressionTree)left.Element, (ExpressionTree)right.Element, implication); } else if(left.Type == ElementType.Filter && right.Type == ElementType.Filter) { parent = ExpressionTreeBuilder.AssociateFilters((FilterBase)left.Element, (FilterBase)right.Element, implication); } return parent; }
/// <summary> /// Parses the expression. /// </summary> /// <param name="expression">The expression.</param> /// <param name="start">The start position.</param> /// <param name="tree">The tree.</param> /// <param name="expressionLength">Length of the expression.</param> /// <returns></returns> private bool ParseExpression(string expression, int start, out ExpressionTree tree, out int expressionLength) { tree = null; expressionLength = 0; if(start < 0 || start >= expression.Length) { return false; } // get the end position int position = start; ExpressionElement[] elements = new ExpressionElement[3]; int elementPosition = 0; int length = expression.Length; while(position < length) { // jump over spaces if(expression[position] == ' ' || expression[position] == ExpressionEndChar) { position++; continue; } bool positionChanged = false; if(expression[position] == ExpressionStartChar) { ExpressionTree child; int subexpressionLength; // invalid expression if(ParseExpression(expression, position + 1, out child, out subexpressionLength) == false) { return false; } // invalid expression if(elementPosition == 1) { return false; } elements[elementPosition].Type = ElementType.Tree; elements[elementPosition].Element = child; elementPosition++; position += subexpressionLength + 1; positionChanged = true; } else { // get the first substring string[] components = expression.Substring(position).Split(ExpressionSeparators, StringSplitOptions.RemoveEmptyEntries); // invalid expression if(components.Length == 0) { return false; } FilterImplication implication; if(GetImplicationType(components[0], out implication)) { // valid Implication if(elementPosition != 1) { // invalid expression return false; } elements[elementPosition].Type = ElementType.Implication; elements[elementPosition].Element = implication; elementPosition++; } else { // Filter name if(elementPosition == 1) { // invalid expression return false; } FilterBase filter = GetFilter(components[0]); // invalid expression if(filter == null) { return false; } elements[elementPosition].Type = ElementType.Filter; elements[elementPosition].Element = filter; elementPosition++; } position += components[0].Length + 1; positionChanged = true; } if(positionChanged == false) { position++; } if(position >= length || elementPosition >= 3) { // end of expression, build evaluation tree if(elementPosition == 2) { // invalid expression return false; } // build the tree tree = AssociateElements(elements, elementPosition); expressionLength = position - start; return true; } } return false; }
public IntegralExpressionElement(string value, ExpressionElement elementType, Operator @operator) { this.Value = value; this.ElementType = elementType; this.Operator = @operator; }