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); }
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); }
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); }