Пример #1
0
 public KirinValue(string raw, FiMClass reportClass, KirinVariableType forcedType)
 {
     this.Raw        = raw;
     this.Class      = reportClass;
     this.ForcedType = forcedType;
     this.Load();
 }
Пример #2
0
        private static string DefaultValue(KirinVariableType type)
        {
            if (type == KirinVariableType.STRING)
            {
                return("\"\"");
            }
            if (type == KirinVariableType.CHAR)
            {
                return("\"\0\"");
            }
            if (type == KirinVariableType.NUMBER)
            {
                return("0.0");
            }
            if (type == KirinVariableType.BOOL)
            {
                return("false");
            }
            if (type == KirinVariableType.STRING_ARRAY)
            {
                return("[,]");
            }
            if (type == KirinVariableType.NUMBER_ARRAY)
            {
                return("[,]");
            }
            if (type == KirinVariableType.BOOL_ARRAY)
            {
                return("[,]");
            }

            return("");
        }
Пример #3
0
        private static string SanitizeObject(object value, KirinVariableType valueType)
        {
            switch (valueType)
            {
            case KirinVariableType.STRING: return($"\"{ value }\"");

            case KirinVariableType.CHAR: return($"\'{ value }\'");

            case KirinVariableType.BOOL: return((bool)value == true ? "true" : "false");

            case KirinVariableType.NUMBER: return(Convert.ToDouble(value).ToString());

            case KirinVariableType.NUMBER_ARRAY:
            {
                IDictionary dict = value as IDictionary;
                return($"[,{ string.Join(", ", dict.Values.Cast<double>()) }]");
            }

            case KirinVariableType.STRING_ARRAY:
            {
                IDictionary dict = value as IDictionary;
                return($"[,{ string.Join(", ", dict.Values.Cast<string>().Select(s => $"\"{s}\"")) }]");
            }

            case KirinVariableType.BOOL_ARRAY:
            {
                IDictionary dict = value as IDictionary;
                return($"[,{ string.Join(", ", dict.Values.Cast<bool>().Select(b => (bool)b == true ? "true" : "false")) }]");
            }

            default: return("");
            }
        }
Пример #4
0
        public static object GetDefaultValue(KirinVariableType type)
        {
            if (type == KirinVariableType.STRING)
            {
                return("");
            }
            if (type == KirinVariableType.CHAR)
            {
                return('\0');
            }
            if (type == KirinVariableType.NUMBER)
            {
                return(0.0d);
            }
            if (type == KirinVariableType.BOOL)
            {
                return(false);
            }
            if (type == KirinVariableType.STRING_ARRAY)
            {
                return(new Dictionary <int, string>());
            }
            if (type == KirinVariableType.NUMBER_ARRAY)
            {
                return(new Dictionary <int, double>());
            }
            if (type == KirinVariableType.BOOL_ARRAY)
            {
                return(new Dictionary <int, bool>());
            }

            throw new FiMException("Invalid type");
        }
Пример #5
0
 public void ForceType(KirinVariableType type)
 {
     if (this.ForcedType != null)
     {
         return;
     }
     this.ForcedType = type;
 }
Пример #6
0
 public static bool IsTypeArray(KirinVariableType type)
 {
     if (type == KirinVariableType.STRING_ARRAY)
     {
         return(true);
     }
     if (type == KirinVariableType.NUMBER_ARRAY)
     {
         return(true);
     }
     if (type == KirinVariableType.BOOL_ARRAY)
     {
         return(true);
     }
     return(false);
 }
Пример #7
0
        public static bool IsTypeOfArray(KirinVariableType type, KirinArrayType arrayType)
        {
            KirinVariableType aType = KirinVariableType.UNKNOWN;

            if (arrayType == KirinArrayType.STRING)
            {
                aType = KirinVariableType.STRING;
            }
            else if (arrayType == KirinArrayType.NUMBER)
            {
                aType = KirinVariableType.NUMBER;
            }
            else if (arrayType == KirinArrayType.BOOL)
            {
                aType = KirinVariableType.BOOL;
            }
            return(type == aType);
        }
Пример #8
0
        private static string KirinTypeAsJavascriptType(KirinVariableType type)
        {
            switch (type)
            {
            case KirinVariableType.STRING: return("string");

            case KirinVariableType.NUMBER: return("number");

            case KirinVariableType.BOOL: return("boolean");

            case KirinVariableType.CHAR: return("string");

            case KirinVariableType.BOOL_ARRAY: return("boolean[]");

            case KirinVariableType.STRING_ARRAY: return("string[]");

            case KirinVariableType.NUMBER_ARRAY: return("number[]");
            }

            return(string.Empty);
        }
Пример #9
0
        /// <summary>
        /// Evaluates raw FiM++ string into a value
        /// </summary>
        public static object Evaluate(
            FiMClass reportClass,
            string evaluatable,
            out KirinVariableType returnedType,
            KirinVariableType?expectedType = null
            )
        {
            returnedType = KirinVariableType.UNKNOWN;

            // Nothing
            if (evaluatable == "nothing" && expectedType != null)
            {
                returnedType = (KirinVariableType)expectedType;
                return(FiMHelper.GetDefaultValue(returnedType));
            }

            // Calling an existing variable
            if (reportClass.GetVariable(evaluatable) != null)
            {
                var variable = reportClass.GetVariable(evaluatable);
                returnedType = variable.Type;
                return(variable.Value);
            }

            // Calling an existing method
            if (reportClass.GetParagraphLazy(evaluatable) != null)
            {
                KirinValue[] args  = null;
                string       pName = evaluatable;

                if (pName.Contains(KirinFunctionCall.FunctionParam))
                {
                    int pIndex = pName.IndexOf(KirinFunctionCall.FunctionParam);
                    pName = pName.Substring(0, pIndex);
                    args  = KirinFunctionCall.ParseCallArguments(
                        evaluatable.Substring(pName.Length + KirinFunctionCall.FunctionParam.Length), reportClass
                        ).ToArray();
                }

                var paragraph = reportClass.GetParagraph(pName);
                if (paragraph == null)
                {
                    throw new FiMException("Paragraph " + pName + " not found");
                }

                if (paragraph.ReturnType == KirinVariableType.UNKNOWN)
                {
                    throw new FiMException("Paragraph returns nothing");
                }
                returnedType = paragraph.ReturnType;
                return(paragraph.Execute(args));
            }

            // Array
            if (expectedType != null && FiMHelper.IsTypeArray((KirinVariableType)expectedType))
            {
                System.Collections.IDictionary dict = null;
                var args = KirinFunctionCall.ParseCallArguments(evaluatable, reportClass);

                if (!FiMHelper.IsTypeOfArray(args[0].Type, (KirinArrayType)expectedType))
                {
                    throw new FiMException("Invalid list value type");
                }
                if (!args.All(a => a.Type == args[0].Type))
                {
                    throw new FiMException("Unidentical list value type");
                }

                int i = 1;
                if (expectedType == KirinVariableType.STRING_ARRAY)
                {
                    dict = new Dictionary <int, string>();
                    args.ForEach(kv => dict.Add(i++, Convert.ToString(kv.Value)));
                }
                else if (expectedType == KirinVariableType.NUMBER_ARRAY)
                {
                    dict = new Dictionary <int, double>();
                    args.ForEach(kv => dict.Add(i++, Convert.ToDouble(kv.Value)));
                }
                else if (expectedType == KirinVariableType.BOOL_ARRAY)
                {
                    dict = new Dictionary <int, bool>();
                    args.ForEach(kv => dict.Add(i++, Convert.ToBoolean(kv.Value)));
                }

                returnedType = (KirinVariableType)expectedType;
                return(dict);
            }

            // Array index
            if (FiMHelper.ArrayIndex.IsArrayIndex(evaluatable, reportClass))
            {
                var match = FiMHelper.ArrayIndex.GetArrayIndex(evaluatable, reportClass);

                var varIndex = new KirinValue(match.RawIndex, reportClass);
                if (varIndex.Type != KirinVariableType.NUMBER)
                {
                    throw new FiMException("Invalid index value");
                }
                int index = Convert.ToInt32(varIndex.Value);

                string strVar = match.RawVariable;
                if (!reportClass.Variables.Has(strVar))
                {
                    throw new FiMException("Variable " + strVar + " does not exist");
                }
                var variable = reportClass.Variables.Get(strVar);
                if (!FiMHelper.IsTypeArray(variable.Type) && variable.Type != KirinVariableType.STRING)
                {
                    throw new FiMException("Cannot index a non-array variable");
                }

                if (variable.Type == KirinVariableType.STRING)
                {
                    returnedType = KirinVariableType.CHAR;
                    return(Convert.ToString(variable.Value)[index - 1]);
                }

                var dict = variable.Value as System.Collections.IDictionary;
                if (variable.Type == KirinVariableType.STRING_ARRAY)
                {
                    returnedType = KirinVariableType.STRING;
                    return(Convert.ToString(dict[index]));
                }
                if (variable.Type == KirinVariableType.BOOL_ARRAY)
                {
                    returnedType = KirinVariableType.BOOL;
                    return(Convert.ToBoolean(dict[index]));
                }
                if (variable.Type == KirinVariableType.NUMBER_ARRAY)
                {
                    returnedType = KirinVariableType.NUMBER;
                    return(Convert.ToDouble(dict[index]));
                }
            }

            // Arithmetic
            if (KirinArithmetic.IsArithmetic(evaluatable, out var arithmeticResult))
            {
                var arithmetic = new KirinArithmetic(arithmeticResult);
                var value      = arithmetic.GetValue(reportClass);
                returnedType = FiMHelper.AsVariableType(value.GetType());
                return(value);
            }

            // Conditional
            if (KirinConditional.IsConditional(evaluatable, out var conditionalResult))
            {
                var conditional = new KirinConditional(conditionalResult);
                returnedType = KirinVariableType.BOOL;
                return(conditional.GetValue(reportClass));
            }

            throw new FiMException("Cannot evaluate " + evaluatable);
        }
Пример #10
0
 public static string AsNamedString(this KirinVariableType type)
 {
     return(Enum.GetName(typeof(KirinVariableType), type));
 }