예제 #1
0
        private void CheckForUndeclaredIdent(ASTProgram root, CheckerInformation info)
        {
            UsedIdents usedIdents = new UsedIdents(info);

            root.GetUsedIdents(usedIdents);
            info.CurrentNamespace = null;
            //Check to see if each local outflow parameter was initialized
            foreach (string ident in info.ProcFuncs)
            {
                foreach (ASTParam param in info.ProcFuncs[ident].Params)
                {
                    if (param.FlowMode == FlowMode.OUT && (!usedIdents.LocalInitialized.ContainsKey(ident) || !usedIdents.LocalInitialized[ident].Contains(param.Ident)))
                    {
                        throw new CheckerException("The outflow parameter '" + param.Ident + "' of the procedure/function '" + ident + "' was not initialized");
                    }
                }
            }
            //Check if each global outflow parameter was initialized
            foreach (string global in info.Globals)
            {
                if (info.Globals[global] is ASTParam)
                {
                    ASTParam param = (ASTParam)info.Globals[global];
                    if (param.FlowMode == FlowMode.OUT && !usedIdents.GlobalInitialized.Contains(param.Ident))
                    {
                        throw new CheckerException("The global outflow parameter '" + param.Ident + "' of the program was not initialized");
                    }
                }
            }
        }
예제 #2
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);
        }
예제 #3
0
        public static int GenerateCallingCode(int loc, IVirtualMachine vm, CheckerInformation info, ASTProcFuncDecl callee, List <ASTExpression> exprList)
        {
            //Allocate Return Location on Stack
            if (callee.IsFunc)
            {
                vm.Alloc(loc++, 1);
            }
            //Evaluate argument expressions
            var paramIttr = callee.Params.GetEnumerator();

            //Omit return param for functions
            if (callee.IsFunc)
            {
                if (!paramIttr.MoveNext())
                {
                    throw new IVirtualMachine.InternalError("No return param found for function");
                }
            }
            foreach (ASTExpression expr in exprList)
            {
                if (!paramIttr.MoveNext())
                {
                    throw new IVirtualMachine.InternalError("Too many arguments");
                }
                ASTParam param = paramIttr.Current;
                if (param.OptMechmode != MechMode.COPY || (param.FlowMode == FlowMode.OUT || param.FlowMode == FlowMode.INOUT))
                {
                    bool modifiable = param.OptChangemode == ChangeMode.VAR;
                    loc = expr.GenerateLValue(loc, vm, info, modifiable); //Load address on the stack
                }
                else
                {
                    loc = expr.GenerateCode(loc, vm, info); //Load value on the stack
                }
            }
            if (paramIttr.MoveNext())
            {
                throw new IVirtualMachine.InternalError("Too few arguments");
            }
            //Address of the function is not known.
            //So it has to be stored that at this loc should be a call to the function/procedure.
            if (callee.Address >= 0)
            {
                vm.Call(loc, callee.Address);
            }
            else
            {
                if (!info.Calls.ContainsKey(callee.Ident))
                {
                    info.Calls.Add(callee.Ident, new List <int>());
                }
                info.Calls[callee.Ident].Add(loc);
            }
            ++loc;
            return(loc);
        }
예제 #4
0
파일: ASTIdent.cs 프로젝트: TheJP/cpib
 private void AssertNotConstant(ASTParam sto)
 {
     if (sto.OptChangemode == null || sto.OptChangemode.Value != ChangeMode.VAR)
     {
         if (!IsInit)
         {
             throw new CheckerException("Can't modify constant parameter '" + Ident + "'");
         }
     }                                                                                                                                                                               //Default Changemode is const!
     if (sto.FlowMode == FlowMode.IN && sto.OptMechmode != MechMode.COPY)
     {
         throw new CheckerException("Can't modify 'in ref' parameter '" + Ident + "'");
     }
 }