public List<String> ToJavascript(GPCmd cmd, List<JSLine> preJSLines) { List<String> rv = new List<String>(); List<JSLine> wjs = new List<JSLine>(); // Handle LOOPs preJSLines.Where(x => x.Keyword == EKeyword.Loop && x.State == EKeywordState.Begin).ToList().ForEach(x => x.Output = "/* LOOP */"); preJSLines.Where(x => x.Keyword == EKeyword.Loop && x.State == EKeywordState.End) .ToList() .ForEach(x => x.Output = GPProcessVarName + "._instLocal = " + preJSLines.IndexOf( preJSLines.Where(y => y.idControl == x.idControl && y.Keyword == x.Keyword && y.State == EKeywordState.Begin ).Single() ) + "; /* LOOP END */" ); // Handle REPEATs preJSLines.Where(x => x.Keyword == EKeyword.Repeat && x.State == EKeywordState.Begin).ToList().ForEach(x => x.Output = "/* REPEAT */"); preJSLines.Where(x => x.Keyword == EKeyword.Repeat && x.State == EKeywordState.End) .ToList() .ForEach(x => x.Output = x.Output = "if ( !(" + ParseCondition(x.InnerCode) + ") ) { " + GPProcessVarName + "._instLocal = " + preJSLines.IndexOf( preJSLines.Where(y => y.idControl == x.idControl && y.Keyword == x.Keyword && y.State == EKeywordState.Begin ).Single() ) + " }; /* UNTIL */" ); // Handle WHILEs preJSLines.Where(x => x.Keyword == EKeyword.While && x.State == EKeywordState.Begin).ToList().ForEach(x => x.Output = "/* WHILE */"); preJSLines.Where(x => x.Keyword == EKeyword.While && x.State == EKeywordState.End) .ToList() .ForEach(x => x.Output = x.Output = "if ( (" + ParseCondition(x.InnerCode) + ") ) { " + GPProcessVarName + "._instLocal = " + preJSLines.IndexOf( preJSLines.Where(y => y.idControl == x.idControl && y.Keyword == x.Keyword && y.State == EKeywordState.Begin ).Single() ) + " }; /* WHILE END */" ); // Handle FROMs preJSLines.Where(x => x.Keyword == EKeyword.From && x.State == EKeywordState.End) .ToList() .ForEach(x => x.Output = GPProcessVarName + "._instLocal = " + (preJSLines.IndexOf( preJSLines.Where(y => y.idControl == x.idControl && y.Keyword == x.Keyword && y.State == EKeywordState.Initialize ).Single() ) + 1 ) + "; /* FROM END */" ); preJSLines.Where(x => x.Keyword == EKeyword.From && x.State == EKeywordState.Initialize) .ToList() .ForEach(x => x.Output = x.InnerCode.Substring(0, x.InnerCode.ToUpperInvariant().IndexOf(" TO")) ); preJSLines.Where(x => x.Keyword == EKeyword.From && x.State == EKeywordState.Begin) .ToList() .ForEach(x => x.Output = ParseFrom(x.InnerCode) + (preJSLines.IndexOf( preJSLines.Where(y => y.idControl == x.idControl && y.Keyword == EKeyword.From && y.State == EKeywordState.End ).Single() ) + 1 ) + " }" ); // Handle FORs preJSLines.Where(x => x.Keyword == EKeyword.For && x.State == EKeywordState.End) .ToList() .ForEach(x => x.Output = GPProcessVarName + "._instLocal = " + (preJSLines.IndexOf( preJSLines.Where(y => y.idControl == x.idControl && y.Keyword == x.Keyword && y.State == EKeywordState.Initialize ).Single() ) + 1 ) + "; /* FOR END */" ); preJSLines.Where(x => x.Keyword == EKeyword.For && x.State == EKeywordState.Initialize) .ToList() .ForEach(x => x.Output = x.InnerCode.Substring(0, x.InnerCode.ToUpperInvariant().IndexOf(";")) ); preJSLines.Where(x => x.Keyword == EKeyword.For && x.State == EKeywordState.Begin) .ToList() .ForEach(x => x.Output = ParseFor(x.InnerCode) + (preJSLines.IndexOf( preJSLines.Where(y => y.idControl == x.idControl && y.Keyword == EKeyword.For && y.State == EKeywordState.End ).Single() ) + 1 ) + " }" ); // Handle RETURNs preJSLines.Where(x => x.Keyword == EKeyword.Return).ToList().ForEach(x => x.Output = GPProcessVarName + "._instLocal = -1; return " + x.InnerCode + ";" ); // Handle BREAKs preJSLines.Where(x => x.Keyword == EKeyword.Break).ToList().ForEach(x => x.Output = GPProcessVarName + "._instLocal = " + ( preJSLines.IndexOf( preJSLines.Where(y => y.idControl == x.idControl && (y.Keyword == EKeyword.For || y.Keyword == EKeyword.From || y.Keyword == EKeyword.Loop || y.Keyword == EKeyword.Repeat || y.Keyword == EKeyword.While) && y.State == EKeywordState.End ).Single() ) + 1 ) + ";" ); // Handle IFs // TODO: Implement different logic, for ELSEs and such preJSLines.Where(x => x.Keyword == EKeyword.If && x.State == EKeywordState.End).ToList().ForEach(x => x.Output = "/* ENDIF */"); preJSLines.Where(x => x.Keyword == EKeyword.If && x.State == EKeywordState.Condition).ToList().ForEach(x => x.Output = "/* IF -> ELSE */"); preJSLines.Where(x => x.Keyword == EKeyword.If && x.State == EKeywordState.EndElse) .ToList() .ForEach(x => x.Output = "/* END BEFORE ELSE */ " + GPProcessVarName + "._instLocal = " + (preJSLines.IndexOf( preJSLines.Where(y => y.idControl == x.idControl && y.Keyword == EKeyword.If && y.State == EKeywordState.End ).First() ) + 1 ) + "" ); preJSLines.Where(x => x.Keyword == EKeyword.If && x.State == EKeywordState.Begin) .ToList() .ForEach(x => x.Output = "if ( !(" + ParseCondition(x.InnerCode) + ") ) { " + GPProcessVarName + "._instLocal = " + (preJSLines.IndexOf( preJSLines.Where(y => y.idControl == x.idControl && y.Keyword == EKeyword.If && (y.State == EKeywordState.Condition || y.State == EKeywordState.End) ).First() ) + 1 ) + " }" ); //////////////////////////////////////////////////////////// // CONVERT //////////////////////////////////////////////////////////// if(GlobalVars.Count > 0) preJSLines.ForEach(x => x.Output = FindVariables(x.Output, GPEngineVarName + ".aGlobals.", GlobalVars.Select(y => y.Key).OrderBy(y => y).ToList())); if (cmd.Variables.Count > 0) preJSLines.ForEach(x => x.Output = FindVariables(x.Output, GPProcessVarName + ".", cmd.Variables.Keys.OrderBy(y => y).ToList())); if (cmd.InternalVariables.Count > 0) preJSLines.ForEach(x => x.Output = FindVariables(x.Output, GPProcessVarName + ".", cmd.InternalVariables.Keys.OrderBy(y => y).ToList())); if (LocalVars.Count > 0) preJSLines.ForEach(x => x.Output = FindVariables(x.Output, GPProcessVarName + ".", LocalVars.Select(y => y.Key).OrderBy(y => y).ToList())); if (!String.IsNullOrEmpty(cmd.Arguments)) foreach (String v in cmd.Arguments.Split(',')) { String arg = v.Trim(); if (GlobalVars.Where(x => x.Key == arg).Count() == 0) if (GlobalLocalVars.Where(x => x.Key == arg).Count() == 0) if (cmd.Variables.Where(x => x.Key == arg).Count() == 0) if (cmd.InternalVariables.Where(x => x.Key == arg).Count() == 0) cmd.InternalVariables.Add(arg, "(typeof " + arg + " === 'undefined') ? null : " + arg); } foreach (JSLine l in preJSLines) if (l.Keyword == EKeyword.For) if (l.State == EKeywordState.Initialize) if (!l.Output.ToLowerInvariant().Trim().StartsWith("_gpp")) if (!l.Output.ToLowerInvariant().Trim().StartsWith("var")) cmd.InternalVariables.Add(l.Output.Trim().Substring(0, l.Output.IndexOf('=')).Trim(), l.Output.Substring(l.Output.IndexOf("=") + 1)); if (cmd.InternalVariables.Count > 0) preJSLines.ForEach(x => x.Output = FindVariables(x.Output, GPProcessVarName + ".", cmd.InternalVariables.Keys.OrderBy(y => y).ToList())); preJSLines.ForEach(x => x.Output = Sanitize(x.Output)); preJSLines.ForEach(x => x.Output = FindCode(x.Output, SanitizeFunctions)); preJSLines.ForEach(x => x.Output = FindResources(x.Output)); int i = 0; foreach (String o in preJSLines.Select(x => x.Output).ToList()) { string finalLine = o ?? ""; if (!finalLine.EndsWith(";") && !finalLine.EndsWith("/")) finalLine += ";"; foreach (String p in ProcessList) if (finalLine.ToLowerInvariant().Trim().Contains(p + "(") || finalLine.ToLowerInvariant().Trim().Contains(p + " (")) { finalLine = GPEngineVarName + ".SetParent(_gpp); " + finalLine; break; } foreach (String fn in new String[] { "let_me_alone", "get_dist", "get_angle" }) if (finalLine.ToLowerInvariant().Trim().Contains(fn + "(") || finalLine.ToLowerInvariant().Trim().Contains(fn + " (")) { finalLine = GPEngineVarName + ".SetCaller(_gpp); " + finalLine; break; } rv.Add(" " + GPProcessVarName + "._code[" + i + "] = function() { " + finalLine + " };"); i++; } return rv; }
public GPCmd Compile(List<String> lines) { GPParser p = new GPParser(); List<String> Cmd = p.Sanitize(lines); GPCmd Root = new GPCmd() { IsKeyword = false, }; GPCmd curCmd = Root; GPCmd oldCmd = null; bool IsGlobals = false; bool IsLocals = false; bool IsConstants = false; bool IsAddingVariables = false; foreach (String sCommand in Cmd) { String raw = sCommand; String cmd = sCommand.ToLowerInvariant().Trim(); if (cmd.EndsWith(";")) { cmd = cmd.Substring(0, cmd.Length - 1); raw = raw.Substring(0, raw.Length - 1); } String sKeyword = cmd; if (sKeyword.Contains(' ')) sKeyword = sKeyword.Substring(0, sKeyword.IndexOf(' ')); if (sKeyword.Contains('(')) sKeyword = sKeyword.Substring(0, sKeyword.IndexOf('(')); GPCmd d2cmd = new GPCmd(); String sArguments = String.Empty; String sName = raw.Substring(sKeyword.Length).Trim(); if (raw.Contains('(') && raw.Contains(')')) { sArguments = raw.Substring(raw.IndexOf('(') + 1); sArguments = sArguments.Substring(0, sArguments.LastIndexOf(')')); sName = sName.Substring(0, sName.IndexOf('(')); } if (Keywords.Contains(sKeyword)) { switch (sKeyword) { case "program": controlId.Add(new KeyValuePair<Guid, EKeyword>(Guid.NewGuid(), EKeyword.Program)); curCmd.Commands.Add(new GPCmd() { Parent = curCmd, IsKeyword = true, Keyword = EKeyword.Program, Name = sName }); d2cmd = curCmd.Commands.Last(); oldCmd = curCmd; curCmd = d2cmd; break; case "process": // If curCmd == null - extra end without opening if/loop/etc. controlId.Add(new KeyValuePair<Guid, EKeyword>(Guid.NewGuid(), EKeyword.Process)); curCmd.Commands.Add(new GPCmd() { Parent = curCmd, IsKeyword = true, Keyword = EKeyword.Process, Name = sName, Arguments = sArguments }); d2cmd = curCmd.Commands.Last(); oldCmd = curCmd; curCmd = d2cmd; break; case "loop": controlId.Add(new KeyValuePair<Guid, EKeyword>(Guid.NewGuid(), EKeyword.Loop)); curCmd.Commands.Add(new GPCmd() { Parent = curCmd, IsKeyword = true, Keyword = EKeyword.Loop, Id = controlId.Where(x => x.Value == EKeyword.Loop).Last().Key }); d2cmd = curCmd.Commands.Last(); oldCmd = curCmd; curCmd = d2cmd; break; case "repeat": controlId.Add(new KeyValuePair<Guid, EKeyword>(Guid.NewGuid(), EKeyword.Repeat)); curCmd.Commands.Add(new GPCmd() { Parent = curCmd, IsKeyword = true, Keyword = EKeyword.Repeat, Id = controlId.Where(x => x.Value == EKeyword.Repeat).Last().Key }); d2cmd = curCmd.Commands.Last(); oldCmd = curCmd; curCmd = d2cmd; break; case "until": curCmd.Commands.Add(new GPCmd() { Parent = curCmd, IsKeyword = true, Keyword = EKeyword.Until, Id = controlId.Where(x => x.Value == EKeyword.Repeat).Last().Key, Arguments = sArguments }); curCmd = curCmd.Parent; break; case "while": controlId.Add(new KeyValuePair<Guid, EKeyword>(Guid.NewGuid(), EKeyword.While)); curCmd.Commands.Add(new GPCmd() { Parent = curCmd, IsKeyword = true, Keyword = EKeyword.While, Id = controlId.Where(x => x.Value == EKeyword.While).Last().Key, Arguments = sArguments }); d2cmd = curCmd.Commands.Last(); oldCmd = curCmd; curCmd = d2cmd; break; case "from": controlId.Add(new KeyValuePair<Guid, EKeyword>(Guid.NewGuid(), EKeyword.From)); sArguments = raw.Substring(sKeyword.Length).Trim(); curCmd.Commands.Add(new GPCmd() { Parent = curCmd, IsKeyword = true, Keyword = EKeyword.From, Id = controlId.Where(x => x.Value == EKeyword.From).Last().Key, Arguments = sArguments }); d2cmd = curCmd.Commands.Last(); oldCmd = curCmd; curCmd = d2cmd; break; case "for": controlId.Add(new KeyValuePair<Guid, EKeyword>(Guid.NewGuid(), EKeyword.For)); sArguments = raw.Substring(sKeyword.Length).Trim(); curCmd.Commands.Add(new GPCmd() { Parent = curCmd, IsKeyword = true, Keyword = EKeyword.For, Id = controlId.Where(x => x.Value == EKeyword.For).Last().Key, Arguments = sArguments }); d2cmd = curCmd.Commands.Last(); oldCmd = curCmd; curCmd = d2cmd; break; case "if": controlId.Add(new KeyValuePair<Guid, EKeyword>(Guid.NewGuid(), EKeyword.If)); curCmd.Commands.Add(new GPCmd() { Parent = curCmd, IsKeyword = true, Keyword = EKeyword.If, Id = controlId.Where(x => x.Value == EKeyword.If).Last().Key, Arguments = sArguments }); d2cmd = curCmd.Commands.Last(); oldCmd = curCmd; curCmd = d2cmd; break; case "else": curCmd.Commands.Add(new GPCmd() { Parent = curCmd.Parent, IsKeyword = true, Keyword = EKeyword.Else, Id = controlId.Where(x => x.Value == EKeyword.If).Last().Key }); //d2cmd = curCmd.Commands.Last(); //oldCmd = curCmd; //curCmd = d2cmd; break; case "end": controlId.Remove(controlId.Last()); curCmd = curCmd.Parent; break; case "global": IsGlobals = true; IsConstants = false; IsLocals = false; IsAddingVariables = true; break; case "const": IsGlobals = false; IsConstants = true; IsLocals = false; IsAddingVariables = true; break; case "local": IsLocals = true; IsGlobals = false; IsConstants = false; IsAddingVariables = true; break; case "private": IsLocals = false; IsGlobals = false; IsConstants = false; IsAddingVariables = true; break; case "begin": IsLocals = false; IsGlobals = false; IsConstants = false; IsAddingVariables = false; break; case "return": curCmd.Commands.Add(new GPCmd() { Parent = curCmd, IsKeyword = true, Keyword = EKeyword.Return, Id = Guid.Empty, Arguments = sArguments }); break; case "break": curCmd.Commands.Add(new GPCmd() { Parent = curCmd, IsKeyword = true, Keyword = EKeyword.Break, Id = controlId.Where(x => x.Value == EKeyword.Loop || x.Value == EKeyword.For || x.Value == EKeyword.From || x.Value == EKeyword.While || x.Value == EKeyword.Repeat ).Last().Key }); break; case "frame": curCmd.Commands.Add(new GPCmd() { Parent = curCmd, IsKeyword = true, Keyword = EKeyword.Frame, Arguments = sArguments }); break; } } else { if (!IsAddingVariables) curCmd.Commands.Add(new GPCmd() { Parent = curCmd, IsKeyword = false, Raw = raw.Trim() }); else { Char sc = ','; List<KeyValuePair<String, String>> Vars = new List<KeyValuePair<String, String>>(); if (cmd.Contains("[")) { sc = ';'; if(!cmd.Contains(";")) cmd += ";"; } else if (!cmd.Contains(',')) cmd += ","; foreach (String v in cmd.Split(new char[] { sc }, StringSplitOptions.RemoveEmptyEntries)) { String varName = v; String varValue = "null"; if (v.IndexOf('=') > 0) { varName = v.Substring(0, v.IndexOf('=')).Trim(); varValue = v.Substring(v.IndexOf('=') + 1).Trim(); if (varName.Contains("[")) { varValue = varName.Substring(varName.IndexOf("[")) + " = " + varValue; varName = varName.Substring(0, varName.IndexOf("[")); } } if (IsGlobals) GlobalVars.Add(new KeyValuePair<String, String>(varName, varValue)); else if(IsConstants) ConstVars.Add(new KeyValuePair<String, String>(varName, varValue)); else if (IsLocals) LocalVars.Add(new KeyValuePair<String, String>(varName, varValue)); else { curCmd.Variables.Add(varName, varValue); if (curCmd.Keyword == EKeyword.Program) GlobalLocalVars.Add(new KeyValuePair<String, String>(varName, varValue)); } } } } } return Root; }