예제 #1
0
    /// <summary>Calculates if the child is the same type as parent (zero), or how many levels of inheritance it's
    /// removed from.  Returns -1 if the child isn't a subclass of (or equal to) the parent.</summary>
    public static int DistanceFrom(string child, string parent = "anything")// StandardType st, StandardType from = StandardType.anything)
    {
        int distance;

        for (distance = 0; child != null && child != parent; distance++)
        {
            child = InheritanceTree.Find(item => item.name == child).parent;
        }
        if (child != parent)
        {
            distance = -1;
        }
        return(distance); // Distance of 0 means same exact type. Distance of 1 means one's a direct parent, etc.
    }
예제 #2
0
    /// <summary>Returns the parent of the passed-in type. Returns Anything for unrecognized types as well as Anything
    /// itself.  Returns Object (which is assumed) for types which claim to have no parent.  (Those were implicitly
    /// created by a "list of" construction, and will presumably be filled in later.) </summary>
    public static StandardType ParentOf(StandardType st)
    {
        if (st == StandardType.anything)
        {
            return(StandardType.anything);                             // anything is anything, the root type
        }
        InheritedType it = InheritanceTree.Find(item => item.typeid == st);

        if (it == null)
        {
            return(StandardType.anything);
        }
        if (it.parent == null)
        {
            return(StandardType.Object);                   // only happens with used but undefined types
        }
        return(InheritanceTree.Find(item => item.name == it.parent).typeid);
    }
예제 #3
0
    /*public static void TestInheritanceTree()
     * {
     *  IsA(StandardType.number, StandardType.number);
     *  Console.WriteLine("Is {0} a {1}? {2}.", StandardType.number, StandardType.number, (distance > -1));
     *  IsA(StandardType.number, StandardType.valueType);
     *  Console.WriteLine("Is {0} a {1}? {2}.", StandardType.number, StandardType.valueType, (distance > -1));
     *  IsA(StandardType.Object, StandardType.anything);
     *  Console.WriteLine("Is {0} a {1}? {2}.", StandardType.Object, StandardType.anything, (distance > -1));
     *  IsA(StandardType.anything, StandardType.anything);
     *  Console.WriteLine("Is {0} a {1}? {2}.", StandardType.anything, StandardType.anything, (distance > -1));
     *  IsA(StandardType.text, StandardType.valueType);
     *  Console.WriteLine("Is {0} a {1}? {2}.", StandardType.text, StandardType.valueType, (distance > -1));
     *  IsA(StandardType.text, StandardType.reference);
     *  Console.WriteLine("Is {0} a {1}? {2}.", StandardType.text, StandardType.reference, (distance > -1));
     *  IsA(StandardType.number, StandardType.percent);
     *  Console.WriteLine("Is {0} a {1}? {2}.", "number", "percent", (distance > -1));
     *  IsA(StandardType.percent, StandardType.number);
     *  Console.WriteLine("Is {0} a {1}? {2}.", "percent", "number", (distance > -1));
     *  IsA(StandardType.number, StandardType.anything);
     *  Console.WriteLine("Is {0} a {1}? {2}.", "number", "anything", (distance > -1));
     *  IsA(StandardType.number, StandardType.something);
     *  Console.WriteLine("Is {0} a {1}? {2}.", "number", "something", (distance > -1));
     *  /*IsA(StandardType.money, StandardType.car);
     *  Console.WriteLine("Is {0} a {1}? {2}.", "money", "car", (distance > -1));
     *  IsA("car", "object");
     *  Console.WriteLine("Is {0} a {1}? {2}.", "car", "object", (distance > -1));
     *  IsA("car", "something");
     *  Console.WriteLine("Is {0} a {1}? {2}.", "car", "something", (distance > -1));
     * }*/

    /// <summary>Returns the name of the given StandardType, including newly-defined types in the source. </summary>
    public static string NameOfType(StandardType?s)
    {
        if (s == null)
        {
            return("whatever");
        }
        var st = s.Value;

        if (st <= StandardType.anything)
        {
            return(StandardType.anything.ToString());
        }
        if (st < StandardType.Count)
        {
            return(st.ToString());
        }
        InheritedType it = InheritanceTree.Find(item => item.typeid == st);

        return(it.name);
    }
예제 #4
0
    /// <summary>Part of CreateParameterObject, which does the work for ParseNounPhraseForParameter.
    /// When declaring the parameters of a function's signature, this helper digests the "many..." parameter, which isn't
    /// a trivial operation, considering that lists have subtypes, some of which may not be known yet.</summary>
    static parameter CreateListParameterObject(ref StandardType?type, string ident, bool adjnounswap)
    {
        if (ident == null && type == null)
        {
            Console.WriteLine("  ERROR: many whats?");
            method_being_constructed.problems++;
            return(new parameter("", ident, Article.many, (StandardType)0, adjnounswap));
        }

        //either ident has value, type has value, or both have value
        // if basetype has value, then ident must not be a type. i.e., warn of "numeric car" or "many numeric cars" when car is of type object
        if (ident.HasValue() && type.HasValue)
        {
            InheritedType it = InheritanceTree.Find(item => item.name == ident);
            if (it != null && it.typeid != type.Value)
            {
                Console.WriteLine("  WARNING: '{0}' is declared elsewhere as a '{1}', not a '{2}'", it.name, NameOfType(it.typeid), NameOfType(type.Value));
            }
        }

        // for the term "several/many/multiple numbers", set ident to the whole term "many numbers" -- a generated name
        if (string.IsNullOrEmpty(ident))
        {
            ident = string.Format("many {0}", type);
        }

        // for the term "many gadgets", set type to "gadgets" by finding the type by name, or making a new one
        if (type == null)
        {
            InheritedType subtype = InheritanceTree.Find(item => item.name == ident);
            if (subtype == null)
            {   // make a new type, "gadgets", whose parent (and subtype, if applicable) to be filled out later?
                subtype = new InheritedType()
                {
                    name = ident, typeid = (StandardType)(InheritanceTree.Count + 2)
                };
                InheritanceTree.Add(subtype);
            }
            type = subtype.typeid;
        }

        // now all three are populated:  mode, type, ident
        // now, does our composite type already exist? Else make a new typeid
        string        typeAsString = type.Value.ToString();
        InheritedType aggregate    = InheritanceTree.Find(item => item.name == ident && item.parent == StandardType.list.ToString() && item.subtypes == typeAsString);

        if (aggregate != null)
        {
            Console.WriteLine("  another '{0}' (a list of {1})", ident, NameOfType(type.Value));
            return(new parameter("", ident, Article.many, type.Value, adjnounswap));
        }
        aggregate = new InheritedType()
        {
            name = ident, parent = StandardType.list.ToString(), subtypes = type.Value.ToString(), typeid = (StandardType)(InheritanceTree.Count + 2)
        };
        InheritanceTree.Add(aggregate);
        just_declared_new_type = true;

        string typename = NameOfType(type.Value);

        if (ident != typename)
        {
            Console.WriteLine("  a list of {0}, called {1}", typename, ident);
        }
        else
        {
            Console.WriteLine("  a list of {0}", typename);
        }

        return(new parameter("", ident, Article.many, type.Value, adjnounswap));
    }
예제 #5
0
    /// <summary>When defining a parameter of a new function's signature, and once parsing of that parameter is done, this converts
    /// the information into a parameter object. Uses CreateListParameterObject since that is a tome in itself.</summary>
    static parameter CreateParameterObject(string[] words, Article?mode, StandardType?type, StandardTypeAdjective?adjtype, string ident, bool identIsAdjectiveTypeIsNoun = false, bool isSubject = false)
    {
        // something/nothing/anything aren't preceded by an article. Treat as "a thing"
        if (type.HasValue && type <= StandardType.something)
        {
            Console.WriteLine("  declaring a parameter which {0}", type == StandardType.nothing ? "must be nothing" : type == StandardType.anything ? "could be anything" : "mustn't be nothing");
            return(new parameter("", type.Value.ToString(), Article.a, type.Value, identIsAdjectiveTypeIsNoun));
        }

        switch (mode)
        {
        case Article.the:
            if (type.HasValue)
            {
                if (adjtype == null)
                {
                    Console.WriteLine("ERROR: we say 'the {0}' to use it later in the sentence. Here we should say 'a {0}'.", NameOfType(type.Value));
                }
                else
                {
                    Console.WriteLine("ERROR: we say 'the {0}' to use it later in the sentence. Here we should say 'a {0} {1}'.", adjtype, ident == "" ? "name-of-it" : ident);
                }
                method_being_constructed.problems++;
                return(null);
            }
            if (isSubject || isQuestion)
            {
                just_declared_new_type = isSubject;     // and a global instance, as well
                return(new parameter("", ident, mode ?? Article.the, type ?? StandardType.number, identIsAdjectiveTypeIsNoun));
            }
            Console.WriteLine("ERROR: we should use 'a' not 'the' in this part of the sentence.");
            method_being_constructed.problems++;
            return(null);

        case Article.many:
            return(CreateListParameterObject(ref type, ident, identIsAdjectiveTypeIsNoun));

        case Article.a:
            if (type.HasValue)     // also, should we disallow it when the ident is also a type? "numeric car"
            {
                Console.WriteLine("  declaring a parameter of type {0} called '{1}'", NameOfType(type.Value), ident);
                InheritedType it = InheritanceTree.Find(item => item.name == ident);
                if (it != null && it.typeid != type.Value)
                {
                    Console.WriteLine("  WARNING: '{0}' is declared elsewhere as a '{1}', not a '{2}'", it.name, NameOfType(it.typeid), NameOfType(type.Value));
                }
            }
            else if (isQuestion && incarnations == TheVerbIs)
            {
                for (IdentEndsAt = index; IdentEndsAt < words.Length && words[IdentEndsAt] != "?"; IdentEndsAt++)
                {
                    ;
                }
                if (IdentEndsAt >= words.Length)
                {
                    Console.WriteLine("  ERROR: I thought #{0} was a question because it began with '{1}', but I couldn't find a question mark afterward.", method_being_constructed.prompt, method_being_constructed.question);
                    method_being_constructed.problems++;
                    return(null);
                }
                Console.WriteLine("  defining a {0} by Q&A.", ident);
                ident = ParseNewIdentifier(words, ref type);
            }
            else if (!isSubject)
            {
                if (ident == "")     // then we have no type info whatsoever. Just get a new ident
                {
                    ident = ParseNewIdentifier(words, ref type);
                }
                Console.WriteLine("  TODO: is '{0}' textual? Numeric? Or something more complex?", ident);
                method_being_constructed.todo++;
            }
            // defining a new type
            else if (InheritanceTree.Find(item => item.name == ident) != null)
            {
                Console.WriteLine("  ERROR: re-defining type '{0}'.", ident);
                method_being_constructed.problems++;
                //return null; // let it parse for now
                return(new parameter("", ident, mode ?? Article.a, type ?? (StandardType)0, identIsAdjectiveTypeIsNoun));
            }
            else
            {
                // object until proven otherwise. heck, it may not even be a type, it might be an instance or variable.
                var newType = CreateNewType(ident);
                Console.WriteLine("  assuming '{0}' is a new type", newType.name, newType.typeid);
            }
            break;

        case null:
            if (type == null)
            {
                return(null);
            }
            if (ident == null)
            {
                Console.WriteLine("  plural(?) parameter of type {0}", type);
            }
            else
            {
                Console.WriteLine("  plural(?) parameter of type {1} called the {0}", ident, NameOfType(type.Value));
            }
            break;
        }
        return(new parameter("", ident, mode ?? Article.a, type ?? (StandardType)0, identIsAdjectiveTypeIsNoun));
    }