Пример #1
0
 public override int GenerateLValue(int loc, IVirtualMachine vm, CheckerInformation info, bool hasToBeLValue = true)
 {
     if (IsFuncCall)
     {
         throw new IVirtualMachine.InternalError("The result of a function can't be an LValue");
     }
     else
     {
         //Write address to the top of the stack
         if (info.CurrentNamespace != null &&
             info.Namespaces.ContainsKey(info.CurrentNamespace) &&
             info.Namespaces[info.CurrentNamespace].ContainsIdent(Ident))
         {
             IASTStoDecl storage = info.Namespaces[info.CurrentNamespace][Ident];
             if (hasToBeLValue)
             {
                 AssertNotConstant(storage);
             }
             if (storage is ASTStoDecl || (storage is ASTParam && ((ASTParam)storage).OptMechmode == MechMode.COPY))
             {
                 //Local Identifier or parameter with mechmode COPY
                 vm.LoadRel(loc++, storage.Address);
             }
             else if (storage is ASTParam)
             {
                 //If mechmode is null: default = Mechmode.REF
                 //Load parameter with mechmode REF
                 vm.LoadRel(loc++, storage.Address); //Relative Address to fp
                 vm.Deref(loc++);                    //Deref to get global Address
                 //With another Deref the value is loaded
             }
             else
             {
                 //Should never happen as long as no new type is added
                 throw new IVirtualMachine.InternalError("Unknown Identifier Type");
             }
         }
         else if (info.Globals.ContainsIdent(Ident))
         {
             IASTStoDecl storage = info.Globals[Ident];
             if (hasToBeLValue)
             {
                 AssertNotConstant(storage);
             }
             vm.IntLoad(loc++, storage.Address);
         }
         else
         {
             throw new IVirtualMachine.InternalError("Access of undeclared Identifier " + Ident);
         }
         return(loc);
     }
 }
Пример #2
0
        public override int GenerateCode(int loc, IVirtualMachine vm, CheckerInformation info)
        {
            loc = Expr.GenerateCode(loc, vm, info);

            var type = GetExpressionType(info);

            if (type == Type.BOOL)
            {
                //1 NE 1 == 0
                //0 NE 1 == 1
                vm.IntLoad(loc++, 1);
                vm.IntNE(loc++);
            }
            else
            {
                throw new IVirtualMachine.InternalError(
                          "Cannot negate Non-Bool value " + Expr.ToString());
            }

            return(loc);
        }
Пример #3
0
 public override int GenerateCode(int loc, IVirtualMachine vm, CheckerInformation info)
 {
     vm.IntLoad(loc++, Value ? 1 : 0);
     return(loc);
 }
Пример #4
0
        public int GenerateCode(int loc, IVirtualMachine vm, CheckerInformation info)
        {
            //Allocate global storage
            vm.Alloc(loc++, info.Globals.Count);
            //Load input params
            foreach (ASTParam param in Params)
            {
                if (param.FlowMode == FlowMode.IN || param.FlowMode == FlowMode.INOUT)
                {
                    //Load address where to save the input
                    vm.IntLoad(loc++, param.Address);
                    //Switch between types:
                    switch (param.Type)
                    {
                    case Type.INT32:
                        vm.IntInput(loc++, param.Ident);
                        break;

                    case Type.BOOL:
                        vm.BoolInput(loc++, param.Ident);
                        break;

                    case Type.DECIMAL:
                        vm.DecimalInput(loc++, param.Ident);
                        break;
                    }
                }
            }
            //Generate main code
            foreach (ASTCpsCmd cmd in Commands)
            {
                loc = cmd.GenerateCode(loc, vm, info);
            }
            //Add output code
            foreach (ASTParam param in Params)
            {
                if (param.FlowMode == FlowMode.OUT || param.FlowMode == FlowMode.INOUT)
                {
                    //Load output value
                    vm.IntLoad(loc++, param.Address);
                    vm.Deref(loc++);
                    //Switch between types:
                    switch (param.Type)
                    {
                    case Type.INT32:
                        vm.IntOutput(loc++, param.Ident);
                        break;

                    case Type.BOOL:
                        vm.BoolOutput(loc++, param.Ident);
                        break;

                    case Type.DECIMAL:
                        vm.DecimalOutput(loc++, param.Ident);
                        break;
                    }
                }
            }
            //Add stop as last command
            vm.Stop(loc++);
            //Generate functions/procedures
            foreach (string ident in info.ProcFuncs)
            {
                ASTProcFuncDecl procFunc = info.ProcFuncs[ident];
                procFunc.Address = loc;
                //Add calls, now that the function/procedure address is known
                if (info.Calls.ContainsKey(ident) && info.Calls[ident] != null)
                {
                    foreach (int callLoc in info.Calls[ident])
                    {
                        vm.Call(callLoc, procFunc.Address);
                    }
                }
                //Change current namespace
                info.CurrentNamespace = ident;
                //Generate code for function/procedure
                loc = procFunc.GenerateCode(loc, vm, info);
                //Reset namespace
                info.CurrentNamespace = null;
            }
            return(loc);
        }
Пример #5
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;
            }
        }