示例#1
0
        public override int GenerateCode(int loc, IVirtualMachine vm, CheckerInformation info)
        {
            int copies = 0;

            foreach (ASTParam param in Params)
            {
                if (param.OptMechmode == MechMode.COPY && (param.FlowMode == FlowMode.INOUT || param.FlowMode == FlowMode.OUT))
                {
                    ++copies;
                }
            }
            vm.Enter(loc++, copies + Declarations.Count, 0);
            //CopyIn of inout copy parameters
            foreach (ASTParam param in Params)
            {
                if (param.OptMechmode == MechMode.COPY && param.FlowMode == FlowMode.INOUT)
                {
                    vm.CopyIn(loc++, param.AddressLocation.Value, param.Address);
                }
            }
            //Generate body
            foreach (ASTCpsCmd cmd in Commands)
            {
                loc = cmd.GenerateCode(loc, vm, info);
            }
            //CopyOut of inout copy and out copy parameters
            bool omit = IsFunc;

            foreach (ASTParam param in Params)
            {
                if (omit)
                {
                    omit = false;
                }
                else
                {
                    if (param.OptMechmode == MechMode.COPY && (param.FlowMode == FlowMode.INOUT || param.FlowMode == FlowMode.OUT))
                    {
                        vm.CopyOut(loc++, param.Address, param.AddressLocation.Value);
                    }
                }
            }
            if (IsFunc)
            {
                //CopyOut return value
                //Can't use standard CopyOut, becuase it works with absolute target address and not with top of stack as needed!
                var      paramIttr = Params.GetEnumerator(); paramIttr.MoveNext();
                ASTParam result    = paramIttr.Current;
                vm.LoadRel(loc++, result.Address);
                vm.Deref(loc++);
                vm.LoadRel(loc++, result.AddressLocation.Value);
                vm.Store(loc++);
            }
            //Return
            vm.Return(loc++, Params.Count - (IsFunc ? 1 : 0)); //For function the return size is one smaller, leaving the function expression result on the stack!
            return(loc);
        }
示例#2
0
/*
 *  program intDiv
 *  global
 *    proc divide(in copy m:int, in copy n:int, out ref q:int, out ref r:int)
 *    do
 *      q init := 0;
 *      r init := m;
 *      while r >= n do
 *        q := q + 1;
 *        r := r - n
 *      endwhile
 *    endproc;
 *
 *    var m:int;
 *    var n:int;
 *    var q:int;
 *    var r:int
 *  do
 *    ? m init;
 *    ? n init;
 *    call divide(m, n, q init, r init);
 *    ! q;
 *    ! r
 *  endprogram
 */

        public static void Test()
        {
            try {
                vm.Alloc(0, 4);
                vm.IntLoad(1, 0);
                vm.IntInput(2, "m");
                vm.IntLoad(3, 1);
                vm.IntInput(4, "n");
                vm.Alloc(5, 0);
                vm.IntLoad(6, 0);
                vm.Deref(7);
                vm.IntLoad(8, 1);
                vm.Deref(9);
                vm.IntLoad(10, 2);
                vm.IntLoad(11, 3);
                vm.Call(12, 20);
                vm.IntLoad(13, 2);
                vm.Deref(14);
                vm.IntOutput(15, "q");
                vm.IntLoad(16, 3);
                vm.Deref(17);
                vm.IntOutput(18, "r");
                vm.Stop(19);
                vm.Enter(20, 0, 0);
                vm.IntLoad(21, 0);
                vm.LoadRel(22, (-2));
                vm.Deref(23);
                vm.Store(24);
                vm.LoadRel(25, (-4));
                vm.Deref(26);
                vm.LoadRel(27, (-1));
                vm.Deref(28);
                vm.Store(29);
                vm.LoadRel(30, (-1));
                vm.Deref(31);
                vm.Deref(32);
                vm.LoadRel(33, (-3));
                vm.Deref(34);
                vm.IntGE(35);
                vm.CondJump(36, 55);
                vm.LoadRel(37, (-2));
                vm.Deref(38);
                vm.Deref(39);
                vm.IntLoad(40, 1);
                vm.IntAdd(41);
                vm.LoadRel(42, (-2));
                vm.Deref(43);
                vm.Store(44);
                vm.LoadRel(45, (-1));
                vm.Deref(46);
                vm.Deref(47);
                vm.LoadRel(48, (-3));
                vm.Deref(49);
                vm.IntSub(50);
                vm.LoadRel(51, (-1));
                vm.Deref(52);
                vm.Store(53);
                vm.UncondJump(54, 30);
                vm.Return(55, 4);
            } catch (IVirtualMachine.CodeTooSmallError e) {
                Console.WriteLine(e.ToString());
                return;
            }

            try {
                vm.Execute();
            } catch (IVirtualMachine.ExecutionError e) {
                Console.WriteLine(e.ToString());
                return;
            }
        }