public void ParseSetting_Variable_Parse() { var block = BlockFactory.GetBlock <AutoBlockInstance>("ConstantString"); var valueSetting = block.Settings["value"]; var input = "value = @myVariable"; LoliCodeParser.ParseSetting(ref input, block.Settings, block.Descriptor); Assert.Equal(SettingInputMode.Variable, valueSetting.InputMode); Assert.Equal("myVariable", valueSetting.InputVariableName); }
public void ParseSetting_InterpolatedString_Parse() { var block = BlockFactory.GetBlock <AutoBlockInstance>("ConstantString"); var valueSetting = block.Settings["value"]; var input = "value = $\"my <interp> string\""; LoliCodeParser.ParseSetting(ref input, block.Settings, block.Descriptor); Assert.Equal(SettingInputMode.Interpolated, valueSetting.InputMode); Assert.IsType <InterpolatedStringSetting>(valueSetting.InterpolatedSetting); Assert.Equal("my <interp> string", ((InterpolatedStringSetting)valueSetting.InterpolatedSetting).Value); }
public void ParseSetting_FixedStringSetting_Parse() { var block = BlockFactory.GetBlock <AutoBlockInstance>("ConstantString"); var valueSetting = block.Settings["value"]; var input = "value = \"myValue\""; LoliCodeParser.ParseSetting(ref input, block.Settings, block.Descriptor); Assert.Equal(SettingInputMode.Fixed, valueSetting.InputMode); Assert.IsType <StringSetting>(valueSetting.FixedSetting); Assert.Equal("myValue", (valueSetting.FixedSetting as StringSetting).Value); }
public override void FromLC(ref string script, ref int lineNumber) { /* * TYPE:STANDARD * "name=hello&value=hi" * "application/x-www-form-urlencoded" * * TYPE:RAW * BASE64_DATA * "application/octet-stream" * * TYPE:BASICAUTH * "myUser" * "myPass" * * TYPE:MULTIPART * "myBoundary" * CONTENT:STRING "name" "content" "content-type" * CONTENT:RAW "name" BASE64_DATA "content-type" * CONTENT:FILE "name" "fileName" "content-type" * */ // First parse the options that are common to every BlockInstance base.FromLC(ref script, ref lineNumber); using var reader = new StringReader(script); string line, lineCopy; while ((line = reader.ReadLine()) != null) { line = line.Trim(); lineCopy = line; lineNumber++; if (string.IsNullOrWhiteSpace(line)) { continue; } if (line.StartsWith("TYPE:")) { try { var reqParams = Regex.Match(line, "TYPE:([A-Z]+)").Groups[1].Value; switch (reqParams) { case "STANDARD": var standardReqParams = new StandardRequestParams(); // Read one line to parse the content line = reader.ReadLine().Trim(); lineCopy = line; lineNumber++; LoliCodeParser.ParseSettingValue(ref line, standardReqParams.Content, new StringParameter()); // Read another line to parse the content-type line = reader.ReadLine().Trim(); lineCopy = line; lineNumber++; LoliCodeParser.ParseSettingValue(ref line, standardReqParams.ContentType, new StringParameter()); RequestParams = standardReqParams; break; case "RAW": var rawReqParams = new RawRequestParams(); // Read one line to parse the content line = reader.ReadLine().Trim(); lineCopy = line; lineNumber++; LoliCodeParser.ParseSettingValue(ref line, rawReqParams.Content, new ByteArrayParameter()); // Read another line to parse the content-type line = reader.ReadLine().Trim(); lineCopy = line; lineNumber++; LoliCodeParser.ParseSettingValue(ref line, rawReqParams.ContentType, new StringParameter()); RequestParams = rawReqParams; break; case "BASICAUTH": var basicAuthReqParams = new BasicAuthRequestParams(); // Read one line to parse the username line = reader.ReadLine().Trim(); lineCopy = line; lineNumber++; LoliCodeParser.ParseSettingValue(ref line, basicAuthReqParams.Username, new StringParameter()); // Read another line to parse the password line = reader.ReadLine().Trim(); lineCopy = line; lineNumber++; LoliCodeParser.ParseSettingValue(ref line, basicAuthReqParams.Password, new StringParameter()); RequestParams = basicAuthReqParams; break; case "MULTIPART": var multipartReqParams = new MultipartRequestParams(); // Read one line to parse the boundary line = reader.ReadLine().Trim(); lineCopy = line; lineNumber++; LoliCodeParser.ParseSettingValue(ref line, multipartReqParams.Boundary, new StringParameter()); RequestParams = multipartReqParams; break; default: throw new LoliCodeParsingException(lineNumber, $"Invalid type: {reqParams}"); } } catch (NullReferenceException) { throw new LoliCodeParsingException(lineNumber, "Missing options for the selected content"); } catch { throw new LoliCodeParsingException(lineNumber, $"Could not parse the setting: {lineCopy.TruncatePretty(50)}"); } } else if (line.StartsWith("CONTENT:")) { try { var multipart = (MultipartRequestParams)RequestParams; var token = LineParser.ParseToken(ref line); var tokenType = Regex.Match(token, "CONTENT:([A-Z]+)").Groups[1].Value; switch (tokenType) { case "STRING": var stringContent = new StringHttpContentSettingsGroup(); LoliCodeParser.ParseSettingValue(ref line, stringContent.Name, new StringParameter()); LoliCodeParser.ParseSettingValue(ref line, stringContent.Data, new StringParameter()); LoliCodeParser.ParseSettingValue(ref line, stringContent.ContentType, new StringParameter()); multipart.Contents.Add(stringContent); break; case "RAW": var rawContent = new RawHttpContentSettingsGroup(); LoliCodeParser.ParseSettingValue(ref line, rawContent.Name, new StringParameter()); LoliCodeParser.ParseSettingValue(ref line, rawContent.Data, new ByteArrayParameter()); LoliCodeParser.ParseSettingValue(ref line, rawContent.ContentType, new StringParameter()); multipart.Contents.Add(rawContent); break; case "FILE": var fileContent = new FileHttpContentSettingsGroup(); LoliCodeParser.ParseSettingValue(ref line, fileContent.Name, new StringParameter()); LoliCodeParser.ParseSettingValue(ref line, fileContent.FileName, new StringParameter()); LoliCodeParser.ParseSettingValue(ref line, fileContent.ContentType, new StringParameter()); multipart.Contents.Add(fileContent); break; } } catch { throw new LoliCodeParsingException(lineNumber, $"Could not parse the multipart content: {lineCopy.TruncatePretty(50)}"); } } else { try { LoliCodeParser.ParseSetting(ref line, Settings, Descriptor); } catch { throw new LoliCodeParsingException(lineNumber, $"Could not parse the setting: {lineCopy.TruncatePretty(50)}"); } } } }
private string TranspileStatement(string input, List <string> definedVariables) { Match match; // CODE LABEL // #MYLABEL => MYLABEL: if ((match = Regex.Match(input, $"^#({validTokenRegex})$")).Success) { return($"{match.Groups[1].Value}:"); } // JUMP // JUMP #MYLABEL => goto MYLABEL; if ((match = Regex.Match(input, $"^JUMP #({validTokenRegex})$")).Success) { return($"goto {match.Groups[1].Value};"); } // END // END => } if (input == "END") { return("}"); } // REPEAT // REPEAT 10 => for (int xyz = 0; xyz < 10; xyz++) { if ((match = Regex.Match(input, $"^REPEAT (.+)$")).Success) { var i = VariableNames.RandomName(); return($"for (var {i} = 0; {i} < {match.Groups[1].Value}; {i}++){System.Environment.NewLine}{{"); } // FOREACH // FOREACH v IN list => foreach (var v in list) { if ((match = Regex.Match(input, $"^FOREACH ({validTokenRegex}) IN ({validTokenRegex})$")).Success) { return($"foreach (var {match.Groups[1].Value} in {match.Groups[2].Value}){System.Environment.NewLine}{{"); } // LOG // LOG myVar => data.Logger.Log(myVar); if ((match = Regex.Match(input, $"^LOG (.+)$")).Success) { return($"data.Logger.Log({match.Groups[1].Value});"); } // CLOG // CLOG Tomato "hello" => data.Logger.Log("hello", LogColors.Tomato); if ((match = Regex.Match(input, $"^CLOG ([A-Za-z]+) (.+)$")).Success) { return($"data.Logger.Log({match.Groups[2].Value}, LogColors.{match.Groups[1].Value});"); } // WHILE // WHILE a < b => while (a < b) { if ((match = Regex.Match(input, $"^WHILE (.+)$")).Success) { var line = match.Groups[1].Value.Trim(); if (LoliCodeParser.KeyTypes.Any(t => line.StartsWith(t))) { var keyType = LineParser.ParseToken(ref line); var key = LoliCodeParser.ParseKey(ref line, keyType); return($"while ({CSharpWriter.ConvertKey(key)}){System.Environment.NewLine}{{"); } else { return($"while ({line}){System.Environment.NewLine}{{"); } } // IF // IF a < b => if (a < b) { if ((match = Regex.Match(input, $"^IF (.+)$")).Success) { var line = match.Groups[1].Value.Trim(); if (LoliCodeParser.KeyTypes.Any(t => line.StartsWith(t))) { var keyType = LineParser.ParseToken(ref line); var key = LoliCodeParser.ParseKey(ref line, keyType); return($"if ({CSharpWriter.ConvertKey(key)}){System.Environment.NewLine}{{"); } else { return($"if ({line}){System.Environment.NewLine}{{"); } } // ELSE // ELSE => } else { if (input == "ELSE") { return($"}}{System.Environment.NewLine}else{System.Environment.NewLine}{{"); } // ELSE IF // ELSE IF a < b => } else if (a < b) { if ((match = Regex.Match(input, $"ELSE IF (.+)$")).Success) { var line = match.Groups[1].Value.Trim(); if (LoliCodeParser.KeyTypes.Any(t => line.StartsWith(t))) { var keyType = LineParser.ParseToken(ref line); var key = LoliCodeParser.ParseKey(ref line, keyType); return($"}}{System.Environment.NewLine}else if ({CSharpWriter.ConvertKey(key)}){System.Environment.NewLine}{{"); } else { return($"}}{System.Environment.NewLine}else if ({line}){System.Environment.NewLine}{{"); } } // TRY // TRY => try { if (input == "TRY") { return($"try{System.Environment.NewLine}{{"); } // CATCH // CATCH => } catch { if (input == "CATCH") { return($"}}{System.Environment.NewLine}catch{System.Environment.NewLine}{{"); } // LOCK // LOCK globals => lock (globals) { if ((match = Regex.Match(input, $"^LOCK (.+)$")).Success) { return($"lock({match.Groups[1].Value}){System.Environment.NewLine}{{"); } // SET VAR // SET VAR myString "hello" => string myString = "hello"; if ((match = Regex.Match(input, $"^SET VAR ({validTokenRegex}) (.+)$")).Success) { if (definedVariables.Contains(match.Groups[1].Value)) { return($"{match.Groups[1].Value} = {match.Groups[2].Value};"); } else { definedVariables.Add(match.Groups[1].Value); return($"string {match.Groups[1].Value} = {match.Groups[2].Value};"); } } // SET CAP // SET CAP myCapture "hello" => string myString = "hello"; data.MarkForCapture(nameof(myCapture)); if ((match = Regex.Match(input, $"^SET CAP ({validTokenRegex}) (.+)$")).Success) { if (definedVariables.Contains(match.Groups[1].Value)) { return($"{match.Groups[1].Value} = {match.Groups[2].Value};{System.Environment.NewLine}data.MarkForCapture(nameof({match.Groups[1].Value}));"); } else { definedVariables.Add(match.Groups[1].Value); return($"string {match.Groups[1].Value} = {match.Groups[2].Value};{System.Environment.NewLine}data.MarkForCapture(nameof({match.Groups[1].Value}));"); } } throw new NotSupportedException(); }
public override void FromLC(ref string script, ref int lineNumber) { /* * KEYCHAIN SUCCESS OR * STRINGKEY @myVariable Contains "abc" * DICTKEY @data.COOKIES HasKey "my-cookie" * KEYCHAIN FAIL AND * LISTKEY @myList Contains "item" * FLOATKEY 1 GreaterThan 2 */ // First parse the options that are common to every BlockInstance base.FromLC(ref script, ref lineNumber); using var reader = new StringReader(script); string line, lineCopy; while ((line = reader.ReadLine()) != null) { line = line.Trim(); lineCopy = line; lineNumber++; if (string.IsNullOrWhiteSpace(line)) { continue; } if (line.StartsWith("KEYCHAIN")) { try { var keychain = new Keychain(); LineParser.ParseToken(ref line); keychain.ResultStatus = LineParser.ParseToken(ref line); keychain.Mode = Enum.Parse <KeychainMode>(LineParser.ParseToken(ref line)); Keychains.Add(keychain); } catch { throw new LoliCodeParsingException(lineNumber, $"Invalid keychain declaration: {lineCopy.TruncatePretty(50)}"); } } else if (Regex.IsMatch(line, "^[A-Z]+KEY ")) { try { var keyType = LineParser.ParseToken(ref line); Keychains.Last().Keys.Add(LoliCodeParser.ParseKey(ref line, keyType)); } catch { throw new LoliCodeParsingException(lineNumber, $"Invalid key declaration: {lineCopy.TruncatePretty(50)}"); } } else { try { LoliCodeParser.ParseSetting(ref line, Settings, Descriptor); } catch { throw new LoliCodeParsingException(lineNumber, $"Could not parse the setting: {lineCopy.TruncatePretty(50)}"); } } } }
private string TranspileStatement(string input, List <string> definedVariables) { Match match; // (RESOURCES) TAKEONE // TAKEONE FROM "MyResource" => "myString" if ((match = Regex.Match(input, "TAKEONE FROM (\"[^\"]+\") => @?\"?([^\"]+)\"?")).Success) { return($"string {match.Groups[2].Value} = globals.Resources[{match.Groups[1].Value}].TakeOne();"); } // (RESOURCES) TAKE // TAKE 5 FROM "MyResource" => "myList" if ((match = Regex.Match(input, "TAKE ([0-9]+) FROM (\"[^\"]+\") => @?\"?([^\"]+)\"?")).Success) { return($"List<string> {match.Groups[3].Value} = globals.Resources[{match.Groups[2].Value}].Take({match.Groups[1].Value});"); } // CODE LABEL // #MYLABEL => MYLABEL: if ((match = Regex.Match(input, $"^#({validTokenRegex})$")).Success) { return($"{match.Groups[1].Value}:"); } // JUMP // JUMP #MYLABEL => goto MYLABEL; if ((match = Regex.Match(input, $"^JUMP #({validTokenRegex})$")).Success) { return($"goto {match.Groups[1].Value};"); } // END // END => } if (input == "END") { return("}"); } // REPEAT // REPEAT 10 => for (int xyz = 0; xyz < 10; xyz++) { if ((match = Regex.Match(input, $"^REPEAT (.+)$")).Success) { var i = VariableNames.RandomName(); return($"for (var {i} = 0; {i} < ({match.Groups[1].Value}).AsInt(); {i}++){System.Environment.NewLine}{{"); } // FOREACH // FOREACH v IN list => foreach (var v in list) { if ((match = Regex.Match(input, $"^FOREACH ({validTokenRegex}) IN ({validTokenRegex})$")).Success) { return($"foreach (var {match.Groups[1].Value} in {match.Groups[2].Value}){System.Environment.NewLine}{{"); } // LOG // LOG myVar => data.Logger.Log(myVar); if ((match = Regex.Match(input, $"^LOG (.+)$")).Success) { return($"data.Logger.Log({match.Groups[1].Value});"); } // CLOG // CLOG Tomato "hello" => data.Logger.Log("hello", LogColors.Tomato); if ((match = Regex.Match(input, $"^CLOG ([A-Za-z]+) (.+)$")).Success) { return($"data.Logger.Log({match.Groups[2].Value}, LogColors.{match.Groups[1].Value});"); } // WHILE // WHILE a < b => while (a < b) { if ((match = Regex.Match(input, $"^WHILE (.+)$")).Success) { var line = match.Groups[1].Value.Trim(); if (LoliCodeParser.keyIdentifiers.Any(t => line.StartsWith(t))) { var keyType = LineParser.ParseToken(ref line); var key = LoliCodeParser.ParseKey(ref line, keyType); return($"while ({CSharpWriter.ConvertKey(key)}){System.Environment.NewLine}{{"); } else { return($"while ({line}){System.Environment.NewLine}{{"); } } // IF // IF a < b => if (a < b) { if ((match = Regex.Match(input, $"^IF (.+)$")).Success) { var line = match.Groups[1].Value.Trim(); if (LoliCodeParser.keyIdentifiers.Any(t => line.StartsWith(t))) { var keyType = LineParser.ParseToken(ref line); var key = LoliCodeParser.ParseKey(ref line, keyType); return($"if ({CSharpWriter.ConvertKey(key)}){System.Environment.NewLine}{{"); } else { return($"if ({line}){System.Environment.NewLine}{{"); } } // ELSE // ELSE => } else { if (input == "ELSE") { return($"}}{System.Environment.NewLine}else{System.Environment.NewLine}{{"); } // ELSE IF // ELSE IF a < b => } else if (a < b) { if ((match = Regex.Match(input, $"ELSE IF (.+)$")).Success) { var line = match.Groups[1].Value.Trim(); if (LoliCodeParser.keyIdentifiers.Any(t => line.StartsWith(t))) { var keyType = LineParser.ParseToken(ref line); var key = LoliCodeParser.ParseKey(ref line, keyType); return($"}}{System.Environment.NewLine}else if ({CSharpWriter.ConvertKey(key)}){System.Environment.NewLine}{{"); } else { return($"}}{System.Environment.NewLine}else if ({line}){System.Environment.NewLine}{{"); } } // TRY // TRY => try { if (input == "TRY") { return($"try{System.Environment.NewLine}{{"); } // CATCH // CATCH => } catch { if (input == "CATCH") { return($"}}{System.Environment.NewLine}catch{System.Environment.NewLine}{{"); } // FINALLY // FINALLY => } finally { if (input == "FINALLY") { return($"}}{System.Environment.NewLine}finally{System.Environment.NewLine}{{"); } // LOCK // LOCK globals => lock (globals) { if ((match = Regex.Match(input, $"^LOCK (.+)$")).Success) { return($"lock({match.Groups[1].Value}){System.Environment.NewLine}{{"); } // ACQUIRELOCK // ACQUIRELOCK globals => await data.AsyncLocker.Acquire(nameof(globals), data.CancellationToken); if ((match = Regex.Match(input, $"^ACQUIRELOCK (.+)$")).Success) { return($"await data.AsyncLocker.Acquire(nameof({match.Groups[1].Value}), data.CancellationToken);"); } // RELEASELOCK // RELEASELOCK globals => data.AsyncLocker.Release(nameof(globals)); if ((match = Regex.Match(input, $"^RELEASELOCK (.+)$")).Success) { return($"data.AsyncLocker.Release(nameof({match.Groups[1].Value}));"); } // SET VAR // SET VAR myString "hello" => string myString = "hello"; if ((match = Regex.Match(input, $"^SET VAR @?\"?({validTokenRegex})\"? (.+)$")).Success) { if (definedVariables.Contains(match.Groups[1].Value)) { return($"{match.Groups[1].Value} = {match.Groups[2].Value};"); } else { definedVariables.Add(match.Groups[1].Value); return($"string {match.Groups[1].Value} = {match.Groups[2].Value};"); } } // SET CAP // SET CAP myCapture "hello" => string myString = "hello"; data.MarkForCapture(nameof(myCapture)); if ((match = Regex.Match(input, $"^SET CAP @?\"?({validTokenRegex})\"? (.+)$")).Success) { if (definedVariables.Contains(match.Groups[1].Value)) { return($"{match.Groups[1].Value} = {match.Groups[2].Value};{System.Environment.NewLine}data.MarkForCapture(nameof({match.Groups[1].Value}));"); } else { definedVariables.Add(match.Groups[1].Value); return($"string {match.Groups[1].Value} = {match.Groups[2].Value};{System.Environment.NewLine}data.MarkForCapture(nameof({match.Groups[1].Value}));"); } } // SET USEPROXY // SET USEPROXY TRUE => data.UseProxy = "true"; if ((match = Regex.Match(input, "^SET USEPROXY (TRUE|FALSE)$")).Success) { return($"data.UseProxy = {match.Groups[1].Value.ToLower()};"); } // SET PROXY // SET PROXY "127.0.0.1" 9050 SOCKS5 => data.Proxy = new Proxy("127.0.0.1", 9050, ProxyType.Socks5); // SET PROXY "127.0.0.1" 9050 SOCKS5 "username" "password" => data.Proxy = new Proxy("127.0.0.1", 9050, ProxyType.Socks5, "username", "password"); if (input.StartsWith("SET PROXY ")) { var setProxyParams = input["SET PROXY ".Length..].Split(' ');