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); }
// 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 }