/// <summary>A somewhat high-level function to parse (only) a single indeterminate noun phrase like "a numeric entry", "a number", /// "a car", "a vertical percentage", "several cars", "anything", "the manager" (if the NP is the subject of its /// sentence), "many gadgets" (when gadget itself hasn't been established yet), or a number of specifically invalid /// combinations, that describes a typed parameter in the definition of a multimethod's signature. /// Will soon need ability to parse -ing phrases and sub-predicates as in "To learn (repairing a car with a tool)". /// Uses ParseArticle, ParseNewIdentifier, ParseAdjectiveType, Parse enum, ParseAnyType, and multiple NameOfType. /// Finally calls CreateParameterObject after all but the worst parses. /// </summary> static parameter ParseNounPhraseForParameter(string[] words, bool isSubject = false) { StandardType?type = null; string ident = ""; int savedIndex = index; bool identIsAdjectiveTypeIsNoun = false; // usually if the type is the noun, there is no adjective: "the task" // and usually if both adj & noun are present, the type is the adjective: "the numeric virtue" // this is for constructions like "the horizontal percent, the vertical percent" // step 1: try parsing "something", "an adjective-type noun" "nountype", etc., or as a last resort, just a new identifier Article? mode = ParseArticle(words) ?? ((isQuestion && isSubject) ? Article.a : (Article?)null); OtherParameterTypes? opt = Parse <OtherParameterTypes>(words[index]); StandardTypeAdjective?adjtype = ParseAdjectiveType(words); if (adjtype != null) { ident = ParseNewIdentifier(words, ref type); if (type != null && type != (StandardType)adjtype) { Console.WriteLine("ERROR: I'm unsure whether '{0} {1}' is a {1} nicknamed {0} or is something {0} nicknamed {1}.", adjtype, type); method_being_constructed.problems++; return(null); } type = (StandardType)adjtype; if (ident == "") { Console.WriteLine("ERROR: must provide a name after the adjective '{0}' or use its noun form instead, '{1}'.", adjtype, (StandardType)adjtype); method_being_constructed.problems++; return(null); } } else if (opt != null) { type = (StandardType)opt; } else { fiveforms ing = PresentParticiple(words[index]); if (ing != null) { return(CreateFunctionParameterObject(words, ing, isSubject)); } type = ParseAnyType(words); ident = (type == null) ? "" : NameOfType(type.Value); } if (ident == "" && type == null /*&& isSubject*/) // then we have no type info whatsoever. Just get a new ident { ident = ParseNewIdentifier(words, ref type); identIsAdjectiveTypeIsNoun = (type != null); } if (type == null && mode == null) { // if we know nothing, abort index = savedIndex; return(null); } return(CreateParameterObject(words, mode, type, adjtype, ident, identIsAdjectiveTypeIsNoun, isSubject)); }
/// <summary>This is used while defining a higher-order function, tipped off by the -ing verb form that leads.</summary> static parameter CreateFunctionParameterObject(string[] words, fiveforms ing, bool isSubject = false) { long savedIndex = index; multimethod outerMethod = method_being_constructed; string savedDefinedVerb = definedVerb; method_being_constructed = new multimethod() { prompt = -outerMethod.prompt, question = "" }; multimethod innerMethod = PredicateDefinition2(words, ing, isSubject); // returns method_being_constructed method_being_constructed = outerMethod; definedVerb = savedDefinedVerb; return(new parameter(innerMethod)); }
/// <summary> Creates a parameter name for use in the function body like "the thing given" or "the person given to" </summary> static parameter NamedParameter(parameter noun_phrase_being_constructed, fiveforms verb, bool isSubject = false) { //parameter noun_phrase = noun_phrase_being_constructed; if (noun_phrase_being_constructed.preposition == "" && !isSubject) { HandleSwappedDirectandIndirectObjects(method_being_constructed, "to", verb, isSubject); } foreach (term part_of_speech in method_being_constructed.signature) { if (part_of_speech.which != PartsOfSpeech.noun) { continue; } if (part_of_speech.noun == noun_phrase_being_constructed) { break; } if (part_of_speech.noun.type == noun_phrase_being_constructed.type) // is the noun a Integer? Percentage? Ranking? { noun_phrase_being_constructed.position++; // then it shall be the first/second/third integer/task/customer } } if (noun_phrase_being_constructed.position == 2) // then find the first "the TYPE" and change it to "the first TYPE" { foreach (term np in method_being_constructed.signature) { if (np.which != PartsOfSpeech.noun) { continue; } if (np.noun.type == noun_phrase_being_constructed.type) { np.noun.fullname2 = "first " + np.noun.fullname2; break; } } } CreateFullNames(noun_phrase_being_constructed, verb, isSubject); return(noun_phrase_being_constructed); }
/// <summary>Creates the names by which the given parameter will be invoked: the thing given, the person given to, etc.</summary> static void CreateFullNames(parameter noun_phrase, fiveforms verb, bool isSubject = false) { if (noun_phrase.isAggregate) // it's a gerund, or participial phrase, etc. { return; } noun_phrase.fullname1 = noun_phrase.name + ((verb == TheVerbIs) ? "" : " " + ((isSubject) ? verb._ing : verb._en)); if (noun_phrase.preposition != "") { noun_phrase.fullname1 += " " + noun_phrase.preposition; } noun_phrase.fullname2 = noun_phrase.name; // given name. But, if the name is just the type, then.. if (noun_phrase.position > 1) { if (Contains <StandardType>(noun_phrase.name) || Contains <StandardTypePlural>(noun_phrase.name)) { noun_phrase.fullname2 = NumberToSpelledOutOrdinal(noun_phrase.position) + " " + noun_phrase.name; // TODO translate int to ordinal } } }
static void VerifyAbstractSyntaxTree() { // now check the whole abstract syntax tree // First, is there one and only one root? "To do:" fiveforms rootverb = FindVerb("do"); multimethod main = null; if (mms.ContainsKey(rootverb)) { foreach (multimethod possibleRoot in mms[rootverb]) { if (possibleRoot.signature.Count == 1) { if (main == null) { main = possibleRoot; } else { Console.WriteLine(" ERROR: I have too many definitions for \"To do:\", like #{0} and #{1}", main.prompt, possibleRoot.prompt); } } } } if (main == null) { Console.WriteLine(" ERROR: Where does the whole thing start? I need a sentence which begins, \"To do:\""); } else { main.called++; } // dead code elimination? unused structs elimination? }
/// <summary> Once a string has been converted to a verb (fiveforms), this parses the parameter list via multiple calls to /// ParseNounPhraseForParameter and its own list delimiter parsing. Returns the defined verb as a convenience, but the real /// result is added to the global multimethods collection. </summary> static multimethod PredicateDefinition2(string[] words, fiveforms incarnations, bool isSubject = false) { method_being_constructed.signature.Add(new term(incarnations)); definedVerb = words[index]; string preposition = ""; bool found_official_preposition = false; TheGiveSomebodyItException = DirectObjectPlacement.not_there_yet; do { index++; while (!stringnums.EndsInfinitiveDefinition.Contains(words[index])) { if (stringnums.EOL.Contains(words[index])) { goto doublebreak; } parameter noun_phrase = ParseNounPhraseForParameter(words); if (noun_phrase == null) { if (!stringnums.ListSeparators.Contains(words[index])) { if (!found_official_preposition) // after a preposition, there shouldn't be any words related to the verb. { if (isSubject && FindMainVerb(words[index]).HasValue()) { goto doublebreak; } if (preposition != "") { preposition += " "; } preposition += words[index]; // so, "the person given to", not, "the person given to just" } if (stringnums.prepositions.Contains(words[index])) { found_official_preposition = true; } } index++; } else { if (preposition != "") { method_being_constructed.signature.Add(new term(preposition)); } method_being_constructed.signature.Add(new term(noun_phrase, preposition)); preposition = ""; found_official_preposition = false; } } // if the next word is "a/an/another", then we are probably in a list. // if it were a function body starting, it would likely be "the" } while (stringnums.IndefiniteArticles.Contains(words[index + 1]) || stringnums.ListDeterminers.Contains(words[index + 1]) || stringnums.ListSeparators.Contains(words[index + 1])); doublebreak: if (preposition != "") { method_being_constructed.signature.Add(new term(preposition)); } return(method_being_constructed); }
/// <summary>For cases of "give someone the thing", we must back up and add "to" to the "someone"</summary> static void HandleSwappedDirectandIndirectObjects(multimethod method_being_constructed, string prep, fiveforms verb, bool isSubject) { if (isSubject) { return; } if (listType != null) { return; } switch (TheGiveSomebodyItException) { case DirectObjectPlacement.not_there_yet: TheGiveSomebodyItException = DirectObjectPlacement.normal; break; case DirectObjectPlacement.normal: // then the previous parameter is the indirect, not direct, object, and needs "to" prepended for (int i = 0; method_being_constructed.signature.Count > i; i++) { if (method_being_constructed.signature[i].which == PartsOfSpeech.noun) { term newterm = method_being_constructed.signature[i]; newterm.noun.preposition = prep; method_being_constructed.signature[i] = newterm; CreateFullNames(method_being_constructed.signature[i].noun, verb); //not sure why this is still needed break; } } TheGiveSomebodyItException = DirectObjectPlacement.after_the_indirect_object; break; case DirectObjectPlacement.after_the_indirect_object: case DirectObjectPlacement.error: TheGiveSomebodyItException = DirectObjectPlacement.error; Console.WriteLine(" ERROR: I require those parameters to be separated by prepositions or commas."); method_being_constructed.problems++; break; } }
public term(fiveforms v) { which = PartsOfSpeech.verb; verb = v; }
/// <summary>Once the magic words that begin a relative clause are found ("the TYPE which..") by ParseInvokedNoun, /// this parses the rest of the invocation. Relative clauses invoke phrases or data structures and play a matching game with /// them. This is straightforward with data, but with imperative code we have to "go Prolog" for it to make sense /// even conceptually. </summary> static invocation ParseARelativeInvocation(theTypeWhich theTypeWhich, List <string> words) { subsubprompt++; // Handle passive voice constructions like "the type1 to which the type2 WAS GIVEN". string theIsUsed = ""; fiveforms relativeVerb = null; bool passiveVoice = (words[index] == "was" || words[index] == "were" || words[index] == "is" || words[index] == "are"); if (passiveVoice) { theIsUsed = words[index++]; relativeVerb = mms.SingleOrDefault(item => item.Key._en == words[index]).Key; if (relativeVerb == null) { passiveVoice = false; relativeVerb = TheVerbIs; index--; } } else { relativeVerb = mms.SingleOrDefault(item => item.Key.singular == words[index] || item.Key.plural == words[index] || item.Key.past == words[index]).Key; } /*if (relativeVerb != null) * { * bool pastTense = (words[index++] == relativeVerb.past); * * // now search all possible keywords & prepositions for all possible methods to see if the next word matches one of them * List<multimethod> submatches = new List<multimethod>(); * int invocationBeginsAt = index; * foreach (multimethod mm in mms[relativeVerb]) * { * index = invocationBeginsAt; * foreach (term t in mm.signature) * if (t.which == PartsOfSpeech.noun && Match(words, t.noun.preposition)) * if (IsA(theTypeWhich.type.typeid, t.noun.type)) * // "which gave" (imperative) vs. "which knows" (relation) * if ((pastTense && !mm.fully_parsed) || (!pastTense && mm.fully_parsed)) * { * submatches.Add(mm); * break; * } * } * if (submatches.Count == 0) * { * Console.WriteLine(" ERROR: In the relative clause 'which {0}{1}' I couldn't find any defined method for {2} which matched it", passiveVoice ? theIsUsed + " " : "", passiveVoice ? relativeVerb._en : pastTense ? relativeVerb.past : relativeVerb.singular, relativeVerb.singular); * index = savedIndex; * return null; * } * if (submatches.Count > 1) * { * Console.WriteLine(" ERROR: In the relative clause 'which {0}{1}' I found too many defined methods for {2}", passiveVoice ? theIsUsed + " " : "", passiveVoice ? relativeVerb._en : pastTense ? relativeVerb.past : relativeVerb.singular, relativeVerb.singular); * index = savedIndex; * return null; * } * Console.WriteLine(" relative clause matches #{0}", submatches[0].prompt); * }*/ // now parse the argument(s) being fed to it int savedIndex = index; List <multimethod> likely = passiveVoice ? mms[relativeVerb] : ParseInvocationByFirstWord(words); if (likely == null || likely.Count == 0) { Console.WriteLine("Cannot find any multimethod which fits this part of the relative clause: '{0}...'", words[index]); return(null); } List <invocation> matching = ParseAnInvocation2(words, likely, true, theTypeWhich); return(InvocationProblems(words, matching, likely, savedIndex, theTypeWhich)); }
/// <summary> /// This does a quick 'n shallow look through all the signatures to see which ones match the opening word of the /// invocation-to-be-parsed. Academically speaking, it's unnecessary. Practically speaking, it's better than nothing. /// </summary> public static List <multimethod> ParseInvocationByFirstWord(List <string> words) { var likely = new List <multimethod>(); string firstWord = words[index]; if (stringnums.DefiniteArticles.Contains(firstWord) || stringnums.IndefiniteArticles.Contains(firstWord) || stringnums.ListDeterminers.Contains(firstWord)) { firstWord = words[++index]; } int savedIndex = index; bool startsThe = (words[index] == "the"); while (words[index] == "the") { index++; } theTypeWhich theTypeWhich = IsNameOfTypeWhich(words); index = savedIndex; long?number = ParseNumberOrdinalPercent(words); index = savedIndex; bool TextLit = words[index].StartsWith("__litstring"); index = savedIndex; fiveforms aVerb = PresentParticiple(words[index]) ?? FindMainVerb(firstWord); index = savedIndex; bool IsPrep = stringnums.prepositions.Contains(firstWord); bool IsVerb = aVerb != null; bool IsNoun = startsThe || theTypeWhich != null || number != null || TextLit; bool CanBeNoun = !IsVerb && !IsPrep; foreach (var mm in multimethods) { switch (mm.signature[0].which) { case PartsOfSpeech.verb: if (IsVerb && mm.signature[0].verb.Contains(firstWord)) { likely.Add(mm); } break; case PartsOfSpeech.noun: if (mm.signature[0].noun.isAggregate) { likely.Add(mm); } if (CanBeNoun) { likely.Add(mm); } break; case PartsOfSpeech.preposition: if (IsPrep && firstWord == mm.signature[0].preposition) { likely.Add(mm); } break; } } return(likely); }
static void CodeGeneration() { // create file CodeGen codegen = new Flash(); codegen.Begin("complish"); codegen.WriteStringTable(literalStrings); foreach (multimethod method in multimethods) { if (method.parsed_body == null || method.parsed_body.Count == 0) { // it's data not code parameter subject = null; fiveforms verb = null; foreach (term term in method.signature) { if (term.which == PartsOfSpeech.verb) { verb = term.verb; break; } else if (term.which == PartsOfSpeech.noun) { subject = term.noun; } } if (verb == null) { continue; } bool subjectNamesStruct = (verb == TheVerbIs); if (subjectNamesStruct && subject == null) { continue;//compiler error? named instance? global var? } //Console.WriteLine("struct {0} {1} // #{2}{3}", subjectNamesStruct ? subject.fullname1.Replace(' ', '_') : verb.singular + "_relation", "{", method.prompt, method.problems > 0 ? " ?" : ""); foreach (term term in method.signature) { if (term.which != PartsOfSpeech.noun) { continue; } if (subjectNamesStruct && term.noun == subject) { continue; } /*if (term.noun.art != Article.many) * Console.WriteLine("\t{0} {1};", NameOfType(term.noun.type), term.noun.fullname1.Replace(' ', '_')); * else * Console.WriteLine("\tList<{0}> {1};", NameOfType(term.noun.type), term.noun.fullname1.Replace(' ', '_'));*/ } //Console.WriteLine("}"); //Console.WriteLine(); } else // it's code not data { ;// Console.WriteLine("#{0} called from {1} places", method.prompt, method.called); } } codegen.WriteInt(10); codegen.Finish(); Console.Write("---- press enter ----"); Console.ReadLine(); }
static int prompt = 1, subprompt, subsubprompt; // the sentence#, invocation#, and relative clause # ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// static void Main(string[] args) { ReadForms(); TheVerbIs = FindVerb("is"); InitNumberUnitSystem(); InitInheritanceTree(); string input = null; string[] words = null; int maxWords; TestHarness.loadTestScript("me"); for (Console.Write("{0}: ", prompt); (input = TestHarness.LineFeeder()) != null; TestHarness.EndTurn(2), Console.Write("{0}: ", ++prompt)) { TestHarness.BeginTurn(); // Move string literals into the string table, leaving placeholders behind. while (input.Contains('"')) { int from = input.IndexOf('"'); int endAt = from + 1; loopPastDquoteLiteral: endAt += input.Substring(endAt).IndexOf('"'); if (input.Length > endAt + 1 && input.ElementAt(endAt + 1) == '"') { endAt += 2; goto loopPastDquoteLiteral; } int len = endAt - (from + 1); string literal = input.Substring(from + 1, len); input = input.Substring(0, from - 1) + String.Format(" __litstring{0}__ ", literalStrings.Count) + input.Substring(endAt + 1); literalStrings.Add(literal.Replace("\"\"", "\"")); } // cleanse the input input = input.ToLowerInvariant() + " "; input = input.Replace(", ", " , ").Replace(". ", " . ").Replace(": ", " : ").Replace("? ", " ? "); input = input + " " + stringnums.EOL[0]; words = input.Split(new[] { ' ', '\t', '\n' }, StringSplitOptions.RemoveEmptyEntries); maxWords = (int)words.Count(); if (maxWords < 2) { break; // EOL is always appended } // debugging / testharness feature: input a line number if (maxWords == 2 && Int32.TryParse(words[0], out subjectAt)) { Console.WriteLine(TestHarness.testlines[--subjectAt * 3]); Console.WriteLine(TestHarness.testlines[subjectAt * 3 + 1]); Console.WriteLine(TestHarness.testlines[subjectAt * 3 + 2]); continue; } // meta / macro command: tell the compiler to run another file. if (maxWords == 3 && words[0] == "regard" && words[1].StartsWith("__litstring")) { TestHarness.loadTestScript(Say(words[1])); continue; } // initialize vars index = 0; definedVerb = ""; preposition = ""; method_being_constructed = new multimethod() { prompt = prompt, question = "" }; //method_being_constructed.prompt = prompt; subjectAt = -1; isQuestion = false; incarnations = null; listType = null; IdentEndsAt = maxWords; just_declared_new_type = false; // Absorb any prepositions at the beginning, as in "To give..." or "To boldly go..." or "To a person give...", etc. while (stringnums.prepositions.Contains(words[index])) { if (preposition != "") { preposition += " "; } preposition += words[index++]; } // if the first word(s) indicate a question, read it. //method_being_constructed.question = ""; /*if (stringnums.QuestionWords.Contains(words[index])) * { * string question = ""; * while (stringnums.QuestionWords.Contains(words[index])) * { * if (question != "") question += " "; * question += words[index++]; * } * incarnations = FindVerb(words[index]); // Catches "What is.." but not "Which car is..." * method_being_constructed.question = question; * isQuestion = true; * }*/ // if first word(s) indicated a subject, read it if (stringnums.DefiniteArticles.Contains(words[index]) || stringnums.IndefiniteArticles.Contains(words[index]) || stringnums.ListDeterminers.Contains(words[index]) || words[index].EndsWith("ing") || (method_being_constructed.question != "" && incarnations == null)) { ParseSubject(words); } if (prompt >= 37) { Console.WriteLine(); } // Regardless, parse the predicate: a verb and the nouns that go with. incarnations = PredicateDefinition(words); // If we haven't found a verb yet, but we do have a subject, look for the verb in the subject's name. if (incarnations == null && subjectAt >= 0) { string[] subnames = method_being_constructed.signature[subjectAt].noun.name.Split(' '); for (int i = subnames.Count() - 1; i >= 0; i--) { index--; incarnations = FindMainVerb(subnames[i]); if (incarnations == null) { continue; } // Ah, there's the verb. Shorten the subject's name, and try parsing the predicate again from this index position. definedVerb = subnames[i]; string newname = subnames[0]; for (int j = 1; j < i; j++) { newname += " " + subnames[j]; } method_being_constructed.signature[subjectAt].noun.name = newname; Console.WriteLine(" oops; verb is '{1}' and subject is '{0}'", newname, definedVerb); incarnations = PredicateDefinition(words); break; } } // If we still don't have a verb, we're going to have to search for it the long way. if (incarnations == null) { int savedIndex = index; while (incarnations == null && index < maxWords - 1 && !stringnums.EndsInfinitiveDefinition.Contains(words[index])) { incarnations = FindMainVerb(words[++index]); // this is an expensive loop } if (incarnations != null) { // ah, found it. There must be a subject in front of it... definedVerb = words[index]; IdentEndsAt = index; index = 0; // back to first word of sentence if (ParseSubject(words) == null) { method_being_constructed.signature.Add(new term(incarnations)); Console.Write("ERROR: verb is '{0}' but I don't know what to do with the subject: ", definedVerb); for (int i = savedIndex; i < IdentEndsAt; i++) { Console.Write("{0} ", words[i]); } Console.WriteLine(); method_being_constructed.problems++; multimethods.Add(method_being_constructed); continue; } index++; // advance past verb IdentEndsAt = (int)words.Count(); // un-set the hint var mm = PredicateDefinition2(words, incarnations); // and finish the predicate as normal multimethods.Add(mm); } } // If we STILL don't have a verb, abort this sentence. if (incarnations == null) { method_being_constructed.signature.Add(new term("...")); Console.Write("ERROR: I couldn't find a verb in: "); for (int i = 0; i < index; i++) { Console.Write("{0} ", words[i]); } Console.WriteLine(); method_being_constructed.problems++; multimethods.Add(method_being_constructed); continue; } //if (prompt == 32) // Console.WriteLine("debug"); // OK, we have a verb, and processed the rest of the definition with it. We should be at a marker separating // the function head from the function body. Or if it's a type/struct/object definition, we're at the end of // the sentence entirely. method_being_constructed.fully_parsed = stringnums.EOL.Contains(words[index]); if (stringnums.EndsInfinitiveDefinition.Contains(words[index])) { index++; // advance past the comma, colon, BY, VIA, MEANS, or whatever separates head from body } else if (words[index] != ".") { Console.WriteLine("I didn't expect this definition of '{1}' end with a '{0}'", words[index], definedVerb); method_being_constructed.problems++; continue; } // If we had a valid definition, save away its body. We can't parse the bodies until we read all the heads. // That's because what names, esp. parameter names and other function invocations, that appear in the bodies // aren't even known yet. if (!method_being_constructed.fully_parsed) { method_being_constructed.body = new List <string>(); while (index < maxWords - 1 && !stringnums.EOL.Contains(words[index])) { method_being_constructed.body.Add(words[index++]); //ParseParameterInvocation(words); } } // for case of "X is Y..." // if the subject is already a type, and is now being used with "IS" again, // Ensure we don't use a known type with "is" unless // 1) there's a "when", or // 2) the subject is "the" instance of the type, or // 3) the subject is a gerund phrase (function type), so the predicate is a categorical name, a "class" or "name of enum" for signatures if (subjectAt != -1 && incarnations._en == "been" && method_being_constructed.fully_parsed) { parameter theSubject = method_being_constructed.signature[subjectAt].noun; if (just_declared_new_type && theSubject.art == Article.the) { Console.WriteLine(" global variable or singleton instance '{0}' created", theSubject.name); PermanentDataSegment.Add(theSubject); } else if (theSubject.isAggregate && method_being_constructed.signature.Count == 3) { // "Xing... is Y." so define Y as a category for verbs var ident = method_being_constructed.signature[2].which == PartsOfSpeech.noun ? method_being_constructed.signature[2].noun.name : method_being_constructed.signature[2].preposition; var newType = CreateNewType(ident, StandardType.homogene); Console.WriteLine(" assuming '{0}' categorizes verbs", ident); } else if (!just_declared_new_type) { if (theSubject.type == StandardType.anything) { Console.WriteLine(" ERROR: I have no idea what a '{0}' is. It could be anything.", theSubject.name); } else { Console.WriteLine(" ERROR: trying to re-define the type '{0}'", NameOfType(theSubject.type)); } method_being_constructed.problems++; } } // Create the various names for each parameter in the new method. // This isn't perfect because we don't know where a noun phrase ends and where adverbs and verbs begin. // We'll keep it all as the possible noun phrase, but when we start parsing the body, we'll look at // what the parameters are actually called in there. Then we can shorten our parameter names to match // sensibly. TheGiveSomebodyItException = DirectObjectPlacement.not_there_yet; for (int i = 0; i < method_being_constructed.signature.Count; i++) { if (method_being_constructed.signature[i].which == PartsOfSpeech.noun) { term newterm = method_being_constructed.signature[i]; parameter oldparam = newterm.noun; newterm.noun = NamedParameter(oldparam, incarnations, (i == subjectAt)); method_being_constructed.signature[i] = newterm; } else if (method_being_constructed.signature[i].which == PartsOfSpeech.verb) { TheGiveSomebodyItException = DirectObjectPlacement.not_there_yet; } } // Now we should be at the end of line: a period, question mark, or exclamation mark // If not, throw a helpful error. method_being_constructed.problems++; if (index >= words.Count()) { Console.WriteLine("COMPILER ERROR: EOL eaten: index too high"); } else if (words[index] != "ENDOFINPUT" && words[index] != ".") { if (index < words.Count()) { Console.WriteLine(" ERROR: I wasn't expecting '{0}' there, but rather, the end of the sentence.", words[index]); } else { Console.WriteLine("COMPILER ERROR: EOL eaten"); } } else { method_being_constructed.problems--; } // Sentence processed. Get next sentence } TestSignatures(); Pass2ResolveImplicitTypesAndCreateMultimethodDictionary(); Pass3MethodBodies(); VerifyAbstractSyntaxTree(); CodeGeneration(); }
/// <summary>Stub. Get the proper inflection for the passed-in verb, which is presumably in its root form.</summary> static string FormOf(Inflections inflection, string verb) { // first of all, for the verb "is", handle it separately // (note that "is" does exist in the FindVerb list as the first element, but it's obviously missing a few forms) if (stringnums.InflectionsOfIs.Contains(verb)) { switch (inflection) { case Inflections.root: return("were"); // whatever case Inflections.infinitive: return("to be"); case Inflections.singular: return("is"); case Inflections.plural: return("are"); case Inflections.past: return("was"); // one of them, anyway case Inflections.present_participal: return("being"); case Inflections.past_participal: return("been"); default: return("am"); } } // second, is it one of the irregular ones that have all five forms? fiveforms f5 = FindVerb(verb); if (f5 != null) { switch (inflection) { case Inflections.singular: return(f5.singular); case Inflections.plural: return(f5.plural); case Inflections.past: return(f5.past); case Inflections.present_participal: return(f5._ing); case Inflections.past_participal: return(f5._en); } } // for now, make stuff up switch (inflection) { case Inflections.root: return(verb); // used for the imperative invocation case Inflections.infinitive: return("to " + verb); // used for the infinitive definition case Inflections.singular: return(verb + "s"); // used for relations case Inflections.plural: return(verb); // used for relations case Inflections.past: return(verb + "ed"); case Inflections.present_participal: return(verb + "ing"); // used for continuous tense & for gerund (noun phrase) case Inflections.past_participal: return(verb + "n"); // used for perfect tense & for adjective } return(verb); }