public CallOperator(StandaloneMetric caller, MetricExpression callee) : base(caller, callee) { if (caller == null || callee == null) { throw new ArgumentNullException(); } _caller = caller; _callee = callee; }
private StandaloneMetric ParseMetric() { Token token; // Get name if (!Expect(TokenType.Identifier, out token)) { return(null); } var name = token.Value; var parameters = new string[0]; var nextToken = PeekNextToken(); if (nextToken != null && nextToken.Type == TokenType.LeftBracket) { GetNextToken(); parameters = ParseParameters(); if (parameters == null) { return(null); } if (!Expect(TokenType.RightBracket, out token)) { return(null); } } // check if name is valid metric if (!MetricEvaluationContext.NameToMetricMap.ContainsKey(name)) { LastErrorMessage = string.Format("Undefined metric name {0}", name); return(null); } var metricType = MetricEvaluationContext.NameToMetricMap[name]; StandaloneMetric metric = null; try { var constructors = metricType.FindMembers( MemberTypes.Constructor, BindingFlags.Public | BindingFlags.Instance, null, null); foreach (var constructor in constructors) { var parameterTypes = ((ConstructorInfo)constructor).GetParameters().Select(pi => pi.ParameterType).ToArray(); if (parameterTypes.Length != parameters.Length) { continue; } // try to convert parameters to the expected type var objects = new object[parameterTypes.Length]; try { for (var i = 0; i < parameterTypes.Length; ++i) { objects[i] = Convert.ChangeType(parameters[i], parameterTypes[i]); } } catch { continue; } // now try to create instance with converted parameters metric = new StandaloneMetric((SerialMetric)Activator.CreateInstance(metricType, objects)); break; } if (metric == null) { LastErrorMessage = string.Format( "Can't find proper constructor for metric {0} that can be initialized by parameters {1}", metricType.Name, string.Join(",", parameters)); return(null); } } catch (Exception ex) { LastErrorMessage = string.Format( "Create metric object {0} with parameter {1} failed. Exception {2}", metricType.Name, string.Join(",", parameters), ex.ToString()); return(null); } return(metric); }
private MetricExpression Parse() { // parse the first part, such as MA[20] StandaloneMetric metric = ParseMetric(); if (metric == null) { return(null); } // parse the call operation part, such as (MA[20]) MetricExpression callee = null; Token token = PeekNextToken(); if (token != null && token.Type == TokenType.LeftParenthese) { GetNextToken(); callee = Parse(); if (callee == null || !Expect(TokenType.RightParenthese, out token)) { return(null); } } // parse the selection part, such as .DIF int fieldIndex = -1; token = PeekNextToken(); if (token != null && token.Type == TokenType.Dot) { GetNextToken(); if (!Expect(TokenType.Identifier, out token)) { return(null); } string field = token.Value; // verify if the selection name is part of metric definition Type metricType = metric.Metric.GetType(); MetricAttribute attribute = metricType.GetCustomAttribute <MetricAttribute>(); if (!attribute.NameToFieldIndexMap.ContainsKey(field)) { LastErrorMessage = string.Format("{0} is not a valid subfield of metric {1}", field, metricType.Name); return(null); } fieldIndex = attribute.NameToFieldIndexMap[field]; } MetricExpression retValue = metric; if (callee != null) { retValue = new CallOperator(metric, callee); } if (fieldIndex >= 0) { retValue = new SelectionOperator(retValue, fieldIndex); } return(retValue); }