Пример #1
0
        public static object GetObjectFromString(int line, string str, QType type, Dictionary <string, Variable> globals = null, Dictionary <string, Variable> variables = null)
        {
            if (str.Length == 0)
            {
                throw new ParseFailException(line, "Invalid empty object");
            }
            switch (type)
            {
            case QType.Bool:
            {
                if (str == "true")
                {
                    return((object)true);
                }
                if (str == "false")
                {
                    return((object)false);
                }
                if (!IsValid.Identifier(str))
                {
                    throw new ParseFailException(line, "Invalid identifier used as bool");
                }
                else
                {
                    Variable var = GetVariableFromString(line, str, globals, variables);
                    if (var.type == QType.Bool)
                    {
                        return(var.obj);
                    }
                    else
                    {
                        throw new ParseFailException(line, "Variable " + str + " is not bool");
                    }
                }
            }

            case QType.String:
            {
                if (str.StartsWith("\"") && str.EndsWith("\""))
                {
                    return((object)str.Substring(1, str.Length - 2));
                }
                else
                {
                    Variable var = GetVariableFromString(line, str, globals, variables);
                    if (var.type == QType.String)
                    {
                        return(var.obj);
                    }
                    else
                    {
                        throw new ParseFailException(line, "Variable " + str + " is not string");
                    }
                }
            }

            case QType.Int:
            {
                if (str[0] <= '9' && str[0] >= '0')
                {
                    //return (object)int.Parse(str);
                    if (str.Length < 2)
                    {
                        return(int.Parse(str));
                    }
                    else
                    {
                        if (str[0] != '0')
                        {
                            return(int.Parse(str));
                        }
                        else
                        {
                            if (str[1] == 'x' || str[1] == 'X')
                            {
                                // hexadecimal digits are 0-9, a-f/A-F
                                // we should be able to get away with just a
                                return(int.Parse(str.Substring(2), NumberStyles.HexNumber));
                            }
                            else
                            {
                                // octal representation is 012, which is 10 in decimal
                                // C would use octal if 0 prefix is used
                                string octals = str.Substring(1);
                                int    result = 0;
                                foreach (char c in octals)
                                {
                                    if (c < '0' || c >= '8')
                                    {
                                        throw new ParseFailException(line, c + " is not a valid digit in octal!");
                                    }
                                    result = result * 8 + (c - '0');
                                }
                                return(result);
                            }
                        }
                    }
                }
                else
                {
                    Variable var = GetVariableFromString(line, str, globals, variables);
                    if (var.type == QType.Int)
                    {
                        return(var.obj);
                    }
                    else
                    {
                        throw new ParseFailException(line, "Variable " + str + " is not int");
                    }
                }
            }
            }
            return(null);
        }
Пример #2
0
        public static List <Function> GetFunctions(string code)
        {
            List <Function> functions = new List <Function>();

            // Each function has a start and an end. The function officially starts
            // with a start_function thing, but it can also prepend arguments and return type.
            Function       currentFunction = new Function();
            eFunctionScope currentScope    = eFunctionScope.None;
            List <string>  lines           = code.Split('\n').ToList();

            //Console.WriteLine("[DEBUG] Pass 1: getting functions");
            for (int i = 0; i < lines.Count; i++)
            {
                // Ignore lines that start with a //
                string line = lines[i].TrimStart(' ').TrimEnd(' ');
                if (line.StartsWith("//"))
                {
                    continue;
                }
                if (line.StartsWith("function_args_start"))
                {
                    if (currentScope == eFunctionScope.None)
                    {
                        currentScope = eFunctionScope.Argument;
                        currentFunction.functionArguments.Clear();
                    }
                    else
                    {
                        throw new ParseFailException(i, "Bad function_args_start inside another scope (duplicate?)");
                    }
                }
                else if (line.StartsWith("start_function"))
                {
                    if (currentScope == eFunctionScope.None)
                    {
                        currentScope = eFunctionScope.Main;
                        currentFunction.lines.Clear();
                        // get the name
                        string[] split = line.Split('|');
                        if (split.Length > 2)
                        {
                            throw new ParseFailException(i, "Too many arguments to start_function!");
                        }
                        if (split.Length < 2)
                        {
                            throw new ParseFailException(i, "Name needs to be provided (usage: \"start_function|<your name>\")");
                        }
                        string name = split[1];
                        if (!IsValid.Identifier(name))
                        {
                            throw new ParseFailException(i, "Invalid function name");
                        }
                        currentFunction.name = name;
                        //Console.WriteLine($"[DEBUG] Found function: {name}");
                    }
                    else
                    {
                        throw new ParseFailException(i, "Bad start_function inside another scope (duplicate?)");
                    }
                }
                else if (line.StartsWith("function_args_end"))
                {
                    if (currentScope == eFunctionScope.Argument)
                    {
                        currentScope = eFunctionScope.None;
                    }
                    else
                    {
                        throw new ParseFailException(i, "Bad argument end marker without a scope (duplicate line?)");
                    }
                }
                else if (line.StartsWith("end_function"))
                {
                    if (currentScope == eFunctionScope.Main)
                    {
                        currentScope = eFunctionScope.None;
                        functions.Add(currentFunction);
                        currentFunction = new Function();
                    }
                    else
                    {
                        throw new ParseFailException(i, "Bad function end marker without a scope (duplicate line?)");
                    }
                }
                else
                {
                    switch (currentScope)
                    {
                    case eFunctionScope.Argument:
                    {
                        if (line.StartsWith("func_arg"))
                        {
                            string[] split = line.Split('|');
                            if (split.Length > 3)
                            {
                                throw new ParseFailException(i, "Too many arguments to return_value_type!");
                            }
                            if (split.Length < 2)
                            {
                                throw new ParseFailException(i, "Argument type missing");
                            }
                            if (split.Length < 3)
                            {
                                throw new ParseFailException(i, "Argument name missing");
                            }
                            //currentFunction.returnType = Misc.GetTypeFromString(i, split[1]);
                            currentFunction.functionArguments.Add(new Argument()
                                {
                                    argName = split[2],
                                    argType = Misc.GetTypeFromString(i, split[1])
                                });
                        }
                        break;
                    }

                    case eFunctionScope.Main:
                    {
                        if (string.IsNullOrWhiteSpace(line))
                        {
                            continue;
                        }
                        currentFunction.lines.Add(line);
                        break;
                    }

                    case eFunctionScope.None:
                    {
                        if (line.StartsWith("return_value_type"))
                        {
                            if (currentFunction.returnType == QType.Void)
                            {
                                string[] split = line.Split('|');
                                if (split.Length > 2)
                                {
                                    throw new ParseFailException(i, "Too many arguments to return_value_type!");
                                }
                                if (split.Length < 2)
                                {
                                    throw new ParseFailException(i, "Name needs to be provided (usage: \"return_value_type|<type: string/s/str/bool/boolean/b/integer/int/int32/i32/i>\")");
                                }
                                currentFunction.returnType = Misc.GetTypeFromString(i, split[1]);
                            }
                        }
                        break;
                    }
                    }
                }
            }

            return(functions);
        }