Пример #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
        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);
                        }
                    }
                }
            }
        }
Пример #3
0
        public void Check(ASTProgram root, CheckerInformation info)
        {
            //Fill namespaces with declaration identifiers
            //Throws an exception if an identifier is declared more then once in a namespace
            OptainNamespaceInformation(root, info);
            //Is any applied identifier declared and initialized?
            CheckForUndeclaredIdent(root, info);
            //Checks if the function parameters are valid
            CheckFunctionParameter(root, info);

            //TODO: Check: if only specified globals are accessed in procedures/functions
            //TODO: Check: Only const globals are allowed in functions
            //TODO: Check: Are only different parameters provided to a procedure as references (Never more then one reference to the same storage)
            //TODO: test05.iml: local constant variables should not be modifiable
        }
Пример #4
0
 static void Main(string[] args)
 {
     if (args.Length != 1)
     {
         Console.WriteLine("Compiler usage: iml <program>"); return;
     }
     //TestVirtualMachine.Test(); return;
     try
     {
         //Scanner
         Scanner scanner = new Scanner();
         var     list    = scanner.Scan(new StreamReader(args[0]));
         Console.WriteLine("[" + String.Join(", ", list) + "]");
         Console.WriteLine();
         //Parser
         Parser parser = new Parser();
         var    tree   = parser.Parse(list);
         //Converter
         var ast = tree.ToAbstractSyntax();
         Console.WriteLine(ast.ToString());
         Console.WriteLine();
         if (!(ast is ASTProgram))
         {
             throw new IVirtualMachine.InternalError("Generation of Abstract Syntax Tree failed.");
         }
         ASTProgram program = (ASTProgram)ast;
         //Checker
         CheckerInformation info           = new CheckerInformation();
         ScopeChecker       contextChecker = new ScopeChecker();
         contextChecker.Check(program, info);
         //Code Generator
         IVirtualMachine vm = new VirtualMachine(1000, 1000);
         program.GenerateCode(0, vm, info);
         Console.WriteLine(vm.ToString());
         Console.WriteLine();
         //Executuion
         vm.Execute();
     }
     catch (Exception ex)
     {
         Console.WriteLine("Failed: " + ex.Message);
         //*Only for debuging of the compiler */ Console.WriteLine(ex.StackTrace);
     }
 }
Пример #5
0
 private void CheckFunctionParameter(ASTProgram root, CheckerInformation info)
 {
     //Functions can only have one out/inout param (this has to be the first one)
     foreach (string ident in info.ProcFuncs)
     {
         if (info.ProcFuncs[ident].IsFunc)
         {
             var paramIttr = info.ProcFuncs[ident].Params.GetEnumerator();
             paramIttr.MoveNext();
             while (paramIttr.MoveNext())
             {
                 if (paramIttr.Current.FlowMode == FlowMode.OUT || paramIttr.Current.FlowMode == FlowMode.INOUT)
                 {
                     throw new CheckerException("A function can not have out/inout parameter.");
                 }
             }
         }
     }
 }