Пример #1
0
 public override int GenerateCode(int loc, IVirtualMachine vm, CheckerInformation info)
 {
     if (IsFuncCall)
     {
         if (info.ProcFuncs.ContainsIdent(Ident))
         {
             ASTProcFuncDecl callee = info.ProcFuncs[Ident];
             if (!callee.IsFunc)
             {
                 throw new IVirtualMachine.InternalError("Calls inside expresssions can only be made to functions but never to procedures!");
             }
             loc = ASTCmdCall.GenerateCallingCode(loc, vm, info, callee, OptInitOrExprList);
             return(loc);
         }
         else
         {
             throw new IVirtualMachine.InternalError("Call to unkown function '" + Ident + "'");
         }
     }
     else
     {
         loc = GenerateLValue(loc, vm, info, false);
         vm.Deref(loc++);
         return(loc);
     }
 }
Пример #2
0
        public override int GenerateCode(int loc, IVirtualMachine vm, CheckerInformation info)
        {
            //Get abstract declaration
            ASTProcFuncDecl callee = info.ProcFuncs[Ident];

            loc = ASTCmdCall.GenerateCallingCode(loc, vm, info, callee, ExprList);
            return(loc);
        }
Пример #3
0
        private void OptainNamespaceInformation(ASTProgram root, CheckerInformation info)
        {
            int globalAddress = 0;

            //Add global parameters
            foreach (ASTParam param in root.Params)
            {
                param.Address = globalAddress++;
                info.Globals.addDeclaration(param);
            }
            //Add Global Variables, Functions and Procedures
            //And add local variables and parameters of the Function and Procedures
            foreach (ASTCpsDecl declaration in root.Declarations)
            {
                if (declaration is ASTStoDecl)
                {
                    //Add global storage identifier
                    declaration.Address = globalAddress++;
                    info.Globals.addDeclaration((ASTStoDecl)declaration);
                }
                else if (declaration is ASTProcFuncDecl)
                {
                    ASTProcFuncDecl procFunc = (ASTProcFuncDecl)declaration;
                    //Add function or procedure identifier
                    declaration.Address = -1;
                    info.ProcFuncs.addDeclaration(procFunc);
                    Namespace <IASTStoDecl> ns = new Namespace <IASTStoDecl>();
                    info.Namespaces.Add(declaration.Ident, ns);
                    //Relative address: The framepointer is one above the last parameter. Meaning the last parameter has the relative address -1 and the first -Params.Count
                    int paramAddress = -procFunc.Params.Count;
                    //Relative address: out copy, inout copy and local identifiers. Starting 3 addresses behind the frame pointer.
                    int localAddress = 3;
                    //Add local params of this function/procedure
                    foreach (ASTParam localParam in procFunc.Params)
                    {
                        if (localParam.OptMechmode == MechMode.COPY && (localParam.FlowMode == FlowMode.OUT || localParam.FlowMode == FlowMode.INOUT))
                        {
                            localParam.Address         = localAddress++;
                            localParam.AddressLocation = paramAddress++;
                        }
                        else
                        {
                            localParam.Address = paramAddress++;
                        }
                        ns.addDeclaration(localParam);
                    }
                    //Add local storage identifier of this function/procedure
                    foreach (ASTCpsDecl localDeclaration in ((ASTProcFuncDecl)declaration).Declarations)
                    {
                        if (localDeclaration is ASTStoDecl)
                        {
                            localDeclaration.Address = localAddress++;
                            ns.addDeclaration((ASTStoDecl)localDeclaration);
                        }
                    }
                }
            }
        }
Пример #4
0
        public override Type GetExpressionType(CheckerInformation info)
        {
            if (IsFuncCall)
            {
                if (info.ProcFuncs.ContainsIdent(Ident))
                {
                    ASTProcFuncDecl callee = info.ProcFuncs[Ident];
                    if (!callee.IsFunc)
                    {
                        throw new IVirtualMachine.InternalError("Calls inside expresssions can only be made to functions but never to procedures!");
                    }
                    var paramIttr = callee.Params.GetEnumerator();
                    if (!paramIttr.MoveNext())
                    {
                        throw new IVirtualMachine.InternalError("No return param found for function");
                    }
                    return(paramIttr.Current.Type);
                }
                else
                {
                    throw new IVirtualMachine.InternalError("Call to unkown function '" + Ident + "'");
                }
            }
            else
            {
                if (info.CurrentNamespace != null &&
                    info.Namespaces.ContainsKey(info.CurrentNamespace) &&
                    info.Namespaces[info.CurrentNamespace].ContainsIdent(Ident))
                {
                    return(info.Namespaces[info.CurrentNamespace].GetIdent(Ident).Type);
                }

                if (info.Globals.ContainsIdent(Ident))
                {
                    return(info.Globals.GetIdent(Ident).Type);
                }

                throw new IVirtualMachine.InternalError("Use of unkwon identifier '" + Ident + "'");
            }
        }
Пример #5
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);
        }
Пример #6
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);
        }