Example #1
0
 protected override LayeObject Infix__notEqualTo(LayeState state, LayeObject ths, params LayeObject[] args)
 {
     var arg = args[0];
     if (!(arg is LayeString))
         return TRUE;
     return (LayeBool)((ths as LayeString).value != (arg as LayeString).value);
 }
Example #2
0
 protected override LayeObject Infix__notEqualTo(LayeState state, LayeObject ths, params LayeObject[] args)
 {
     var arg = args[0];
     if (ReferenceEquals(this, arg))
         return FALSE;
     if (!(arg is LayeSymbol))
         return TRUE;
     return (LayeBool)((ths as LayeSymbol).value != (arg as LayeSymbol).value);
 }
Example #3
0
 protected override LayeObject Infix__notEqualTo(LayeState state, LayeObject ths, params LayeObject[] args)
 {
     if (ReferenceEquals(ths, args[0]))
         return FALSE;
     var arg = args[0] as LayeFloat;
     if (arg == null)
         return TRUE;
     return (LayeBool)((ths as LayeFloat).value != arg.value);
 }
Example #4
0
 public override LayeObject InvokeAsMethod(LayeState state, LayeObject ths, params LayeObject[] args)
 {
     try
     {
         return callback(state, ths, args);
     }
     catch (UnhandledLayeException e)
     {
         throw e;
     }
     catch (Exception e)
     {
         state.RaiseException(e.GetType().FullName + ": " + e.Message + Environment.NewLine + e.StackTrace);
         return NULL;
     }
 }
Example #5
0
 public override LayeObject Infix(LayeState state, string op, LayeObject that)
 {
     if (that.IsNumeric)
     {
         lfloat thatValue = that is LayeInt ? (that as LayeInt).value : (that as LayeFloat).value;
         switch (op)
         {
             case "+": return new LayeFloat(value + thatValue);
             case "-": return new LayeFloat(value - thatValue);
             case "*": return new LayeFloat(value * thatValue);
             case "/":
                 if (thatValue == 0)
                 {
                     state.RaiseException("Attempt to divide by zero.");
                     return NULL;
                 }
                 return new LayeFloat(value / thatValue);
             case "//":
                 if (thatValue == 0)
                 {
                     state.RaiseException("Attempt to divide by zero.");
                     return NULL;
                 }
                 return LayeInt.ValueOf((lint)(value / thatValue));
             case "%":
                 if (thatValue == 0)
                 {
                     state.RaiseException("Attempt to divide by zero.");
                     return NULL;
                 }
                 return new LayeFloat(value % thatValue);
             case "^": return new LayeFloat((lfloat)Math.Pow(value, thatValue));
             case "==": return value == thatValue ? TRUE : FALSE;
             case "!=": return value != thatValue ? TRUE : FALSE;
             case "<": return value < thatValue ? TRUE : FALSE;
             case "<=": return value <= thatValue ? TRUE : FALSE;
             case ">": return value > thatValue ? TRUE : FALSE;
             case ">=": return value >= thatValue ? TRUE : FALSE;
             default: break;
         }
     }
     return base.Infix(state, op, that);
 }
Example #6
0
 private LayeObject Infix__repeat(LayeState state, LayeObject ths, params LayeObject[] args)
 {
     var arg = args[0] as LayeInt;
     if (arg == null)
     {
         state.RaiseException("Can only multiply a string by an integer value, got a(n) {0}.", args[0].TypeName);
         return NULL;
     }
     var count = arg.value;
     switch (count)
     {
         case 0: return EMPTY_STRING;
         case 1: return ths;
         case 2: return new LayeString((ths as LayeString).value + (ths as LayeString).value);
         default:
             var value = (ths as LayeString).value;
             var builder = new System.Text.StringBuilder();
             for (var i = 0; i < count; i++)
                 builder.Append(value);
             return new LayeString(builder.ToString());
     }
 }
Example #7
0
        internal LayeClosure(LayeKit kit, FunctionPrototype proto, LayeTypeDef definedType = null, LayeObject[] defaults = null)
            : base(TYPE)
        {
            if (kit == null)
                throw new ArgumentNullException("kit");
            this.kit = kit;
            this.proto = proto;
            outers = new OuterValue[proto.outers.Length];
            this.definedType = definedType == null ? NULL : definedType;

            var numParams = proto.hasVargs ? proto.numParams - 1 : proto.numParams;
            this.defaults = new LayeObject[numParams];
            if (defaults == null || defaults.Length == 0)
                for (int i = 0; i < numParams; i++)
                    this.defaults[i] = NULL;
            else
            {
                for (uint i = 0; i < numParams - defaults.Length; i++)
                    this.defaults[i] = NULL;
                for (uint i = numParams - (uint)defaults.Length, j = 0; i < numParams; i++, j++)
                    this.defaults[i] = defaults[j];
            }
        }
Example #8
0
 internal LayeObject[] PopCount(int count)
 {
     LayeObject[] result = new LayeObject[count];
     while (--count >= 0)
         result[count] = Pop();
     return result;
 }
Example #9
0
 public OuterValue(LayeObject[] stack, uint index)
 {
     values = stack;
     Index = index;
 }
Example #10
0
 internal StackFrame PushFrame(LayeClosure closure, LayeObject ths, LayeObject[] args)
 {
     FrameCount++;
     return Top = new StackFrame(Top, closure, ths, args);
 }
Example #11
0
 internal void Push(LayeObject value)
 {
     if (value == null)
         throw new ArgumentNullException("value");
     CheckOverflow();
     stack[++stackPointer] = value;
 }
Example #12
0
 protected override LayeObject IMethod__toString(LayeState state, LayeObject ths, params LayeObject[] args)
 {
     return new LayeString("null");
 }
Example #13
0
 protected override LayeObject IPropertyGet__hashCode(LayeState state, LayeObject ths, params LayeObject[] args)
 {
     return LayeInt.ValueOf(0);
 }
Example #14
0
 protected virtual LayeObject Infix__Concat(LayeState state, LayeObject ths, params LayeObject[] args)
 {
     return new LayeString(ths.ToString(state) + args[0].ToString(state));
 }
Example #15
0
 internal StackFrame NewFrame(LayeClosure closure, LayeObject ths, LayeObject[] args)
 {
     return new StackFrame(Top, closure, ths, args);
 }
Example #16
0
 private LayeObject As__Int(LayeState state, LayeObject ths, params LayeObject[] args)
 {
     return LayeInt.ValueOf((lint)(ths as LayeFloat).value);
 }
Example #17
0
 protected override LayeObject IMethod__toString(LayeState state, LayeObject ths, params LayeObject[] args)
 {
     return new LayeString((ths as LayeFloat).value.ToString());
 }
Example #18
0
 protected override LayeObject As__Bool(LayeState state, LayeObject ths, params LayeObject[] args)
 {
     return (LayeBool)((ths as LayeFloat).value != 0);
 }
Example #19
0
 protected override LayeObject IPropertyGet__hashCode(LayeState state, LayeObject ths, params LayeObject[] args)
 {
     return LayeInt.ValueOf((ths as LayeFloat).value.GetHashCode());
 }
Example #20
0
 protected override LayeObject Infix__notEqualTo(LayeState state, LayeObject ths, params LayeObject[] args)
 {
     return ReferenceEquals(ths, args[0]) ? FALSE : TRUE;
 }
Example #21
0
 internal void Set(LayeState state, LayeObject value)
 {
     LayeObject temp;
     if ((temp = values[Index]) is LayeReference)
         (temp as LayeReference).Store(state, value);
     else values[Index] = value;
 }
Example #22
0
        internal LayeClosure BuildClosure(FunctionPrototype proto, OuterValue[] openOuters, LayeTypeDef definedType, LayeObject[] defaults)
        {
            var top = stack.Top;
            var closure = new LayeClosure(top.closure.kit, proto, definedType, defaults);
            var protoOuters = proto.outers;

            for (var i = 0; i < protoOuters.Length; i++)
                if (protoOuters[i].type == OuterValueType.LOCAL)
                    closure.outers[i] = FindOuterValue(top.Locals, protoOuters[i].location, openOuters);
                else closure.outers[i] = top.closure.outers[protoOuters[i].location];

            return closure;
        }
Example #23
0
 private static OuterValue FindOuterValue(LayeObject[] locals, uint idx, OuterValue[] openOuters)
 {
     int n = openOuters.Length;
     for (int i = 0; i < n; i++)
         if (openOuters[i] != null && openOuters[i].Index == idx)
             return openOuters[i];
     for (int i = 0; i < n; i++)
         if (openOuters[i] == null)
             return openOuters[i] = new OuterValue(locals, idx);
     throw new ArgumentException("no space for new outer value.");
 }
Example #24
0
 private void DoThisInvoke(StackFrame frame, LayeObject ths, string methodName, uint insn)
 {
     var args = frame.PopCount((int)Insn.GET_A(insn));
     frame.Push(ths.MethodInvoke(this, methodName, args));
 }
Example #25
0
 /// <summary>
 /// Raises an exception in this Laye state.
 /// The exception will propogate up the call stack until handled.
 /// If the exception propogates through all stacks, the exception is thrown
 /// as a <c>UnhandledLayeException</c> exception.
 /// 
 /// The given exception can be any Laye object.
 /// 
 /// A specific type is provided for detailed exceptions, the <c>Exception</c> type.
 /// It's not necessary to use this type, but it's provided for convenience.
 /// </summary>
 /// <param name="obj"></param>
 public void RaiseException(LayeObject obj)
 {
     if (exceptionHandlers.Count == 0)
         throw new UnhandledLayeException(GetStackTrace(), obj.ToString(this));
     else
     {
         lastException = obj;
         var handler = exceptionHandlers.Pop();
         stack.Top.activeExceptionHandlers--;
         stack.Unwind(stack.FrameCount - handler.frameIndex);
         stack.Top.ip = handler.catchIP - 1;
     }
 }
Example #26
0
 protected override LayeObject As__Bool(LayeState state, LayeObject ths, params LayeObject[] args)
 {
     return FALSE;
 }
Example #27
0
        internal LayeObject Execute(StackFrame frame, LayeClosure closure, LayeObject ths = null, params LayeObject[] args)
        {
            if (frame == null)
                frame = stack.PushFrame(closure, ths, args);
            else stack.PushFrame(frame);

        reentry:
            var kit = closure.kit;

            var outers = closure.outers;
            var nested = closure.proto.nested;
            var strings = closure.proto.strings;
            var numericConsts = closure.proto.numericConsts;

            var code = closure.proto.code;
            var codeLen = (uint)code.Length;

            var paramc = closure.proto.numParams;
            var argc = args.Length;
            var vargs = closure.proto.hasVargs;

            var openOuters = frame.openOuters;

            uint insn;
            OpCode op;

            for (; frame.ip < codeLen && !frame.Aborted && !frame.yielded; frame.ip++)
            {
                op = (OpCode)((insn = code[frame.ip]) & Insn.MAX_OP);
#if DEBUG_STACK
                Console.WriteLine(frame.ip + " " + op);
                frame.PrintLocals(this);
                frame.PrintStack(this);
#endif
                switch (op)
                {
                    default: RaiseException(string.Format("Unhandled op code {0}.", op)); return NULL;

                    case OpCode.NOP: continue;
                    case OpCode.POP: frame.Pop(); continue;
                    case OpCode.DUP: frame.Dup(); continue;

                    case OpCode.CLOSE: CloseOuters(openOuters, Insn.GET_C(insn)); continue;

                        // These all do n - 1 because frame.ip++ happens anyway. I hate it, but oh well.
                    case OpCode.JUMP: frame.ip = Insn.GET_C(insn) - 1; continue;
                    case OpCode.JUMPEQ: if (frame.SwapPop().Equals(frame.Pop())) frame.ip = Insn.GET_C(insn) - 1; continue;
                    case OpCode.JUMPNEQ: if (!frame.SwapPop().Equals(frame.Pop())) frame.ip = Insn.GET_C(insn) - 1; continue;
                    case OpCode.JUMPT: if (frame.Pop().ToBool(this)) frame.ip = Insn.GET_C(insn) - 1; continue;
                    case OpCode.JUMPF: if (!frame.Pop().ToBool(this)) frame.ip = Insn.GET_C(insn) - 1; continue;

                    case OpCode.LLOAD: frame.Push(frame[Insn.GET_C(insn)]); continue;
                    case OpCode.LSTORE: frame[Insn.GET_C(insn)] = frame.Top; continue;
                    case OpCode.OLOAD: frame.Push(outers[Insn.GET_C(insn)].Value); continue;
                    case OpCode.OSTORE: outers[Insn.GET_C(insn)].Set(this, frame.Top); continue;
                    case OpCode.KLOAD: frame.Push(kit[this, strings[Insn.GET_C(insn)]]); continue;
                    case OpCode.KSTORE: kit[this, strings[Insn.GET_C(insn)]] = frame.Top; continue;
                    case OpCode.GLOAD: frame.Push(kit.GetGlobal(this, strings[Insn.GET_C(insn)])); continue;
                    case OpCode.GSTORE: kit.SetGlobal(this, strings[Insn.GET_C(insn)], frame.Top); continue;
                    case OpCode.ILOAD: DoILoad(frame, insn); continue;
                    case OpCode.ISTORE: DoIStore(frame, insn); continue;
                    case OpCode.OILOAD: frame.Push(frame.Pop().OperatorIndexGet(this, strings[Insn.GET_C(insn)])); continue;
                    case OpCode.OISTORE: frame.SwapPop().OperatorIndexSet(this, strings[Insn.GET_C(insn)], frame.Top); continue;
                    case OpCode.FLOAD: frame.Push(frame.Pop()[this, strings[Insn.GET_C(insn)]]); continue;
                    case OpCode.FSTORE: frame.SwapPop()[this, strings[Insn.GET_C(insn)]] = frame.Top; continue;
                    case OpCode.LOAD: DoLoad(frame, kit, strings[Insn.GET_C(insn)]); continue;
                    case OpCode.STORE: DoStore(frame, kit, strings[Insn.GET_C(insn)]); continue;

                    case OpCode.NULL: frame.Push(NULL); continue;
                    case OpCode.TRUE: frame.Push(TRUE); continue;
                    case OpCode.FALSE: frame.Push(FALSE); continue;
                    case OpCode.ENDL: frame.Push(ENDL); continue;
                    case OpCode.NCONST: frame.Push(numericConsts[Insn.GET_C(insn)]); continue;
                    case OpCode.SCONST: frame.Push(Insn.GET_B(insn) == 0 ? new LayeString(strings[Insn.GET_A(insn)]) as LayeObject : LayeSymbol.getUnsafe(strings[Insn.GET_A(insn)])); continue;

                    case OpCode.ICONSTM1: frame.Push(ICONSTM1); continue;
                    case OpCode.ICONST0: frame.Push(ICONST0); continue;
                    case OpCode.ICONST1: frame.Push(ICONST1); continue;
                    case OpCode.ICONST2: frame.Push(ICONST2); continue;
                    case OpCode.ICONST3: frame.Push(ICONST3); continue;
                    case OpCode.ICONST4: frame.Push(ICONST4); continue;
                    case OpCode.ICONST5: frame.Push(ICONST5); continue;

                    case OpCode.FCONSTM1: frame.Push(FCONSTM1); continue;
                    case OpCode.FCONST0: frame.Push(FCONST0); continue;
                    case OpCode.FCONST1: frame.Push(FCONST1); continue;
                    case OpCode.FCONST2: frame.Push(FCONST2); continue;

                    case OpCode.LIST: frame.Push(new LayeList(frame.PopCount((int)Insn.GET_C(insn)))); continue;
                    case OpCode.TUPLE: frame.Push(new LayeTuple(frame.PopCount((int)Insn.GET_C(insn)))); continue;

                    case OpCode.CLOSURE: frame.Push(BuildClosure(nested[Insn.GET_A(insn)], openOuters, null, frame.PopCount((int)Insn.GET_B(insn)))); continue;
                    case OpCode.GENERATOR: frame.Push(new LayeClosureGeneratorSpawner(frame.Pop() as LayeClosure)); continue;

                    case OpCode.INVOKE: DoInvoke(frame, insn); continue;
                    case OpCode.MINVOKE: DoMethodInvoke(frame, strings[Insn.GET_B(insn)], insn); continue;
                    case OpCode.TINVOKE: DoThisInvoke(frame, ths, strings[Insn.GET_B(insn)], insn); continue;
                    case OpCode.TAILINVOKE:
                        var saveArgs = frame.PopCount((int)Insn.GET_C(insn));
                        EndCall(frame, openOuters);
                        frame.Reset();
                        frame.SetArgs(saveArgs);
                        goto reentry;

                    case OpCode.YIELD: frame.yielded = true; continue;
                    case OpCode.RES: DoRes(frame); continue;

                    case OpCode.KIT: frame.Push(kit); continue;
                    case OpCode.THIS: frame.Push(ths); continue;
                    case OpCode.SELF: frame.Push(closure); continue;
                    case OpCode.STATIC: frame.Push(closure.definedType); continue;

                    case OpCode.PREFIX: frame.Push(frame.Pop().Prefix(this, strings[Insn.GET_C(insn)])); continue;
                    case OpCode.INFIX: frame.Push(frame.SwapPop().Infix(this, strings[Insn.GET_C(insn)], frame.Pop())); continue;
                    case OpCode.AS: frame.Push(frame.SwapPop().As(this, frame.Pop())); continue;

                    case OpCode.NOT: frame.Push(frame.Pop().ToBool(this) ? FALSE : TRUE); continue;
                    case OpCode.AND: if (frame.Top.ToBool(this)) frame.Pop(); else frame.ip = Insn.GET_C(insn) - 1; continue;
                    case OpCode.OR: if (frame.Top.ToBool(this)) frame.ip = Insn.GET_C(insn) - 1; else frame.Pop(); continue;
                    case OpCode.XOR: frame.Push((frame.Pop().ToBool(this) != frame.Pop().ToBool(this)) ? TRUE : FALSE); continue;

                    case OpCode.COMPIS: frame.Push((LayeBool)ReferenceEquals(frame.Pop(), frame.Pop())); continue;
                    case OpCode.COMPNOTIS: frame.Push((LayeBool)!ReferenceEquals(frame.Pop(), frame.Pop())); continue;
                    case OpCode.COMPTYPEOF: frame.Push((LayeBool)frame.SwapPop().TypeOf(this, frame.Pop())); continue;
                    case OpCode.COMPNOTTYPEOF: frame.Push((LayeBool)!frame.SwapPop().TypeOf(this, frame.Pop())); continue;
                    case OpCode.TYPEOF: frame.Push(frame.Pop().TypeDef); continue;

                    case OpCode.THROW: RaiseException(frame.Pop()); continue;
                    case OpCode.STOREEX: frame[Insn.GET_C(insn)] = lastException; continue;
                    case OpCode.BEGINEXH: var c = Insn.GET_C(insn); while (frame.stackPointer >= c) frame.Pop(); continue;
                    case OpCode.PUSHEXH: frame.activeExceptionHandlers++; exceptionHandlers.Push(new ExceptionHandler(stack.FrameCount, Insn.GET_C(insn))); continue;
                    case OpCode.POPEXH: frame.activeExceptionHandlers--; exceptionHandlers.Pop(); continue;

                    case OpCode.ITERPREP: DoIterPrep(frame, Insn.GET_A(insn), Insn.GET_B(insn) != 0); continue;
                    case OpCode.ITERLOOP: DoIterLoop(frame, Insn.GET_A(insn), Insn.GET_B(insn)); continue;
                    case OpCode.EACHPREP: DoEachPrep(frame, Insn.GET_A(insn)); continue;
                    case OpCode.EACHLOOP: DoEachLoop(frame, Insn.GET_A(insn), Insn.GET_B(insn)); continue;
                    case OpCode.IEACHPREP: DoIEachPrep(frame, Insn.GET_A(insn)); continue;
                    case OpCode.IEACHLOOP: DoIEachLoop(frame, Insn.GET_A(insn), Insn.GET_B(insn)); continue;
                } // end switch
            } // end for

            EndCall(frame, openOuters);

#if DEBUG_STACK
            frame.PrintStack(this);
#endif
            if (frame.Aborted)
                return NULL;
            stack.PopFrame();

            return frame.HasValue() ? frame.Top : NULL;
        }
Example #28
0
        internal StackFrame(StackFrame previous, LayeClosure closure, LayeObject ths, LayeObject[] args)
        {
            this.previous = previous;
            this.closure = closure;
            this.ths = ths;
            locals = new LayeObject[closure.proto.maxLocalCount];
            stack = new LayeObject[closure.proto.maxStackCount];

            openOuters = closure.proto.nested.Length != 0 ? new OuterValue[closure.proto.maxStackCount] : null;
            SetArgs(args);
        }
Example #29
0
        internal void SetArgs(LayeObject[] args)
        {
            var paramc = closure.proto.numParams;
            var argc = args.Length;
            var vargs = closure.proto.hasVargs;

            for (int argi = 0; argi < paramc; argi++)
            {
                int index = argi;
                LayeObject arg;
                if (argi < argc)
                    if (argi == paramc - 1 && vargs)
                    {
                        var vargsArray = new LayeObject[argc - argi];
                        Array.Copy(args, argi, vargsArray, 0, argc - argi);
                        arg = new LayeList(vargsArray);
                        argi = argc;
                    }
                    else arg = args[argi];
                else arg = closure.defaults[argi];
                this[(uint)index] = arg;
            }
        }
Example #30
0
 internal void SetGlobal(LayeState state, string key, LayeObject value)
 {
     globals[key] = value;
 }