Пример #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
        private static string[] AssignTargets(CharSource source, ref char chr, Dictionary <string, IFunction> funcs)
        {
            // Seen '='
            if (!source.Advance(out chr))
            {
                throw new FinalCharacterException("Expected assignment token, \"=>\"");
            }
            else if (chr != '>')
            {
                throw new InvalidCharacterException($"Expected assignment token, \"=>\": found \"={chr}\"");
            }
            if (!source.AdvanceWhiteSpace(out chr))
            {
                throw new FinalCharacterException("Expected assignment");
            }
            var right = Arguments.Multiple(source, ref chr, funcs).Evaluate();

            if (!right.All(t => t is NameArgument))
            {
                throw new InvalidArgumentException($"Assigned types must be names");
            }
            var names = right.Select(t => (t as NameArgument).Value).ToArray();

            return(names);
        }
Пример #3
0
        private static Statement CallArguments(CharSource source, ref char chr, Dictionary <string, IFunction> funcs, IFunction func, int line)
        {
            // Arrive on ':'
            if (!source.AdvanceWhiteSpace(out chr))
            {
                throw new FinalCharacterException("Expected function arguments");
            }
            var args  = Arguments.Multiple(source, ref chr, funcs);
            var fcall = new FunctionCall(line)
            {
                Function  = func,
                Arguments = args
            };

            return(chr == '=' ? Assign(source, ref chr, funcs, fcall, line) : fcall);
        }
Пример #4
0
        public static IArgument Number(CharSource source, ref char chr)
        {
            var integral = source.ReadInt(ref chr);

            if (chr == '.')
            {
                if (!source.Advance(out chr))
                {
                    throw new FinalCharacterException("Expected fractional value after '.'");
                }
                else if (!char.IsDigit(chr))
                {
                    throw new InvalidCharacterException($"Expected fractional value after '.': found '{chr}'");
                }
                var fractional = source.ReadFractional(ref chr);
                var mantissa   = integral >= 0 ? integral + fractional : integral - fractional;

                if (char.ToLower(chr) == 'e')
                {
                    if (!source.AdvanceWhiteSpace(out chr))
                    {
                        throw new FinalCharacterException("Expected exponent after 'e'");
                    }
                    else if (!CharSource.IsNumberStart(chr))
                    {
                        throw new InvalidCharacterException($"Expected exponent after 'e': found '{chr}'");
                    }
                    var exponent = source.ReadInt(ref chr);
                    mantissa *= Math.Pow(10, exponent);
                }

                return(new DoubleLiteral()
                {
                    Value = mantissa
                });
            }
            return(new IntegerLiteral()
            {
                Value = integral
            });
        }
Пример #5
0
        public static IArgument Executable(CharSource source, ref char chr, Dictionary <string, IFunction> funcs)
        {
            // Having seen '<'
            if (!source.AdvanceWhiteSpace(out chr))
            {
                throw new FinalCharacterException("Expected statements, or closing '>'");
            }
            var exec = new ExecutableArgument();

            // Statement reading takes us to the first character of the next potential
            while (true)
            {
                if (chr == '>')
                {
                    source.Advance(out chr);
                    return(exec);
                }
                var statement = Statement(source, ref chr, funcs);
                exec.Value.Add(statement);
            }
        }