예제 #1
0
        public static IArgument Function(CharSource source, ref char chr, Dictionary <string, IFunction> funcs)
        {
            // Arrive here having seen '('
            if (!source.AdvanceWhiteSpace(out chr))
            {
                throw new FinalCharacterException("Expected a function name");
            }
            var name = Arguments.Single(source, ref chr, funcs);

            if (!(name is NameArgument nameArg))
            {
                throw new InvalidArgumentException($"Function name type error: Type = {name.GetType().Name}, Value = {name.ToString()}");
            }
            if (!funcs.TryGetValue(nameArg.Value, out var func))
            {
                throw new InvalidArgumentException($"Function does not exist: \"{nameArg.Value}\"");
            }
            // Get next character:
            if (!source.SkipWhiteSpace(ref chr))
            {
                throw new FinalCharacterException("Expected closing ')'");
            }
            var funcArg = new FunctionArgument()
            {
                Call = new FunctionCall(0) // Line number doesn't really matter, as this isn't a whole statement
                {
                    Function = func
                }
            };

            if (chr == ':')
            {
                // Arguments to go with it
                if (!source.AdvanceWhiteSpace(out chr))
                {
                    throw new FinalCharacterException("Expected argument list");
                }
                funcArg.Call.Arguments = Arguments.Multiple(source, ref chr, funcs);
                // Get closing bracket
                if (!source.SkipWhiteSpace(ref chr))
                {
                    throw new FinalCharacterException("Expected closing ')'");
                }
                else if (chr != ')')
                {
                    throw new InvalidCharacterException($"Expected closing ')': found '{chr}'");
                }
            }
            else if (chr != ')')
            {
                throw new InvalidCharacterException($"Expected closing ')' or arguments (':'): found '{chr}'");
            }
            source.Advance(out chr);
            return(funcArg);
        }
예제 #2
0
        public static ArgumentList Multiple(CharSource source, ref char chr, Dictionary <string, IFunction> funcs)
        {
            var args = new ArgumentList();

            // Typically get here having seen nothing or the first character already
            // Running out of text here is not an error, unless specified as more to come
            while (source.SkipWhiteSpace(ref chr))
            {
                var arg = Single(source, ref chr, funcs);
                args.Add(arg);
                if (!source.SkipWhiteSpace(ref chr))
                {
                    return(args);
                }
                else if (chr != ',')
                {
                    return(args);
                }
                source.Advance(out chr);
            }
            // No need to throw here, as if more expected single argument parsing will catch
            return(args);
        }
예제 #3
0
        public static Executable Parse(CharSource source, Dictionary <string, IFunction> funcs)
        {
            // Get to first character
            var exec = new Executable();

            if (!source.Advance(out var chr))
            {
                return(exec);
            }
            // Always ends on first character of next statement, if possible
            while (source.SkipWhiteSpace(ref chr))
            {
                var statement = Statement(source, ref chr, funcs);
                exec.Add(statement);
            }
            return(exec);
        }