예제 #1
0
파일: Builtins.cs 프로젝트: ebassi/niecza
    internal static Frame RunCATCH_C(Frame th)
    {
        // ENTRY  lex0 : CATCH lambda (decontainerized)
        //        lex1 : exception payload (@! Array)
        // EXIT   ret  : new @!; will catch if false
        // LEX    lex2 : @*unhandled
        //        lex3 : $current
        //        lex4 : @! iterator
        // note, compiler munges catch/control lambdas to return True
        //    if exitted via succeed
        // note2, any exception thrown from under RunCATCH_I will be caught
        //    and pushed onto @*unhandled along with $current, and next;

        // -> $handler, @! { #0
        //    my @*unhandled;
        //    for @! -> $current { #N=1 R=2
        //        $handler.($current) || push @*unhandled, $current
        //    } #L=4
        //    @*unhandled;
        // }

        // $! will be set to munged @! if we return nothing

        Variable t1, t2;
        VarDeque u1;
        P6any v1;
        switch (th.ip) {
            case 0:
                th.lex2 = Kernel.CreateArray();
                t1 = (Variable)th.lex1;
                th.lex4 = t1.Fetch().mo.mro_raw_iterator.Get(t1);
                goto case 1;

            case 1:
                u1 = (VarDeque)th.lex4;
                if (!Kernel.IterHasFlat(u1, true)) goto case 4;
                th.lex3 = u1.Shift();
                goto case 2;

            case 2:
                t1 = (Variable)th.lex3;
                v1 = (P6any)th.lex0;
                th.ip = 3;
                return v1.Invoke(th, new Variable[] { t1 }, null);

            case 3:
                t1 = (Variable)th.resultSlot;
                if (t1.Fetch().mo.mro_raw_Bool.Get(t1))
                    goto case 1; // yay handled
                t1 = (Variable)th.lex3;
                t2 = (Variable)th.lex2;
                t2.Fetch().mo.mro_push.Invoke(t2, new Variable[] { t1 });
                goto case 1;

            case 4:
                th.caller.resultSlot = th.lex2;
                return th.Return();

            default:
                return Kernel.Die(th, "Invalid IP");
        }
    }
예제 #2
0
파일: Builtins.cs 프로젝트: ebassi/niecza
 internal static Frame TEMP_C(Frame th)
 {
     ((Variable)th.outer.lex0).Store((P6any)th.outer.lex1);
     return th.Return();
 }
예제 #3
0
파일: Builtins.cs 프로젝트: ebassi/niecza
    internal static Frame CommonGrep_C(Frame th)
    {
        VarDeque src = (VarDeque) th.lex0;
        VarDeque outq = (VarDeque) th.lex1;
        Variable flt = (Variable) th.lex2;
        int tailmode = th.lexi0;

        switch (th.ip) {
            case 0:
                Variable pen = null;
                while (pen == null) {
                    if (tailmode != 0) {
                        if (!Kernel.IterHasFlat(src, false)) break;
                    } else {
                        if (src.Count() == 0) break;
                        if (src[0].Fetch().mo.HasMRO(Kernel.IterCursorMO)) {
                            P6opaque thunk = new P6opaque(Kernel.GatherIteratorMO);
                            th.coro_return = th;
                            th.MarkSharedChain();
                            thunk.slots[0] = Kernel.NewMuScalar(th);
                            thunk.slots[1] = Kernel.NewMuScalar(Kernel.AnyP);
                            P6opaque lst = new P6opaque(Kernel.ListMO);
                            lst.slots[0] = outq;
                            lst.slots[1] = new VarDeque(Kernel.NewROScalar(thunk));
                            th.caller.resultSlot = Kernel.NewRWListVar(lst);
                            th.lexi0 = 1;
                            return th.Return();
                        }
                    }
                    pen = src.Shift();
                }
                if (pen == null) {
                    if (tailmode != 0)
                        return Kernel.Take(th, Kernel.NewROScalar(Kernel.EMPTYP));
                    P6opaque lst = new P6opaque(Kernel.ListMO);
                    lst.slots[0] = outq;
                    lst.slots[1] = new VarDeque();
                    th.caller.resultSlot = Kernel.NewRWListVar(lst);
                    return th.Return();
                }
                th.lex3 = pen;
                th.ip = 1;
                goto case 1;
            case 1:
                th.ip = 2;
                return flt.Fetch().InvokeMethod(th, "ACCEPTS",
                        new Variable[] { flt, (Variable)th.lex3 }, null);
            case 2:
                Variable r = (Variable) th.resultSlot;
                if (!r.Fetch().mo.mro_raw_Bool.Get(r)) {
                    th.ip = 0;
                    goto case 0;
                }
                if (tailmode != 0) {
                    th.ip = 0;
                    return Kernel.Take(th, (Variable)th.lex3);
                } else {
                    outq.Push((Variable) th.lex3);
                    th.ip = 0;
                    goto case 0;
                }
            case 3:
                th.lex0 = src = new VarDeque();
                th.ip = 0;
                goto case 0;
            default:
                return Kernel.Die(th, "Invalid IP");
        }
    }
예제 #4
0
파일: Builtins.cs 프로젝트: ebassi/niecza
    internal static Frame CommonMEMap_C(Frame th)
    {
        ItemSource src = (ItemSource) th.lex0;
        VarDeque outq = (VarDeque) th.lex1;
        object fnc = th.lex2;
        int tailmode = th.lexi0;

        switch (th.ip) {
            case 0:
                Variable[] pen;
                if (!src.TryGet(out pen, tailmode != 0)) {
                    P6opaque thunk = new P6opaque(Kernel.GatherIteratorMO);
                    th.coro_return = th;
                    th.MarkSharedChain();
                    thunk.slots[0] = Kernel.NewMuScalar(th);
                    thunk.slots[1] = Kernel.NewMuScalar(Kernel.AnyP);
                    P6opaque lst = new P6opaque(Kernel.ListMO);
                    lst.slots[0] = outq;
                    lst.slots[1] = new VarDeque(Kernel.NewROScalar(thunk));
                    th.caller.resultSlot = Kernel.NewRWListVar(lst);
                    th.lexi0 = 1;
                    return th.Return();
                }
                if (pen == null) {
                    if (tailmode != 0)
                        return Kernel.Take(th, Kernel.NewROScalar(Kernel.EMPTYP));
                    P6opaque lst = new P6opaque(Kernel.ListMO);
                    lst.slots[0] = outq;
                    lst.slots[1] = new VarDeque();
                    th.caller.resultSlot = Kernel.NewRWListVar(lst);
                    return th.Return();
                }
                th.lex3 = pen;
                th.ip = 1;
                goto case 1;
            case 1:
                th.ip = 2;
                if (fnc is P6any) {
                    return ((P6any)fnc).Invoke(th, (Variable[])th.lex3, null);
                } else if (fnc == null) {
                    th.resultSlot = MakeParcel((Variable[]) th.lex3);
                    goto case 2;
                } else {
                    th.resultSlot = ((Func<Variable,Variable>)fnc).Invoke(
                        ((Variable[])th.lex3)[0]);
                    goto case 2;
                }
            case 2:
                if (tailmode != 0) {
                    th.ip = 0;
                    return Kernel.Take(th, (Variable)th.resultSlot);
                } else {
                    outq.Push((Variable) th.resultSlot);
                    th.ip = 0;
                    goto case 0;
                }
            case 3:
                th.lex0 = src = ItemSource.Empty;
                th.ip = 0;
                goto case 0;
            default:
                return Kernel.Die(th, "Invalid IP");
        }
    }
예제 #5
0
파일: Cursor.cs 프로젝트: nbrown/niecza
 public Frame FinalEnd(Frame th)
 {
     if (st.pos > global.highwater)
         global.IncHighwater(st.pos);
     th.caller.resultSlot = Kernel.NewROScalar(_matchObj);
     return th.Return();
 }
예제 #6
0
파일: Cursor.cs 프로젝트: nbrown/niecza
 // currently just used for protoregex
 public Frame EndWith(Frame th, Cursor m)
 {
     if (st.pos > global.highwater)
         global.IncHighwater(st.pos);
     if ((flags & RETURN_ONE) != 0) {
         return Kernel.Take(th, Kernel.NewROScalar(m));
     } else {
         th.MarkSharedChain();
         flags |= RETURN_ONE;
         VarDeque ks = new VarDeque();
         ks.Push(Kernel.NewROScalar(m));
         th.coro_return = th;
         P6opaque it  = new P6opaque(Kernel.GatherIteratorMO);
         it.slots[0 /*frame*/] = Kernel.NewMuScalar(th);
         it.slots[1 /*reify*/] = Kernel.NewMuScalar(Kernel.AnyP);
         VarDeque iss = new VarDeque();
         iss.Push(Kernel.NewROScalar(it));
         P6opaque lst = new P6opaque(Kernel.ListMO);
         lst.slots[0 /*items*/] = ks;
         lst.slots[1 /*rest*/ ] = iss;
         th.caller.resultSlot = Kernel.NewRWListVar(lst);
     }
     return th.Return();
 }
예제 #7
0
파일: Cursor.cs 프로젝트: nbrown/niecza
    public Frame Backtrack(Frame th)
    {
        // throw away cut or mark-only frames
        while (bt != rootf && (bt.ip < 0)) {
            if (bt.ip == -1) {
                // Special frame that does $*GOAL cleanup ...
                th.LexicalBind("$*GOAL", (Variable)bt.st.subrule_iter);
            }
            bt = bt.prev;
        }
        if (st.pos > global.highwater)
            global.IncHighwater(st.pos);
        if (bt == rootf) {
            if ((flags & RETURN_ONE) != 0) {
                if (Cursor.Trace)
                    Console.WriteLine("Failing {0}@{1} after no matches",
                            name, from);
                return Kernel.Take(th, Kernel.NewROScalar(Kernel.EMPTYP));
            } else {
                if (Cursor.Trace)
                    Console.WriteLine("Failing {0}@{1} after some matches",
                            name, from);
                if (EmptyList == null) {
                    P6opaque lst = new P6opaque(Kernel.ListMO);
                    lst.slots[0 /*items*/] = new VarDeque();
                    lst.slots[1 /*rest*/ ] = new VarDeque();
                    EmptyList = Kernel.NewRWListVar(lst);
                }
                th.caller.resultSlot = EmptyList;
            }

            return th.Return();
        } else {
            th.ip = bt.ip;
            st = bt.st;
            bt = bt.prev;
            return th;
        }
    }
예제 #8
0
파일: Builtins.cs 프로젝트: o-fun/niecza
    public static Frame dispatch_fromtype(Frame th)
    {
        Variable[] npos = new Variable[th.pos.Length - 2];
        STable from = th.pos[1].Fetch().mo;
        string name = th.pos[2].Fetch().mo.mro_raw_Str.Get(th.pos[2]);
        npos[0] = th.pos[0];
        Array.Copy(th.pos, 3, npos, 1, npos.Length - 1);

        if (!npos[0].Fetch().Does(from)) {
            return Kernel.Die(th, "Cannot dispatch to a method on " +
                from.name + " because it is not inherited or done by " +
                npos[0].Fetch().mo.name);
        }

        var de = from.FindMethod(name);
        if (de != null) {
            return de.info.SetupCall(th.Return(), de.outer, de.ip6,
                        npos, th.named, false, de);
        } else {
            return Kernel.Die(th, "Unable to resolve method " + name + " via " +
                    from.name);
        }
    }
예제 #9
0
파일: Cursor.cs 프로젝트: FROGGS/niecza
 public Frame FinalEnd(Frame th)
 {
     if (st.pos > global.highwater)
         global.IncHighwater(st.pos);
     th.caller.resultSlot = _matchObj;
     return th.Return();
 }