public static void ResetSymbolAsFunction(ISymbols symscope, string varname, LObject lobj) { // 1. Define the function in global symbol scope var lambda = lobj as LFunction; var funcExpr = lambda.Value as FunctionExpr; var symbol = new SymbolFunction(funcExpr.Meta); symbol.Name = varname; symbol.FuncExpr = funcExpr; symscope.Define(symbol); }
public static LNumber ConverToLangDayOfWeekNumber(LObject obj) { if (obj.Type == LTypes.Date) { var day = (int)((LDate)obj).Value.DayOfWeek; return new LNumber(day); } if (obj.Type == LTypes.DayOfWeek) { var day = (int)((LDayOfWeek)obj).Value; return new LNumber(day); } return (LNumber)obj; }
/// <summary> /// Get / set value by index. /// </summary> /// <param name="target">The target list to apply this method on.</param> /// <param name="index"></param> /// <returns></returns> public virtual object GetByStringMember(LObject target, string member) { return LObjects.Null; }
/// <summary> /// Get / set value by index. /// </summary> /// <param name="target">The target list to apply this method on.</param> /// <param name="index"></param> /// <returns></returns> public virtual object GetByNumericIndex(LObject target, int index) { return LObjects.Null; }
/// <summary> /// Evaluates a math expression of 2 time spans. /// </summary> /// <param name="node">The AST node the evaluation is a part of.</param> /// <param name="lhSide">The time on the left hand side</param> /// <param name="rhSide">The time on the right hand side</param> /// <param name="op">The math operator.</param> /// <returns></returns> public static LBool CompareDayDifference(AstNode node, LObject lhSide, LObject rhSide, Operator op) { var today = DateTime.Today; var targetDate = DateTime.Today; TimeSpan expectedDiff = TimeSpan.MinValue; if(lhSide.Type == LTypes.Date) { targetDate = ((LDate)lhSide).Value; expectedDiff = ((LTime)rhSide).Value; } else { targetDate = ((LDate)rhSide).Value; expectedDiff = ((LTime)lhSide).Value; } // Normalized to dates. var diff = targetDate - today; // Now compare if days away. var diffDays = diff.Days; if (diffDays < 0) return new LBool(false); //if (diffDays < 0) diffDays = diffDays*-1; // var diffHours = diff.Hours*-1; var result = false; if (op == Operator.LessThan) result = diffDays < expectedDiff.Days; else if (op == Operator.LessThanEqual) result = diffDays <= expectedDiff.Days; else if (op == Operator.MoreThan) result = diffDays > expectedDiff.Days; else if (op == Operator.MoreThanEqual) result = diffDays >= expectedDiff.Days; else if (op == Operator.EqualEqual) result = diffDays == expectedDiff.Days; else if (op == Operator.NotEqual) result = diffDays != expectedDiff.Days; return new LBool(result); }
/// <summary> /// Set a value by the index. /// </summary> /// <param name="obj"></param> /// <param name="ndx"></param> public virtual void SetByStringMember(LObject obj, string member, LObject val) { }
/// <summary> /// Get / set value by index. /// </summary> /// <param name="target">The target list to apply this method on.</param> /// <param name="index"></param> /// <returns></returns> public virtual object GetByStringMember(LObject target, string member) { return(LObjects.Null); }
/// <summary> /// Whether or not the associted obj of this methods class has the supplied member. /// </summary> /// <param name="obj">The data obj to check for the member</param> /// <param name="memberName">The name of the member to check for.</param> /// <returns></returns> public virtual bool HasMember(LObject obj, string memberName) { return(_allMembersMap.ContainsKey(memberName)); }
/// <summary> /// Executes the method supplied on the the type. /// </summary> /// <param name="obj">The language type</param> /// <param name="methodName">The method name</param> /// <param name="parameters">The parameters to the method.</param> /// <returns></returns> public virtual object ExecuteMethod(LObject obj, string methodName, object[] parameters) { var mappedMethod = _methodMap[methodName]; var args = new ArgsFetcher(parameters); // total required = var funcDef = mappedMethod.FuncDef; int total = funcDef.GetTotalRequiredArgs(); var methodArgs = new List<object>(); var hasParams = parameters != null && parameters.Length > 0; methodArgs.Add(obj); // TODO: Figure out the total required args when AddArg is called. if (total > 0 && hasParams ) { var ndx = 0; var totalParamsGiven = parameters.Length; var convertArgs = mappedMethod.ConvertParameters; // Go through all the argument definitions. foreach (var arg in funcDef.Arguments) { var isRequired = arg.Required; // 1. Required and provided? if (isRequired && ndx < parameters.Length) { // Positional arg. if (arg.Type != "params") { var param = parameters[ndx]; var val = convertArgs ? ConvertToProperType(arg, param) : param; methodArgs.Add(val); } // End of list arguments. else { var remainder = new List<object>(); while (ndx < totalParamsGiven) { var param = parameters[ndx]; var val = convertArgs ? ConvertToProperType(arg, param) : param; remainder.Add(val); ndx++; } methodArgs.Add(remainder.ToArray()); } } // 2. Not required but supplied. else if (!isRequired && ndx < parameters.Length) { var param = parameters[ndx]; var val = convertArgs ? ConvertToProperType(arg, param) : param; methodArgs.Add(val); } // 3. Not required but there is a default. else if (!isRequired && arg.DefaultValue != null && ndx >= parameters.Length) { methodArgs.Add(arg.DefaultValue); } // 4. Not required and extra params else if(!isRequired && arg.DefaultValue == null && arg.Name == "params" && ndx >= parameters.Length) { methodArgs.Add(null); } ndx++; } } else if(hasParams ) { for (var ndx = 0; ndx < parameters.Length; ndx++) { var val = ((LObject) parameters[ndx]).GetValue(); methodArgs.Add(val); } } var methodParams = methodArgs.ToArray(); var method = this.GetType().GetMethod(mappedMethod.HostLanguageMethod); object result = method.Invoke(this, methodParams); return result; }
/// <summary> /// Creates a variable expression with symbol scope, context, script refernce set. /// </summary> /// <param name="name"></param> /// <returns></returns> public static Expr Const(LObject obj, TokenData token) { var exp = new ConstantExpr(); exp.Value = obj; SetupContext(exp, token); return exp; }
/// <summary> /// Gets a see MemberAccess object that represents the instance, member name and other information on the member access expression. /// </summary> /// <param name="node">The Ast node associated with the member access operation</param> /// <param name="methods">The collection of registered methods on various types</param> /// <param name="obj">The object on which the member access is being performed.</param> /// <param name="memberName">The name of the member to get.</param> /// <returns></returns> public static MemberAccess GetLangBasicTypeMember(AstNode node, RegisteredMethods methods, LObject obj, string memberName) { var type = obj.Type; // Get the methods implementation LTypeMethods for this basic type // e.g. string, date, time, array , map // e.g. LStringType LDateType, LTimeType, LArrayType, LMapType var typeMethods = methods.Get(type); var memberExists = typeMethods.HasMember(obj, memberName); // 1. Can set non-existing map properties if (type == LTypes.Map && !memberExists) { var nonExistMAccess = new MemberAccess(MemberMode.PropertyMember); nonExistMAccess.Name = type.Name; nonExistMAccess.Instance = obj; nonExistMAccess.MemberName = memberName; nonExistMAccess.Type = type; nonExistMAccess.MemberMissing = true; return nonExistMAccess; } // 2. Check that the member exists. if (!memberExists) throw ExceptionHelper.BuildRunTimeException(node, "Property or Member : " + memberName + " does not exist"); // 3. It's either a Property or method var isProp = typeMethods.HasProperty(obj, memberName); var mode = isProp ? MemberMode.PropertyMember : MemberMode.MethodMember; var maccess = new MemberAccess(mode); maccess.Name = type.Name; maccess.Instance = obj; maccess.MemberName = memberName; maccess.Type = type; return maccess; }
/// <summary> /// Is match with the type supplied and the /// </summary> /// <param name="type"></param> /// <param name="obj1"></param> /// <param name="obj2"></param> /// <returns></returns> private bool IsTypeMatch(LType type, LObject obj1, LObject obj2) { if (obj1.Type == type && obj2.Type == type) return true; return false; }
/// <summary> /// Check if the expression is true. /// </summary> /// <param name="result"></param> /// <returns></returns> public static bool IsTrue(LObject result) { if (result == null || result == LObjects.Null) return false; if (result.Type == LTypes.Number) { var num = (LNumber) result; return num.Value > 0; } if (result.Type == LTypes.String) { var str = (LString)result; return str.Value != null; } if (result.Type == LTypes.Bool) { var bl = (LBool) result; return bl.Value; } if ( result.Type == LTypes.Date) { var dt = (LDate) result; return dt.Value != DateTime.MinValue && dt.Value != DateTime.MaxValue; } return true; }
/// <summary> /// Evaluate the result of indexing an object e.g. users[0] or users["admins"] /// </summary> /// <param name="regmethods"></param> /// <param name="node"></param> /// <param name="target"></param> /// <param name="ndxObj"></param> /// <returns></returns> public static LObject AccessIndex(RegisteredMethods regmethods, AstNode node, LObject target, LObject ndxObj) { object result = LObjects.Null; // Case 1: Array access users[0]; if (target.Type == LTypes.Array || target.Type.TypeVal == LTypes.Table.TypeVal) { var ndx = ((LNumber)ndxObj).Value; var isArray = target.Type == LTypes.Array; var methods = isArray ? regmethods.Get(LTypes.Array) : regmethods.Get(LTypes.Table); // TODO: Make this generic. var length = Convert.ToInt32(methods.ExecuteMethod(target, "length", null)); if(ndx >= length) throw ExceptionHelper.BuildRunTimeException(node, "Index out of bounds : '" + ndx + "'"); result = methods.GetByNumericIndex(target, (int)ndx); } // Case 2: Map access. users["kishore"]; else if (target.Type == LTypes.Map) { var memberName = ((LString)ndxObj).Value; var methods = regmethods.Get(LTypes.Map); if (!methods.HasProperty(target, memberName)) throw ExceptionHelper.BuildRunTimeException(node, "Property does not exist : '" + memberName + "'"); result = methods.GetByStringMember(target, memberName); } // Conver to lang type. if(result != LObjects.Null && !(result is LObject)) { result = LangTypeHelper.ConvertToLangValue(result); } return (LObject)result; }
/// <summary> /// Evaluates a math expression of 2 time spans. /// </summary> /// <param name="node">The AST node the evaluation is a part of.</param> /// <param name="lhs">The time on the left hand side</param> /// <param name="rhs">The time on the right hand side</param> /// <param name="op">The math operator.</param> /// <returns></returns> public static LBool CompareDays(AstNode node, LObject lhs, LObject rhs, Operator op) { var left = LangTypeHelper.ConverToLangDayOfWeekNumber(lhs); var right = LangTypeHelper.ConverToLangDayOfWeekNumber(rhs); var res = CompareNumbers(node, left, right, op); return res; }
/// <summary> /// Get / set value by index. /// </summary> /// <param name="obj">The object whose index value is being set.</param> /// <param name="index">The index position to set the value</param> /// <param name="val">The value to set at the index</param> /// <returns></returns> public virtual void SetByNumericIndex(LObject obj, int index, LObject val) { }
/// <summary> /// Whether or not the associted obj of this methods class has the supplied member. /// </summary> /// <param name="obj">The data obj to check for the member</param> /// <param name="memberName">The name of the member to check for.</param> /// <returns></returns> public virtual bool HasMember(LObject obj, string memberName) { return _allMembersMap.ContainsKey(memberName); }
/// <summary> /// Whether or not the associted obj of this methods class has the supplied method. /// </summary> /// <param name="obj">The data obj to check for the method</param> /// <param name="methodName">The name of the method to check for.</param> /// <returns></returns> public virtual bool HasMethod(LObject obj, string methodName) { if (!_allMembersMap.ContainsKey(methodName)) return false; var member = _allMembersMap[methodName]; return member == MemberTypes.Method; }
/// <summary> /// Whether or not the associted obj of this methods class has the supplied property. /// </summary> /// <param name="obj">The data obj to check for the property</param> /// <param name="propertyName">The name of the property</param> /// <returns></returns> public virtual bool HasProperty(LObject obj, string propertyName) { if (!_allMembersMap.ContainsKey(propertyName)) return false; var member = _allMembersMap[propertyName]; return member == MemberTypes.Property; }
/// <summary> /// Get / set value by index. /// </summary> /// <param name="target">The target list to apply this method on.</param> /// <param name="index"></param> /// <returns></returns> public virtual object GetByNumericIndex(LObject target, int index) { return(LObjects.Null); }
/// <summary> /// Sets the property value for the specified propertyname. /// </summary> /// <param name="obj">The object to set the property value on</param> /// <param name="propName">The name of the property</param> /// <param name="val">The value to set on the property</param> /// <returns></returns> public virtual void SetProperty(LObject obj, string propName, object val) { var mappedMethod = _methodMap[propName]; // total required = var funcDef = mappedMethod.FuncDef; int total = funcDef.GetTotalRequiredArgs(); var methodArgs = new[] {obj, val}; var method = this.GetType().GetMethod(mappedMethod.HostLanguageMethod); object result = method.Invoke(this, methodArgs); }
/// <summary> /// Validates the method call. /// </summary> /// <param name="obj"></param> /// <param name="methodName"></param> /// <param name="parameters"></param> /// <returns></returns> public virtual BoolMsgObj ValidateCall(LObject obj, string methodName, object[] parameters) { // 1. Valid method/member name? if (!this._methodMap.ContainsKey(methodName)) return new BoolMsgObj(obj, false, "The method name : " + methodName + " does not exist for this type"); // 2. Valid method parameters? var mappedMethod = _methodMap[methodName]; var funcDef = mappedMethod.FuncDef; var ndx = 0; var isValid = true; var message = string.Empty; foreach (var arg in funcDef.Arguments) { if (arg.Required && ndx >= parameters.Length) { isValid = false; message = "Required argument : " + arg.Name + " was not supplied"; break; } var param = parameters[ndx]; ndx++; } return new BoolMsgObj(obj, isValid, message); }
/// <summary> /// Executes the method supplied on the the type. /// </summary> /// <param name="obj">The language type</param> /// <param name="methodName">The method name</param> /// <param name="parameters">The parameters to the method.</param> /// <returns></returns> public virtual object ExecuteMethod(LObject obj, string methodName, object[] parameters) { var mappedMethod = _methodMap[methodName]; var args = new ArgsFetcher(parameters); // total required = var funcDef = mappedMethod.FuncDef; int total = funcDef.GetTotalRequiredArgs(); var methodArgs = new List <object>(); var hasParams = parameters != null && parameters.Length > 0; methodArgs.Add(obj); // TODO: Figure out the total required args when AddArg is called. if (total > 0 && hasParams) { var ndx = 0; var totalParamsGiven = parameters.Length; var convertArgs = mappedMethod.ConvertParameters; // Go through all the argument definitions. foreach (var arg in funcDef.Arguments) { var isRequired = arg.Required; // 1. Required and provided? if (isRequired && ndx < parameters.Length) { // Positional arg. if (arg.Type != "params") { var param = parameters[ndx]; var val = convertArgs ? ConvertToProperType(arg, param) : param; methodArgs.Add(val); } // End of list arguments. else { var remainder = new List <object>(); while (ndx < totalParamsGiven) { var param = parameters[ndx]; var val = convertArgs ? ConvertToProperType(arg, param) : param; remainder.Add(val); ndx++; } methodArgs.Add(remainder.ToArray()); } } // 2. Not required but supplied. else if (!isRequired && ndx < parameters.Length) { var param = parameters[ndx]; var val = convertArgs ? ConvertToProperType(arg, param) : param; methodArgs.Add(val); } // 3. Not required but there is a default. else if (!isRequired && arg.DefaultValue != null && ndx >= parameters.Length) { methodArgs.Add(arg.DefaultValue); } // 4. Not required and extra params else if (!isRequired && arg.DefaultValue == null && arg.Name == "params" && ndx >= parameters.Length) { methodArgs.Add(null); } ndx++; } } else if (hasParams) { for (var ndx = 0; ndx < parameters.Length; ndx++) { var val = ((LObject)parameters[ndx]).GetValue(); methodArgs.Add(val); } } var methodParams = methodArgs.ToArray(); var method = this.GetType().GetMethod(mappedMethod.HostLanguageMethod); object result = method.Invoke(this, methodParams); return(result); }
/// <summary> /// Visita a compare expression with the values evaluated. /// </summary> /// <param name="node"></param> /// <param name="op"></param> /// <param name="left"></param> /// <param name="right"></param> /// <returns></returns> public static object Compare(AstNode node, Operator op, LObject left, LObject right) { object result = null; // Both double if (left.Type == LTypes.Number && right.Type == LTypes.Number) result = EvalHelper.CompareNumbers(node, (LNumber)left, (LNumber)right, op); // Both strings else if (left.Type == LTypes.String && right.Type == LTypes.String) result = EvalHelper.CompareStrings(node, (LString)left, (LString)right, op); // Both bools else if (left.Type == LTypes.Bool && right.Type == LTypes.Bool) result = EvalHelper.CompareBools(node, (LBool)left, (LBool)right, op); // Both dates else if (left.Type == LTypes.Date && right.Type == LTypes.Date) result = EvalHelper.CompareDates(node, (LDate)left, (LDate)right, op); // Both Timespans else if (left.Type == LTypes.Time && right.Type == LTypes.Time) result = EvalHelper.CompareTimes(node, (LTime)left, (LTime)right, op); // 1 or both null else if (left == LObjects.Null || right == LObjects.Null) result = EvalHelper.CompareNull(left, right, op); // Day of week ? else if (left.Type == LTypes.DayOfWeek || right.Type == LTypes.DayOfWeek) result = EvalHelper.CompareDays(node, left, right, op); // Date and time ? else if ((left.Type == LTypes.Date && right.Type == LTypes.Time) || (left.Type == LTypes.Time && right.Type == LTypes.Date)) result = EvalHelper.CompareDayDifference(node, left, right, op); // Units //else if (left.Type == LTypes.Unit || right.Type == LTypes.Unit) else if (left.Type.Name == "LUnit" || right.Type.Name == "LUnit") result = EvalHelper.CompareUnits(node, (LUnit)((LClass)left).Value, (LUnit)((LClass)right).Value, op); return result; }