Пример #1
0
        public static KirinIfStatement ParseNodes(
            KirinIfStatementStart startNode,
            KirinNode[] nodes,
            KirinIfStatementEnd endNode,
            string content)
        {
            var statement = new KirinIfStatement(-1, -1);

            string           currentCondition = startNode.RawCondition;
            KirinNode        conditionNode    = startNode;
            List <KirinNode> subStatement     = new List <KirinNode>();

            foreach (var subnode in nodes)
            {
                if (subnode.NodeType != "KirinElseIfStatement")
                {
                    subStatement.Add(subnode);
                }
                else
                {
                    var conditionStatement = FiMLexer.ParseStatement(subStatement.ToArray(), content);
                    try
                    {
                        statement.AddCondition(currentCondition, conditionStatement);
                    }
                    catch (FiMException ex)
                    {
                        throw new Exception(ex.Message + " at line " +
                                            FiMHelper.GetIndexPair(content, conditionNode.Start).Line);
                    }


                    var elseIfNode = subnode as KirinElseIfStatement;
                    currentCondition = elseIfNode.RawCondition;
                    conditionNode    = subnode;

                    subStatement.Clear();
                }
            }

            if (subStatement.Count > 0)
            {
                var conditionStatement = FiMLexer.ParseStatement(subStatement.ToArray(), content);
                try
                {
                    statement.AddCondition(currentCondition, conditionStatement);
                }
                catch (FiMException ex)
                {
                    throw new Exception(ex.Message + " at line " +
                                        FiMHelper.GetIndexPair(content, conditionNode.Start).Line);
                }
            }

            statement.SetComplete(startNode.Start, endNode.Start + endNode.Length);

            if (statement.Count == 0)
            {
                throw new FiMException("If Statement has empty conditions");
            }

            return(statement);
        }
Пример #2
0
        public virtual object Execute(FiMClass reportClass)
        {
            uint   localVariables = 0;
            object result         = null;

            foreach (var node in this.Body)
            {
                if (!node.GetType().IsSubclassOf(typeof(KirinExecutableNode)))
                {
                    if (node.GetType().IsSubclassOf(typeof(KirinNode)) || node.GetType() == typeof(KirinNode))
                    {
                        var no = (KirinNode)node;
                        throw new FiMException($"Paragraph contains a non-KirinExecutable node at line ${FiMHelper.GetIndexPair(reportClass.Report.ReportString, node.Start).Line}");
                    }
                    else
                    {
                        throw new FiMException($"Paragraph contains a non-KirinExecutable node ('{node.NodeType}')");
                    }
                }
                var n = (KirinExecutableNode)node;

                if (n.NodeType == "KirinVariableDeclaration")
                {
                    localVariables++;
                }

                object r;
#if HIDE_ERROR
                r = n.Execute(reportClass);
#else
                try
                {
                    r = n.Execute(reportClass);
                }
                catch (FiMException err)
                {
                    throw new Exception(err.Message + " at line " + FiMHelper.GetIndexPair(reportClass.Report.ReportString, n.Start).Line);
                }
#endif
                if (r != null)
                {
                    reportClass.Variables.Pop(count: localVariables);
                    return(r);
                }

                if (n.NodeType == "KirinReturn")
                {
                    result = ((KirinValue)r).Value;
                    break;
                }
            }

            reportClass.Variables.Pop(count: localVariables);
            return(result);
        }
Пример #3
0
        public override object Execute(FiMClass reportClass)
        {
            var variable = reportClass.GetVariable(this.LeftOp);

            if (variable == null)
            {
                throw new FiMException("Variable " + this.LeftOp + " does not exist");
            }
            if (!FiMHelper.IsTypeArray(variable.Type) && variable.Type != KirinVariableType.STRING)
            {
                throw new FiMException("Variable " + this.LeftOp + " is not an array");
            }

            var kIndex = new KirinValue(this.RawIndex, reportClass);

            if (kIndex.Type != KirinVariableType.NUMBER)
            {
                throw new FiMException("Invalid index " + kIndex.Value);
            }
            var iValue = Convert.ToInt32(kIndex.Value);

            var value = new KirinValue(this.RightOp, reportClass);

            if (variable.Type == KirinVariableType.STRING)
            {
                if (value.Type != KirinVariableType.CHAR)
                {
                    throw new FiMException("Invalid array modify value");
                }

                var sb = new StringBuilder(variable.Value as string);
                sb[iValue]     = (char)variable.Value;
                variable.Value = sb.ToString();
            }
            else
            {
                if (!FiMHelper.IsTypeOfArray(value.Type, (KirinArrayType)variable.Type))
                {
                    throw new FiMException("Invalid array modify value");
                }

                dynamic dict;
                int     index = Convert.ToInt32(kIndex.Value);
                if (variable.Type == KirinVariableType.STRING_ARRAY)
                {
                    dict        = variable.Value as Dictionary <int, string>;
                    dict[index] = Convert.ToString(value.Value);
                }
                else if (variable.Type == KirinVariableType.NUMBER_ARRAY)
                {
                    dict        = variable.Value as Dictionary <int, double>;
                    dict[index] = Convert.ToDouble(value.Value);
                }
                else if (variable.Type == KirinVariableType.BOOL_ARRAY)
                {
                    dict        = variable.Value as Dictionary <int, bool>;
                    dict[index] = Convert.ToBoolean(value.Value);
                }
            }

            ;
            return(null);
        }
Пример #4
0
        private static string SanitizeValue(string value, JavascriptContainer container, KirinVariableType?expectedType = null)
        {
            var eType = FiMHelper.DeclarationType.Determine(" " + value, out string eKeyword, strict: false);

            if (eType != KirinVariableType.UNKNOWN)
            {
                value        = value.Substring(eKeyword.Length);
                expectedType = eType;
            }

            // Nothing
            if ((value == null || value == "nothing") && expectedType != null)
            {
                return(DefaultValue((KirinVariableType)expectedType));
            }

            if (KirinLiteral.TryParse(value, out object val))
            {
                if (val.GetType() == typeof(bool))
                {
                    return((bool)val == true ? "true" : "false");
                }
                return(value);
            }

            // Calling an existing method
            if (container.report.GetParagraphLazy(value) != null)
            {
                string args  = "";
                string pName = value;

                if (pName.Contains(KirinFunctionCall.FunctionParam))
                {
                    int pIndex = pName.IndexOf(KirinFunctionCall.FunctionParam);
                    pName = pName.Substring(0, pIndex);
                    args  = string.Join(", ",
                                        value
                                        .Substring(pName.Length + KirinFunctionCall.FunctionParam.Length)
                                        .Split(new string[] { " and " }, StringSplitOptions.None)
                                        .Select(v => SanitizeValue(v, container))
                                        );
                }

                if (container.internalFunctions.ContainsKey(pName))
                {
                    return($"{ container.internalFunctions[pName] }({ args })");
                }
                return($"this.{ SanitizeName(pName, container) }({ args })");
            }

            // Array
            if (expectedType != null && FiMHelper.IsTypeArray((KirinVariableType)expectedType))
            {
                string args = string.Join(", ",
                                          value
                                          .Split(new string[] { " and " }, StringSplitOptions.None)
                                          .Select(v => SanitizeValue(v, container))
                                          );

                return($"[, { args }]");
            }

            // Array index
            if (IsArrayIndex(value))
            {
                var match = GetArrayIndex(value);

                var index    = SanitizeValue(match.RawIndex, container);
                var variable = SanitizeValue(match.RawVariable, container);

                return($"{ variable }[ fim_index({ variable }, {index}) ]");
            }

            // Arithmetic
            if (KirinArithmetic.IsArithmetic(value, out var arithmeticResult))
            {
                return(ParseArithmeticNodes(arithmeticResult, container));
            }

            // Conditional
            if (KirinConditional.IsConditional(value, out var conditionalResult))
            {
                return(ParseConditionalNodes(conditionalResult, container));
            }

            // Calling an existing variable (hopefully)
            return(SanitizeName(value, container));
        }