Esempio n. 1
0
        internal static Variable Parse(ParseSession parser, int starttoken, out int consumedtokens, Origins origin)
        {
            consumedtokens = starttoken;

            if (parser.CheckToken(starttoken + 1, "."))
            {
                return(null);
            }

            var basetypename = parser.PeekToken(starttoken);

            int totaltokens = starttoken + 1;

            if (parser.CheckToken(totaltokens, "<"))
            {
                ++totaltokens;
                if (!parser.ParseTemplateArguments(totaltokens, basetypename, out totaltokens))
                {
                    return(null);
                }
            }

            var varname = parser.PeekToken(totaltokens);

            if (!parser.CheckToken(totaltokens + 1, "="))
            {
                return(null);
            }

            var type     = TypeSignatureInstantiated.Construct(parser, starttoken, totaltokens);
            var variable = new Variable {
                Name = varname, Origin = origin, Type = type
            };

            totaltokens += 2;

            Expression.Parse(parser, totaltokens, out totaltokens);
            while (parser.CheckToken(totaltokens, ","))
            {
                ++totaltokens;
                Expression.Parse(parser, totaltokens, out totaltokens);
            }

            consumedtokens = totaltokens;

            return(variable);
        }
Esempio n. 2
0
        public static TypeSignatureInstantiated Construct(ParseSession parser, int begintoken, int endtoken)
        {
            var signature = new TypeSignatureInstantiated();

            signature.TypeName = parser.PeekToken(begintoken).Text;


            if (parser.CheckToken(begintoken + 1, "<"))
            {
                signature.TypeArguments = new List <TypeArgument>();
                int totaltokens = begintoken + 2;
                while (!parser.CheckToken(totaltokens, ">"))
                {
                    var argtoken = parser.PeekToken(totaltokens);
                    signature.TypeArguments.Add(new TypeArgument {
                        SpecifiedType = new TypeSignatureInstantiated {
                            TypeName = argtoken.Text
                        }
                    });
                    ++totaltokens;

                    if (parser.CheckToken(totaltokens, ","))
                    {
                        ++totaltokens;
                    }
                }
            }


            int reftoken = endtoken - 1;

            if (reftoken > begintoken)
            {
                signature.TypeIsReference = parser.CheckToken(reftoken, "ref");
            }

            return(signature);
        }
        //
        // Helper routine for parsing a set of function parameters from a token stream.
        //
        // Passes back the index of the next token to inspect, as well as a list of parameters
        // extracted from the token stream, if applicable. May return null in case of a syntax
        // error.
        //
        private static List <FunctionOverload.Parameter> ParseFunctionParams(ParseSession parser, int starttoken, out int consumedtokens)
        {
            var ret = new List <FunctionOverload.Parameter>();

            consumedtokens = starttoken;
            int totaltokens = starttoken;

            while (!parser.CheckToken(totaltokens, "{") && !parser.CheckToken(totaltokens, "->"))
            {
                //
                // Handle the "nothing" case since we don't need to parse any identifiers in addition
                // to the actual "nothing" keyword. This should come first to avoid backtracking in a
                // later parse step.
                //
                if (parser.CheckToken(totaltokens, "nothing"))
                {
                    var signature = new TypeSignatureInstantiated();

                    ret.Add(new FunctionOverload.Parameter {
                        Name = parser.PeekToken(totaltokens), Type = signature
                    });
                    ++totaltokens;
                }

                //
                // Handle higher-order functions.
                //
                else if (parser.CheckToken(totaltokens, "("))
                {
                    ++totaltokens;

                    var higherordername = parser.PeekToken(totaltokens);

                    // TODO - don't treat syntax elements as optional if they are technically required!
                    if (parser.CheckToken(totaltokens + 1, ":"))
                    {
                        totaltokens += 2;

                        bool moreparams = true;
                        if (parser.CheckToken(totaltokens, ")"))
                        {
                            moreparams = false;
                        }

                        while (moreparams)
                        {
                            ++totaltokens;
                            if (parser.CheckToken(totaltokens, "ref"))
                            {
                                ++totaltokens;
                            }

                            if (!parser.CheckToken(totaltokens, ","))
                            {
                                break;
                            }

                            ++totaltokens;
                        }
                    }

                    if (parser.CheckToken(totaltokens, "->"))
                    {
                        totaltokens += 2;
                    }

                    if (!parser.CheckToken(totaltokens, ")"))
                    {
                        return(null);
                    }

                    ++totaltokens;

                    var signature = new TypeSignatureInstantiated();        // TODO - implement higher order function signatures
                    ret.Add(new FunctionOverload.Parameter {
                        Name = higherordername, Type = signature
                    });
                }

                //
                // Handle functions with literal parameters (for pattern matching).
                //
                else if (IsLiteralFunctionParam(parser.PeekToken(totaltokens)))
                {
                    // TODO - better literal support

                    var signature = new TypeSignatureInstantiated();
                    ret.Add(new FunctionOverload.Parameter {
                        Name = parser.PeekToken(totaltokens), Type = signature
                    });

                    ++totaltokens;
                }

                //
                // Handle the general case of "type [ref] identifier[,]" format parameters.
                //
                // Also handles the presence of template arguments attached to the parameter
                // type, as necessary.
                //
                else
                {
                    int begintoken = totaltokens;

                    if (parser.CheckToken(totaltokens + 1, "<"))
                    {
                        var paramtype = parser.PeekToken(totaltokens);
                        totaltokens += 2;
                        if (!parser.ParseTemplateArguments(totaltokens, paramtype, out totaltokens))
                        {
                            return(null);
                        }
                    }
                    else
                    {
                        ++totaltokens;
                    }

                    var paramname = parser.PeekToken(totaltokens);
                    if (parser.CheckToken(totaltokens, "ref"))
                    {
                        ++totaltokens;
                        paramname = parser.PeekToken(totaltokens);
                    }

                    var signature = TypeSignatureInstantiated.Construct(parser, begintoken, totaltokens);
                    ret.Add(new FunctionOverload.Parameter {
                        Name = paramname, Type = signature
                    });

                    ++totaltokens;
                }

                if (!parser.CheckToken(totaltokens, ","))
                {
                    consumedtokens = totaltokens;
                    return(ret);
                }

                ++totaltokens;
            }

            return(ret);
        }
Esempio n. 4
0
        private static List <FunctionOverload.Parameter> ParseFunctionParams(ParseSession parser, int starttoken, out int consumedtokens)
        {
            var ret = new List <FunctionOverload.Parameter>();

            consumedtokens = starttoken;
            int totaltokens = starttoken;

            while (!parser.CheckToken(totaltokens, "{") && !parser.CheckToken(totaltokens, "->"))
            {
                if (parser.CheckToken(totaltokens, "nothing"))
                {
                    var signature = new TypeSignatureInstantiated();

                    ret.Add(new FunctionOverload.Parameter {
                        Name = parser.PeekToken(totaltokens), Type = signature
                    });
                    ++totaltokens;
                }
                else if (parser.CheckToken(totaltokens, "("))
                {
                    ++totaltokens;

                    var higherordername = parser.PeekToken(totaltokens);

                    if (parser.CheckToken(totaltokens + 1, ":"))
                    {
                        totaltokens += 2;

                        bool moreparams = true;
                        if (parser.CheckToken(totaltokens, ")"))
                        {
                            moreparams = false;
                        }

                        while (moreparams)
                        {
                            ++totaltokens;
                            if (parser.CheckToken(totaltokens, "ref"))
                            {
                                ++totaltokens;
                            }

                            if (!parser.CheckToken(totaltokens, ","))
                            {
                                break;
                            }

                            ++totaltokens;
                        }
                    }

                    if (parser.CheckToken(totaltokens, "->"))
                    {
                        totaltokens += 2;
                    }

                    if (!parser.CheckToken(totaltokens, ")"))
                    {
                        return(null);
                    }

                    ++totaltokens;

                    var signature = new TypeSignatureInstantiated();        // TODO - implement higher order function signatures
                    ret.Add(new FunctionOverload.Parameter {
                        Name = higherordername, Type = signature
                    });
                }
                else if (IsLiteralFunctionParam(parser.PeekToken(totaltokens)))
                {
                    // TODO - better literal support

                    var signature = new TypeSignatureInstantiated();
                    ret.Add(new FunctionOverload.Parameter {
                        Name = parser.PeekToken(totaltokens), Type = signature
                    });

                    ++totaltokens;
                }
                else
                {
                    int begintoken = totaltokens;

                    if (parser.CheckToken(totaltokens + 1, "<"))
                    {
                        var paramtype = parser.PeekToken(totaltokens);
                        totaltokens += 2;
                        if (!parser.ParseTemplateArguments(totaltokens, paramtype, out totaltokens))
                        {
                            return(null);
                        }
                    }
                    else
                    {
                        ++totaltokens;
                    }

                    var paramname = parser.PeekToken(totaltokens);
                    if (parser.CheckToken(totaltokens, "ref"))
                    {
                        ++totaltokens;
                        paramname = parser.PeekToken(totaltokens);
                    }

                    var signature = TypeSignatureInstantiated.Construct(parser, begintoken, totaltokens);
                    ret.Add(new FunctionOverload.Parameter {
                        Name = paramname, Type = signature
                    });

                    ++totaltokens;
                }

                if (!parser.CheckToken(totaltokens, ","))
                {
                    consumedtokens = totaltokens;
                    return(ret);
                }

                ++totaltokens;
            }

            return(ret);
        }
        //
        // Helper routine for parsing a structure definition.
        //
        // Consumes tokens and returns a wrapped Structure on success.
        // Returns null on parsing failures, either due to syntactical
        // mistakes, or due to legitimate code that isn't a structure.
        //
        internal static ParsedObject <Structure> Parse(ParseSession parser)
        {
            int totaltokens = 0;

            if (!parser.CheckToken(0, "structure"))
            {
                return(null);
            }

            var nametoken = parser.PeekToken(1);

            if (nametoken == null)
            {
                return(null);
            }

            if (parser.CheckToken(2, "<"))
            {
                if (!parser.ParseTemplateParameters(3, nametoken, out totaltokens))
                {
                    return(null);
                }
            }
            else
            {
                totaltokens = 2;
            }


            if (!parser.CheckToken(totaltokens, ":"))
            {
                return(null);
            }

            ++totaltokens;

            var structure = new Structure {
                Name = nametoken
            };

            structure.Members = new List <Member>();
            var parsed = new ParsedObject <Structure> {
                Name = nametoken, Object = structure
            };

            bool moremembers = true;

            while (moremembers)
            {
                if (parser.CheckToken(totaltokens, "("))
                {
                    ++totaltokens;

                    var membername = parser.PeekToken(totaltokens);

                    ++totaltokens;

                    if (!parser.CheckToken(totaltokens, ":"))
                    {
                        return(null);
                    }

                    ++totaltokens;

                    bool moreparams = true;
                    while (moreparams)
                    {
                        ++totaltokens;
                        if (!parser.CheckToken(totaltokens, ","))
                        {
                            moreparams = false;
                        }
                        else
                        {
                            ++totaltokens;
                        }
                    }

                    if (parser.CheckToken(totaltokens, "->"))
                    {
                        totaltokens += 2;
                    }

                    if (!parser.CheckToken(totaltokens, ")"))
                    {
                        return(null);
                    }

                    ++totaltokens;

                    // TODO - register function-typed structure members
                }
                else
                {
                    int typestarttoken = totaltokens;
                    var membertype     = parser.PeekToken(totaltokens);

                    ++totaltokens;
                    int typeendtoken = totaltokens;

                    var membername = parser.PeekToken(totaltokens);

                    ++totaltokens;

                    if (membername.Text.Equals("<"))
                    {
                        int starttotal = totaltokens;
                        if (!parser.ParseTemplateArguments(totaltokens, membertype, out totaltokens))
                        {
                            return(null);
                        }

                        if (totaltokens <= starttotal)
                        {
                            return(null);
                        }

                        typeendtoken = totaltokens;

                        membername = parser.PeekToken(totaltokens);
                        ++totaltokens;
                    }

                    if (membername.Text.Equals("ref"))
                    {
                        typeendtoken = totaltokens;
                        membername   = parser.PeekToken(totaltokens);
                        ++totaltokens;
                    }

                    parsed.Object.Members.Add(new Member {
                        Name = membername, Type = TypeSignatureInstantiated.Construct(parser, typestarttoken, typeendtoken)
                    });
                }

                if (!parser.CheckToken(totaltokens, ","))
                {
                    moremembers = false;
                }
                else
                {
                    ++totaltokens;
                }
            }

            parser.ConsumeTokens(totaltokens);
            return(parsed);
        }