Beispiel #1
0
 bool IsAgentsEyes(ObjSpec obj)
 {
     if (obj.referredToAs == "eyes" && obj.owner == Owner.You)
     {
         return(true);
     }
     return(false);
 }
Beispiel #2
0
        private bool isObjAssignable(ObjSpec sObj, ObjSpec slotObj)
        {
            C.Nn(sObj, slotObj);

            foreach (var slotMember in slotObj.Env.Items)
            {
                var sMember = sObj.Env.GetFromThisEnvOnlyOrNull(slotMember.Key.Ident, null);
                if (sMember == null || !isAssignable(sMember.Value, slotMember.Value.Value))
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #3
0
        private void specStm(Stm e, Env <Spec> env)
        {
            C.Nn(e, env);

            switch (e)
            {
            case Declr d:
                if (d.Exp == null)
                {
                    env.Declare(d, NotSetSpec.Instance);
                }
                else
                {
                    env.Declare(d, specExp(d.Exp, env, AnySpec.Instance));
                    if (d.Exp is Ident fromIdent)
                    {
                        d.AssignedFrom.Add(fromIdent);
                    }
                    d.Ident.Spec = d.Exp.Spec;
                }

                break;

            case Assign a:
                switch (a.To)
                {
                case Ident ident:
                {
                    var orig  = env.Get(ident, true).Value;
                    var slot3 = orig == NotSetSpec.Instance ? AnySpec.Instance : orig;
                    var s     = specExp(a.Exp, env, slot3);
                    if (orig == NotSetSpec.Instance)
                    {
                        env.Set(ident, s);
                    }
                    if (a.Exp is Ident fromIdent)
                    {
                        a.AssignedFrom.Add(fromIdent);
                    }

                    break;
                }

                case MemberAccess ma:
                {
                    var minObjEnv = env.Create();
                    var declr     = new Let(
                        new Ident(ma.Ident.Name, ma.Ident.TokenType)
                        .CopyInfoFrom(ma.Ident, true), Void.Instance);
                    minObjEnv.Declare(declr, AnySpec.Instance);
                    var minObj = new ObjSpec(minObjEnv);
                    var maExpS = specExp(ma.Exp, env, minObj);
                    if (maExpS is ObjSpec objS)
                    {
                        var orig  = objS.Env.Get(ma.Ident, true).Value;
                        var slot3 = orig == NotSetSpec.Instance ? AnySpec.Instance : orig;
                        var s     = specExp(a.Exp, env, slot3);
                        if (orig == AnySpec.Instance)
                        {
                            objS.Env.Set(ma.Ident, s);
                            a.AssignedFrom.Add(ma.Ident);
                        }
                    }

                    break;
                }

                default:
                    throw new NotSupportedException();
                }

                break;

            case Return r:
                var slot2 = returns.Peek();
                var retS  = specExp(r.Exp, env, slot2 == NotSetSpec.Instance ? AnySpec.Instance : slot2);
                returns.UpdateTop(retS);
                break;

            case Loop l:
                specSequence(l.Body, env);
                break;

            case Break _:
                break;

            case Continue _:
                break;

            case Toss ts:
                var _ = specExp(ts.Exception, env, AnySpec.Instance);
                // TODO requires exp to be of some type?
                break;

            case Attempt att:
                specSequence(att.Body, env);
                if (att.Grab != null)
                {
                    var grabEnv = env.Create();
                    var exDeclr = new Let(new Ident("exception", TokenType.Ident));
                    grabEnv.Declare(exDeclr, AnySpec.Instance);
                    specSequence(att.Grab, grabEnv);
                }

                if (att.AtLast != null)
                {
                    specSequence(att.AtLast, env);
                }
                break;

            case Import imp:
                isImportContext = true;
                var objSpecWithNoMembers = new ObjSpec(env.Create());
                var modImpEl             = specExp(imp.QualifiedIdent, env, objSpecWithNoMembers);
                isImportContext = false;
                if (modImpEl is ObjSpec modImp)
                {
                    env.AddImport(imp.QualifiedIdent, modImp.Env, (Declr)modImp.Parent);
                }
                break;

            case Sequence seq:
                specSequence(seq, env);
                break;

            default:
                throw new NotSupportedException();
            }
        }
Beispiel #4
0
        private Spec specExp2(Exp exp, Env <Spec> env, Spec slot)
        {
            C.Nn(exp, env, slot);
            C.ReturnsNn();

            Spec ss;

            switch (exp)
            {
            case Ident i:
                if (isImportContext)
                {
                    return(env.GetWithoutImports(i).Value);
                }
                else
                {
                    var orig = env.Get(i).Value;

                    if (orig == NotSetSpec.Instance || orig == AnySpec.Instance)
                    {
                        //prog.RemarkList.AttemptToReadUninitializedVariableWarn(i);
                        setIdentAndAssignedFrom(env, i, slot);
                        return(slot);
                    }

                    if (!isAssignable(orig, slot))
                    {
                        prog.RemarkList.CannotConvertType(orig, slot, i);
                    }
                    return(orig);
                }

            case FnApply fna:
            {
                if (fna.Fn is Ident fnI && fnI.Name == "typeof")
                {
                    if (!(fna.Arguments[0] is Spec))
                    {
                        fna.Arguments = new FnArguments(new List <Exp> {
                                specExp(fna.Arguments[0], env, AnySpec.Instance)
                            });
                    }
                    return(VoidSpec.Instance);
                }

                var orig = specExp(fna.Fn, env, AnySpec.Instance);

                if (orig is FnSpec fnS)
                {
                    if (fnS.ParameterSpec.Count != fna.Arguments.Count)
                    {
                        throw prog.RemarkList.ParameterArgumentCountMismatch(fna, fnS.ParameterSpec.Count);
                    }

                    var argumentSpecs = new List <Spec>();
                    var ix            = 0;
                    foreach (var aa in fna.Arguments)
                    {
                        var pS = fnS.ParameterSpec[ix];
                        var aS = specExp(aa, env, pS);
                        argumentSpecs.Add(isAssignable(aS, pS) ? aS : pS);
                        ++ix;
                    }

                    if (fna.Arguments.Count != 0 && fnS.Fn?.SpecEnv != null)
                    {
                        var newFn  = new Fn(fnS.Fn.Parameters, fnS.Fn.Sequence, fnS.Fn.SpecEnv).CopyInfoFrom(fnS.Fn);
                        var newFnS = specFn(newFn, null, argumentSpecs);
                        fnS = newFnS;
                    }

                    if (!isAssignable(fnS.ReturnSpec, slot))
                    {
                        prog.RemarkList.CannotConvertType(fnS.ReturnSpec, slot, fna);
                    }

                    return(fnS.ReturnSpec);
                }

                var sigS = new List <Spec>();
                foreach (var aa in fna.Arguments)
                {
                    var aS = specExp(aa, env, AnySpec.Instance);
                    sigS.Add(aS);
                }

                sigS.Add(slot == NotSetSpec.Instance ? AnySpec.Instance : slot);

                var newFnSpec = new FnSpec(sigS, null);
                if (fna.Fn is Ident fnI2)
                {
                    env.Set(fnI2, newFnSpec);
                }

                return(slot);
            }

            case Fn f:
                return(specFn(f, env));

            case When w:
                var _     = specExp(w.Test, env, BoolSpec.Instance);
                var thenS = specSequenceItem(w.Then, env, slot);
                if (w.Otherwise == null)
                {
                    return(VoidSpec.Instance);
                }
                else
                {
                    var otherwiseS = specSequenceItem(w.Otherwise, env, slot);
                    if (!areSame(thenS, otherwiseS))
                    {
                        prog.RemarkList.CannotConvertType(thenS, otherwiseS, w.Otherwise);
                    }
                    return(thenS);
                }

            case ArrConstructor ae:
                var s          = new ArrSpec(commonType(ae.Arguments, env));
                var notSetArgs = ae.Arguments.OfType <Ident>().ToList();
                foreach (var a in notSetArgs)
                {
                    var orig2 = env.Get(a).Value;
                    if (isAssignable(s.ItemSpec, orig2))
                    {
                        setIdentAndAssignedFrom(env, a, s.ItemSpec);
                    }
                }

                return(s);

            case MemberAccess ma:
                ss = specExp(ma.Exp, env, NotSetSpec.Instance);
                var mai = ma.Ident;
                if (ss is NotSetSpec || ss is AnySpec)
                {
                    var objSEnv = env.Create();
                    var objS    = new ObjSpec(objSEnv)
                    {
                        FromUsage = true
                    };
                    var declr = new Var(new Ident(mai.Name, mai.TokenType).CopyInfoFrom(mai, true));
                    objSEnv.Declare(declr, slot);
                    var __ = specExp(mai, objSEnv, slot);
                    ss = objS;
                    if (ma.Exp is Ident i)
                    {
                        setIdentAndAssignedFrom(env, i, objS);
                    }
                }

                var objS2 = ss as ObjSpec;
                if (objS2 == null)
                {
                    throw prog.RemarkList.OnlyObjectsCanHaveMembers(ma, ss);
                }
                if (objS2.FromUsage)
                {
                    var member = objS2.Env.GetFromThisEnvOnlyOrNull(mai, null);     // also use type and var/let?
                    if (member == null)
                    {
                        var declr = new Var(new Ident(mai.Name, mai.TokenType).CopyInfoFrom(mai, true));
                        objS2.Env.Declare(declr, slot);
                        var __ = specExp(mai, objS2.Env, slot);
                    }
                }

                var objSpec = (ObjSpec)ss;
                ss = objSpec.Env.GetFromThisEnvOnly(mai, null).Value;
                return(ss);

            case New n:
                var objEnv = env.Create();
                foreach (var classItem in n.Body)
                {
                    specStm(classItem, objEnv);
                }
                return(new ObjSpec(objEnv)
                {
                    Parent = n.Parent
                });

            case Text _:
                return(TextSpec.Instance);

            case Bool _:
                return(BoolSpec.Instance);

            case Builtin bu:
                return(bu.FixedSpec);

            case Char _:
                return(CharSpec.Instance);

            case Int _:
                return(IntSpec.Instance);

            case Void _:
                return(VoidSpec.Instance);

            default:
                throw new NotSupportedException();
            }
        }
Beispiel #5
0
        public static ActionSpec GrokAction(ParseState st, int verbIdx)
        {
            //UnityEngine.Debug.Log("GrokAction: " + st.ToString() + " with verb at " + verbIdx);
            var    act  = new ActionSpec();
            string verb = st.words[verbIdx].ToLower();

            switch (verb)
            {
            case "grab":
            case "pick_up":
                act.action = Action.PickUp;
                break;

            case "drop":
            case "set_down":
            case "put_down":
                act.action = Action.SetDown;
                break;

            case "say":
                act.action = Action.Say;
                break;

            case "put":
            case "set":
            case "place":
                act.action = Action.Put;
                break;

            case "close":
                act.action = Action.Close;
                break;

            case "open":
                act.action = Action.Open;
                break;

            case "raise":
            case "lift":
                act.action = Action.Raise;
                break;

            case "lower":
                act.action = Action.Lower;
                break;

            case "look":
            case "look_at":
                act.action = Action.Look;
                break;

            case "point":
                act.action = Action.Point;
                break;

            case "stop":
                act.action = Action.Stop;
                break;

            case "thank":
            case "thank_you":
                // whoops, this isn't an action, it's a phatic comment.
                return(null);

            case "stand_by":
                act.action = Action.StandBy;
                break;
            }

            // Check for specific action idioms.
            string verbTree = st.TreeForm(verbIdx);

            if (verbTree == "VB[is RB[enough]]" && verbIdx > 0 && st.words[verbIdx - 1] == "that")
            {
                // that's enough: idiom for "stop"
                act.action = Action.Stop;
            }

            var kids = st.ChildrenOf(verbIdx);

            if (kids != null)
            {
                foreach (int i in kids)
                {
                    if (st.partOfSpeech[i] == PartOfSpeech.NN)
                    {
                        ObjSpec obj = GrokObject(st, i);
                        act.directObject = obj;
                        if (obj.referredToAs == "hand" && verb == "follow")
                        {
                            // "Follow my hand" idiom
                            act.action = Action.Point;
                        }
                    }
                    if (st.partOfSpeech[i] == PartOfSpeech.WRB)
                    {
                        // e.g.: [VB[point WRB[where]] VB[NN[I] point]]
                        // For now, we'll assume any "where" clause boils down to:
                        act.direction = new DirectionSpec(DirectionSpec.Direction.WhereUserPoints);
                    }
                    if (st.partOfSpeech[i] == PartOfSpeech.RB)
                    {
                        if (st.words[i] == "up" && verb == "pick")
                        {
                            act.action = Action.PickUp;
                        }
                        else if (st.words[i] == "down" && (verb == "put" || verb == "set" || verb == "place"))
                        {
                            act.action = Action.SetDown;
                        }
                        else if (st.words[i] == "here" || st.words[i] == "there" ||
                                 st.words[i] == "over_here" || st.words[i] == "over_there")
                        {
                            act.location = new LocationSpec()
                            {
                                relation = LocationSpec.Relation.Indicated
                            };
                        }
                    }
                }
            }

            return(act);
        }
Beispiel #6
0
        public static ObjSpec GrokObject(ParseState st, int root)
        {
            var obj = new ObjSpec();

            obj.referredToAs = st.words[root].ToLower();
            // ToDo: we could get better determination of singular/plural,
            // and get the lemma at the same time, from the SEMCOR corpus.
            // But for now we'll just hard-code a few.
            if (EqualsAny(obj.referredToAs, "i", "me", "you", "it", "they", "them"))
            {
                obj.specificity = Specificity.Named;
            }
            if (EqualsAny(obj.referredToAs, "block", "one", "cube", "thing", "i", "me", "it", "box", "book"))
            {
                obj.plurality = Plurality.Singular;
            }
            else if (EqualsAny(obj.referredToAs, "blocks", "ones", "cubes", "things", "boxes", "books"))
            {
                obj.plurality    = Plurality.Plural;
                obj.referredToAs = obj.referredToAs.Substring(0, obj.referredToAs.Length - 1);
            }
            else if (EqualsAny(obj.referredToAs, "they", "them"))
            {
                obj.plurality = Plurality.Plural;
            }

            var kids = st.ChildrenOf(root);

            if (kids != null)
            {
                foreach (int i in kids)
                {
                    string pos  = st.partOfSpeech[i];
                    string word = st.words[i].ToLower();
                    if (pos == PartOfSpeech.DT)
                    {
                        if (EqualsAny(word, "the", "that", "this", "those"))
                        {
                            obj.specificity = Specificity.Specific;
                        }
                        else if (EqualsAny(word, "a", "some", "any"))
                        {
                            obj.specificity = Specificity.Nonspecific;
                        }
                    }
                    else if (pos == PartOfSpeech.JJ)
                    {
                        switch (word)
                        {
                        case "big":
                        case "large":
                            obj.vagueSize = VagueSize.Large;
                            break;

                        case "medium":
                            obj.vagueSize = VagueSize.Medium;
                            break;

                        case "small":
                        case "little":
                            obj.vagueSize = VagueSize.Small;
                            break;

                        case "left":
                            obj.leftRight = LeftRightAxis.Left;
                            break;

                        case "right":
                            obj.leftRight = LeftRightAxis.Right;
                            break;

                        case "your":
                            obj.owner = Owner.You;
                            break;

                        case "my":
                            obj.owner = Owner.Me;
                            break;

                        default:
                            foreach (Color c in System.Enum.GetValues(typeof(Color)))
                            {
                                if (word == c.ToString().ToLower())
                                {
                                    obj.color = c;
                                    break;
                                }
                            }
                            break;
                        }
                    }
                }
            }
            return(obj);
        }