Пример #1
0
        public dynamic RunParagraph(string paragraphName, FiMObject paramObject = null)
        {
            if (!Paragraphs.ContainsKey(paragraphName))
            {
                throw new Exception("Invalid Paragraph name");
            }

            FiMParagraph paragraph = Paragraphs[paragraphName];

            // Empty function
            if (paragraph.Lines.Count() == 0)
            {
                return(null);
            }

            List <string> paragraphLines = new List <string>();

            paragraphLines.AddRange(paragraph.Lines);

            for (int i = 0; i < paragraphLines.Count(); i++)
            {
                if (!string.IsNullOrWhiteSpace(paragraphLines[i]) && !Regex.IsMatch(paragraphLines[i], @"( |\t)*(P\.)(P\.)*S\.($| )"))
                {
                    string nl = paragraphLines[i];
                    if (nl.StartsWith("    "))
                    {
                        nl = nl.Remove(0, "    ".Length);
                    }
                    else if (nl.StartsWith("\t"))
                    {
                        nl = nl.Remove(0, 1);
                    }
                    else
                    {
                        throw new Exception("Invalid indentation at line '" + paragraph.FirstLineIndex + i + "'");
                    }

                    paragraphLines[i] = nl;
                }
            }

            //
            Dictionary <string, FiMObject> LocalVariables = new Dictionary <string, FiMObject>();

            if (paragraph.ParameterName != null)
            {
                LocalVariables.Add(paragraph.ParameterName, paramObject);
            }

            int lineIndex = 1;
            int skipTo    = -1;

            string[] pLArray = paragraphLines.ToArray();
            foreach (string line in paragraphLines)
            {
                if (lineIndex <= skipTo)
                {
                    lineIndex++;
                    continue;
                }

                //Console.WriteLine(line);

                if (!string.IsNullOrWhiteSpace(line) && !Regex.IsMatch(line, @"( |\t)*(P\.)(P\.)*S\.($| )"))
                {
                    NetFIMMethods.FiMMethodOut method;
                    try {
                        method = NetFIMMethods.ScanMethod(this, line, pLArray, paragraph.FirstLineIndex + lineIndex + 1, lineIndex, paragraph, variables: NetFIMMethods.MergeLocalAndGlobalVariables(GlobalVariables, LocalVariables), paragraphs: Paragraphs);
                    }
                    catch (Exception e) { throw e; }

                    //

                    switch (method.methodType)
                    {
                    case "WRITE-RUN":
                    {
                        if (!Paragraphs.ContainsKey(method.outArgs["Method Name"]))
                        {
                            throw new Exception("[" + paragraph.FirstLineIndex + lineIndex + "] Paragraph '" + method.outArgs["Method Name"] + "' doesn't exist");
                        }

                        if (method.outArgs["doWrite"] == true)
                        {
                            NetFIMMethods.WriteToScreen(RunParagraph(method.outArgs["Method Name"], method.outArgs["Parameter"]));
                        }
                        else
                        {
                            RunParagraph(method.outArgs["Method Name"], method.outArgs["Parameter"]);
                        }
                    }
                    break;

                    case "MAKE-VARIABLE":
                    {
                        LocalVariables.Add(method.outArgs["Variable Name"], method.outArgs["Variable"]);
                    }
                    break;

                    case "MODIFY-ARRAY":
                    {
                        // In the case of Paragraph ScanMethod, we either put it on the Global or Local list.
                        if (GlobalVariables.ContainsKey(method.outArgs["Variable Name"]))
                        {
                            var ol = GlobalVariables[method.outArgs["Variable Name"]].GetActualValue();
                            ol[method.outArgs["Slot"]] = method.outArgs["New Value"];
                            GlobalVariables[method.outArgs["Variable Name"]].Value = (object)ol;
                        }
                        else
                        {
                            var ol = LocalVariables[method.outArgs["Variable Name"]].GetActualValue();
                            ol[method.outArgs["Slot"]] = method.outArgs["New Value"];
                            LocalVariables[method.outArgs["Variable Name"]].Value = (object)ol;
                        }
                    }
                    break;

                    case "MODIFY-VARIABLE":
                    {
                        if (GlobalVariables.ContainsKey(method.outArgs["Variable Name"]))
                        {
                            GlobalVariables[method.outArgs["Variable Name"]] = method.outArgs["New Value"];
                        }
                        else
                        {
                            LocalVariables[method.outArgs["Variable Name"]] = method.outArgs["New Value"];
                        }
                    }
                    break;

                    case "VARIABLE-INCREMENT":
                    {
                        if (GlobalVariables.ContainsKey(method.outArgs["Variable Name"]))
                        {
                            float oldValue = GlobalVariables[method.outArgs["Variable Name"]].GetActualValue();
                            oldValue++;
                            GlobalVariables[method.outArgs["Variable Name"]].Value = (object)oldValue;
                        }
                        else
                        {
                            float oldValue = LocalVariables[method.outArgs["Variable Name"]].GetActualValue();
                            oldValue++;
                            LocalVariables[method.outArgs["Variable Name"]].Value = (object)oldValue;
                        }
                    }
                    break;

                    case "VARIABLE-DECREMENT":
                    {
                        if (GlobalVariables.ContainsKey(method.outArgs["Variable Name"]))
                        {
                            float oldValue = GlobalVariables[method.outArgs["Variable Name"]].GetActualValue();
                            oldValue--;
                            GlobalVariables[method.outArgs["Variable Name"]].Value = (object)oldValue;
                        }
                        else
                        {
                            float oldValue = LocalVariables[method.outArgs["Variable Name"]].GetActualValue();
                            oldValue--;
                            LocalVariables[method.outArgs["Variable Name"]].Value = (object)oldValue;
                        }
                    }
                    break;

                    case "WHILE":
                    {
                        skipTo = lineIndex + method.outArgs["Skip"] + 1;
                        //
                        Dictionary <string, FiMObject> changed = method.outArgs["Changed Variables"];

                        if (changed.Count() > 0)
                        {
                            changed.Keys.ToList().ForEach(x =>
                                {
                                    FiMObject obj = changed[x];

                                    if (GlobalVariables.ContainsKey(x))
                                    {
                                        GlobalVariables[x] = obj;
                                    }
                                    else
                                    {
                                        LocalVariables[x] = obj;
                                    }
                                });
                        }

                        if (method.outArgs.ContainsKey("Returned Variable"))
                        {
                            return(method.outArgs["Returned Variable"]);
                        }
                    }
                    break;

                    case "IF-ELSE":
                    {
                        skipTo = lineIndex + method.outArgs["Skip"] + 1;
                        //
                        if (method.outArgs.ContainsKey("Statement"))
                        {
                            NetFIMMethods.FiMStatement statement = method.outArgs["Statement"];
                            statement.changedVariables.Keys.ToList().ForEach(x =>
                                {
                                    FiMObject obj = statement.changedVariables[x];

                                    if (GlobalVariables.ContainsKey(x))
                                    {
                                        GlobalVariables[x] = obj;
                                    }
                                    else
                                    {
                                        LocalVariables[x] = obj;
                                    }
                                });

                            if (statement.hasReturned)
                            {
                                return(statement.returnedObject);
                            }
                        }
                    }
                    break;

                    case "RETURN":
                        return(method.outArgs["Variable"]);

                    case "WRITE-WRITE":
                    default:
                        break;
                    }
                }

                lineIndex++;
            }

            return(null);
        }
Пример #2
0
        // READ FILE CONTENT
        public void ReadReport(string path)
        {
            Report = new FiMReport();

            // CHECKS
            if (!Directory.Exists(path))
            {
                throw new FiMException("Directory doesn't exist!");
            }
            if (!File.Exists(path + "/main.fpp"))
            {
                throw new FiMException("main.fpp doesn't exist!");
            }
            //

            List <string> lines = File.ReadAllLines(path + "/main.fpp").ToList();

            #region Read main.fpp File

            try
            {
                lines = NetFIMMethods.SanitizeReport(lines);
            }
            catch (Exception e)
            {
                throw e;
            }

            // lets be strict on the report
            if (!lines.First().StartsWith(NetFIMGlobal.ReportStart))
            {
                throw new Exception("Invalid Report beginning");
            }
            else
            {
                Report.ReportName = lines.First().Remove(0, NetFIMGlobal.ReportStart.Length);
            }

            lines = NetFIMMethods.RemoveLinesAfterReportEnd(lines);
            if (!lines.Last().StartsWith(NetFIMGlobal.ReportEnd))
            {
                throw new Exception("Invalid Report ending");
            }
            else
            {
                Report.Writer = lines.Last().Remove(0, NetFIMGlobal.ReportEnd.Length);
            }

            // Grab global variables
            bool gv_inside = false;
            for (int i = 0; i < lines.Count; i++)
            {
                string line = lines[i];
                if (line.Replace("Today ", "").StartsWith("I learned "))
                {
                    gv_inside = true;
                }
                if (line.StartsWith("That's all about "))
                {
                    gv_inside = false;
                }

                if (!gv_inside)
                {
                    if (line.StartsWith(NetFIMGlobal.Keywords.Method_Declare))
                    {
                        string    variableName;
                        FiMObject obj;
                        try { obj = NetFIMMethods.InterpretVariableDecleration(line, out variableName, Report.GlobalVariables); }
                        catch (Exception e) { throw new Exception("[" + i + "] " + e.Message); }

                        if (Report.GlobalVariables.ContainsKey(variableName))
                        {
                            throw new Exception("A global variable with the name '" + variableName + "' already exists.");
                        }

                        Report.GlobalVariables.Add(variableName, obj);
                    }
                }
            }

            // Grab functions
            for (int i = 0; i < lines.Count(); i++)
            {
                string line = lines[i];
                if (line.Replace("Today ", "").StartsWith("I learned "))
                {
                    string funcName = line.Replace("Today ", "").Replace("I learned ", "");

                    FiMObjectTypes funcType = FiMObjectTypes.UNKNOWN;
                    FiMObjectTypes retrType = FiMObjectTypes.UNKNOWN;
                    string         retrName = null;

                    if (NetFIMGlobal.Keywords.Method_Return.Any(x => funcName.Contains(x)) || funcName.Contains(NetFIMGlobal.Keywords.Method_Parameter))
                    {
                        if (NetFIMGlobal.Keywords.Method_Return.Any(x => funcName.Contains(x)))
                        {
                            string r_ph = NetFIMGlobal.Keywords.Method_Return.Where(x => funcName.Contains(x)).FirstOrDefault();
                            string r_ap;
                            try
                            {
                                funcType = NetFIMMethods.GetVariableInitializerType(funcName.Split(new string[] { r_ph }, StringSplitOptions.None)[1].TrimStart(' ').TrimEnd(' '), out r_ap);
                            }
                            catch (Exception ex) { throw new Exception("Invalid Paragraph return - " + ex); }
                            //
                            funcName = funcName.Replace(" " + r_ph + " " + r_ap, "");
                        }
                        if (funcName.Contains(NetFIMGlobal.Keywords.Method_Parameter))
                        {
                            string p_ap;
                            try
                            {
                                retrType = NetFIMMethods.GetVariableInitializerType(funcName.Split(new string[] { NetFIMGlobal.Keywords.Method_Parameter }, StringSplitOptions.None)[1].TrimStart(' ').TrimEnd(' '), out p_ap);
                                retrName = funcName.Split(new string[] { NetFIMGlobal.Keywords.Method_Parameter + " " + p_ap }, StringSplitOptions.None)[1].TrimStart(' ');
                            }
                            catch { throw new Exception("Invalid Paragraph parameter"); }
                            //
                            funcName = funcName.Split(new string[] { NetFIMGlobal.Keywords.Method_Parameter + " " + p_ap }, StringSplitOptions.None)[0].TrimEnd(' ');
                        }
                    }

                    if (NetFIMGlobal.KeywordsList.Any(x => funcName.Contains(x)))
                    {
                        throw new Exception("Paragraph name '" + funcName + "' has broken one or more restrictions");
                    }

                    List <string> iLines = new List <string>();

                    int  il   = i + 1;
                    bool ibrk = false;
                    while (!ibrk)
                    {
                        string inn = lines[il];

                        if (inn.StartsWith("That's all about "))
                        {
                            // might also want to do the check here
                            if (inn.Substring("That's all about ".Length) != funcName)
                            {
                                throw new Exception("Paragraph '" + funcName + "' doesn't end with the same name");
                            }
                            ibrk = true;
                        }
                        else
                        {
                            iLines.Add(inn);
                        }

                        il++;
                    }

                    if (!ibrk)
                    {
                        throw new Exception("Paragraph '" + funcName + "' doesn't end properly");
                    }

                    FiMParagraph paragraph = new FiMParagraph(iLines, i, line.StartsWith("Today "), returnType: funcType, paramType: retrType, paramName: retrName);

                    if (Report.Paragraphs.Any(x => x.Value.isMainFunction == true && line.StartsWith("Today ")))
                    {
                        throw new Exception("Multiple main paragraphs found");
                    }

                    Report.Paragraphs.Add(funcName, paragraph);

                    i = il;
                }
            }

            #endregion
        }