Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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)}");
                    }
                }
            }
        }
Example #7
0
        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(' ');