Ejemplo n.º 1
0
        internal static Value Fill(Script vm)
        {
            int val   = vm.Argument(1).AsInt;
            var array = new ArrayInfo(vm, vm.Argument(0).AsInt);

            for (int i = array.address; i < array.address + array.length; i++)
            {
                vm.WriteWord(val, i);
            }

            return(Value.Void);
        }
Ejemplo n.º 2
0
        internal static Value Pop(Script vm)
        {
            var array   = new ArrayInfo(vm, vm.Argument(0).AsInt);
            int element = vm.Argument(1).AsInt;

            if (array.length <= 0)
            {
                vm.cpu.status = Cpu.Status.BAD_MEMORY_ACCESS;
                return(new Value(-1));
            }

            vm.WriteWord(array.length - 1, array.address - 1);
            return(new Value(vm.ReadWord(array.address + array.length - 1)));
        }
Ejemplo n.º 3
0
        internal static Value Clear(Script vm)
        {
            var array = new ArrayInfo(vm, vm.Argument(0).AsInt);

            Array.Clear(vm.memory, array.address, array.length);
            return(Value.Void);
        }
Ejemplo n.º 4
0
        ///
        /// Push element to the end of an array, reallocate the array
        /// if it's full. If new memory is allocated the old array is
        /// freed.
        ///
        /// arg(0) : Address of the array
        /// arg(1) : Element
        ///
        /// Note that the address is passed by value, so Push returns
        /// a pointer to the allocated array. In the future, It might
        /// be better to pass a pointer to the array instead, so that
        /// the reference can be updated.
        ///
        internal static Value Push(Script vm)
        {
            var array   = new ArrayInfo(vm, vm.Argument(0).AsInt);
            int element = vm.Argument(1).AsInt;

            if (array.length >= array.capacity)
            {
                // Double array capacity
                int new_array = Heap.Alloc(vm, array.capacity * 2);

                vm.MemCopy(array.address, new_array, array.capacity);

                if (array.address >= vm.cpu.heap)
                {
                    // Only free array if it's in dynamic memory
                    Heap.Free(vm, array.address);
                }
                array.address = new_array;
            }

            vm.WriteWord(element, array.address + array.length);
            vm.WriteWord(array.length + 1, array.address - 1);
            return(new Value(array.address));
        }
Ejemplo n.º 5
0
        ///
        /// Print formatted string from the current stack pointer.
        /// Format must be called with arguments pushed in reverse
        /// order to the stack and ESP pointing to a format string
        /// in memory.
        ///
        internal static string Format(Script vm)
        {
            // Arguments for printf should be pushed in reverse order.
            // The first argument is pointer to a str which contains the format
            // The following arguments must be in the sequence specified by
            // the format string.
            string fmt = vm.Argument(0).AsString;

            // @Performance
            var  buffer      = new StringBuilder();
            bool is_fmt_char = false;

            // Basic state-machine printf implementation
            int arg = 0;

            foreach (char c in fmt)
            {
                if (c == '%')
                {
                    is_fmt_char = true;
                    continue;
                }

                if (is_fmt_char)
                {
                    switch (c)
                    {
                    case 'd': {
                        int d = vm.Argument(++arg).AsInt;
                        buffer.Append(d);
                        break;
                    }

                    case 'f': {
                        float f = vm.Argument(++arg).AsFloat;
                        buffer.Append(f);
                        break;
                    }

                    case 's': {
                        string s = vm.Argument(++arg).AsString;
                        buffer.Append(s);
                        break;
                    }

                    case 'n': {
                        buffer.AppendLine();
                        break;
                    }

                    case 'c': {
                        int i = vm.Argument(++arg).AsInt;
                        buffer.Append(char.ConvertFromUtf32(i));
                        break;
                    }

                    case '%': {
                        // %% means instert a % character
                        buffer.Append(c);
                        break;
                    }

                    default: break;     // @Todo: error
                    }
                    is_fmt_char = false;
                    continue;
                }

                buffer.Append(c);
            }

            return(buffer.ToString());
        }