Beispiel #1
0
        public void Test_GenerateTokens_CanTraverseEntireFileAndThrowErrors(string content)
        {
            StreamReader FakeReader = CreateFakeReader(content, Encoding.UTF8);

            Tokeniser tokeniser = new Tokeniser(FakeReader);

            tokeniser.GenerateTokens();
            Assert.IsTrue(Tokeniser.HasError);
        }
Beispiel #2
0
        public void Test_GenerateTokens_CanNotGenrateInvalidRanges()
        {
            string       content    = "a is 0...5";
            StreamReader FakeReader = CreateFakeReader(content, Encoding.UTF8);

            Tokeniser tokeniser = new Tokeniser(FakeReader);

            tokeniser.GenerateTokens();
            Assert.IsTrue(Tokeniser.HasError);
        }
Beispiel #3
0
        public void Test_GenerateTokens_CanTraverseEntireFileWithNoErrorsAndCorrentAmountOfTokens(string content, int expectedAmountOfTokens)
        {
            StreamReader FakeReader = CreateFakeReader(content, Encoding.UTF8);

            Tokeniser tokeniser = new Tokeniser(FakeReader);

            tokeniser.GenerateTokens();

            Assert.AreEqual(expectedAmountOfTokens, tokeniser.Tokens.Count, "tokeniser did not generate the correct amount of tokens.");
        }
Beispiel #4
0
        public void Test_GenerateTokens_ThrowsExceptionOnInvalidMultilineComment()
        {
            string       content    = "#< comment";
            StreamReader FakeReader = CreateFakeReader(content, Encoding.UTF8);

            Tokeniser tokeniser = new Tokeniser(FakeReader);

            tokeniser.GenerateTokens();
            Assert.IsTrue(Tokeniser.HasError);
        }
Beispiel #5
0
        public void Test_GenerateTokens_TokenListIsEmpty()
        {
            string       content    = "";
            StreamReader FakeReader = CreateFakeReader(content, Encoding.UTF8);

            Tokeniser tokeniser = new Tokeniser(FakeReader);

            tokeniser.GenerateTokens();

            Assert.AreEqual(0, tokeniser.Tokens.Count, "TokenList had the wrong amount of tokens");
        }
Beispiel #6
0
        public void Test_GenerateTokens_GeneratesMultiLineCommentToken()
        {
            string       content    = "#< comment >#";
            StreamReader FakeReader = CreateFakeReader(content, Encoding.UTF8);

            Tokeniser tokeniser = new Tokeniser(FakeReader);

            tokeniser.GenerateTokens();

            Assert.AreEqual(TokenType.MULT_COMNT, tokeniser.Tokens.First.Value.Type, "The tokeniser did not recognise the comment as a comment");
        }
Beispiel #7
0
        public void Test_GenerateTokens_CanScanMultilineComments()
        {
            string       content    = "#< comment >#";
            StreamReader FakeReader = CreateFakeReader(content, Encoding.UTF8);

            Tokeniser tokeniser = new Tokeniser(FakeReader);

            tokeniser.GenerateTokens();

            Assert.AreEqual(1, tokeniser.Tokens.Count, "The tokeniser did not recognise a comment");
        }
Beispiel #8
0
        public void Test_GenerateTokens_TokenListNotEmpty()
        {
            string       content    = "a is 4";
            StreamReader FakeReader = CreateFakeReader(content, Encoding.UTF8);

            Tokeniser tokeniser = new Tokeniser(FakeReader);

            tokeniser.GenerateTokens();

            Assert.AreEqual(3, tokeniser.Tokens.Count, "TokenList generated the wrong amound of tokens. Should contain elements more than just PROG and EOF");
        }
Beispiel #9
0
        public void Test_ASTHelper_Constructor(string content)
        {
            StreamReader FakeReader = CreateFakeReader(content, Encoding.UTF8);
            Tokeniser    tokeniser  = new Tokeniser(FakeReader);

            tokeniser.GenerateTokens();
            List <ScannerToken> tokens = tokeniser.Tokens.ToList();

            Parser.Parser parser = new Parser.Parser(tokens);
            parser.Parse(out nowhere);
            Assert.IsFalse(Parser.Parser.HasError, "The parser encountered an error");
        }
Beispiel #10
0
        public void Test_GenerateTokens_CanGenerateRanges()
        {
            string       content    = "a is 0..5";
            StreamReader FakeReader = CreateFakeReader(content, Encoding.UTF8);

            Tokeniser tokeniser = new Tokeniser(FakeReader);

            tokeniser.GenerateTokens();


            Assert.AreEqual(5, tokeniser.Tokens.Count, $"The tokeniser found the wrong amount of tokens.");
        }
Beispiel #11
0
        public void Test_AssignmentNode_NodeHasNoOperator()
        {
            StreamReader reader    = CreateFakeReader(program2);
            Tokeniser    tokeniser = new Tokeniser(reader);

            tokeniser.GenerateTokens();
            Parser.Parser parser = new Parser.Parser(tokeniser.Tokens.ToList());
            parser.Parse(out nowhere);
            Assert.IsFalse(Parser.Parser.HasError, "Parser encountered an error state:\n\n" + nowhere);
            parser.Root.Accept(new TypeChecker(new List <string>()
            {
                "3", "5", "6", "9", "10", "11"
            }));
            Assert.IsNull(((AssignmentNode)parser.Root.Statements[0]).Operator, "Operator was not null for assignment node");
        }
Beispiel #12
0
        public void Test_TypeChecker_CheckHasNoErrors(string program)
        {
            StreamReader reader    = CreateFakeReader(program);
            Tokeniser    tokeniser = new Tokeniser(reader);

            tokeniser.GenerateTokens();
            Parser.Parser parser = new Parser.Parser(tokeniser.Tokens.ToList());
            parser.Parse(out nowhere);
            Assert.IsFalse(Parser.Parser.HasError, "Parser encountered an error state:\n\n" + nowhere);
            parser.Root.Accept(new TypeChecker(new List <string>()
            {
                "3", "5", "6", "9", "10", "11"
            }));
            Assert.IsFalse(TypeChecker.HasError, "Typechecker encountered an error.");
        }
Beispiel #13
0
        public void Test_ASTHelper_Assign_2(string test)
        {
            StreamReader FakeReader = CreateFakeReader(test, Encoding.UTF8);
            Tokeniser    tokeniser  = new Tokeniser(FakeReader);

            tokeniser.GenerateTokens();
            List <ScannerToken> tokens = tokeniser.Tokens.ToList();

            Parser.Parser parser = new Parser.Parser(tokens);
            parser.Parse(out nowhere);
            if (Parser.Parser.HasError)
            {
                Assert.Fail();
            }
            parser.Root.Accept(new PrettyPrinter());
        }
Beispiel #14
0
        public void Test_TypeChecker_CanThrowExceptions(string program)
        {
            StreamReader reader    = CreateFakeReader(program);
            Tokeniser    tokeniser = new Tokeniser(reader);

            tokeniser.GenerateTokens();
            Parser.Parser parser = new Parser.Parser(tokeniser.Tokens.ToList());
            parser.Parse(out nowhere);
            Assert.IsFalse(Parser.Parser.HasError, "Parser encountered an error state:\n\n" + nowhere);
            try {
                parser.Root.Accept(new TypeChecker(new List <string>()
                {
                    "3", "5", "6", "9", "10", "11"
                }));
            } catch {
            }
            Assert.IsTrue(TypeChecker.HasError, "The error was not caught");
        }
Beispiel #15
0
        public void Test_Program(string program)
        {
            StreamReader FakeReader = CreateFakeReader(program, Encoding.UTF8);
            Tokeniser    tokeniser  = new Tokeniser(FakeReader);

            tokeniser.GenerateTokens();
            List <ScannerToken> tokens = tokeniser.Tokens.ToList();

            Parser.Parser parser = new Parser.Parser(tokens);
            parser.Parse(out nowhere);
            if (Parser.Parser.HasError)
            {
                Assert.Fail();
            }
            parser.Root.Accept(new TypeChecker(new List <string>()
            {
                "3", "5", "6", "9", "10", "11"
            }));
            CodeGenerationVisitor codeGenerationVisitor = new CodeGenerationVisitor("Codegen_output.cpp", new List <string>());

            parser.Root.Accept(codeGenerationVisitor);
        }
        public void Test_CodeGenVisitor_pin_fail()
        {
            StreamReader FakeReader = CreateFakeReader(pin_fail, Encoding.UTF8);
            Tokeniser    tokeniser  = new Tokeniser(FakeReader);

            tokeniser.GenerateTokens();
            List <ScannerToken> tokens = tokeniser.Tokens.ToList();

            Parser.Parser parser = new Parser.Parser(tokens);
            parser.Parse(out dbg);
            if (Parser.Parser.HasError)
            {
                Assert.Fail("The parser encountered an error\n\n" + dbg);
            }
            parser.Root.Accept(new TypeChecker(new List <string>()
            {
                "3", "5", "6", "9", "10", "11"
            }));
            Assert.IsFalse(TypeChecker.HasError, "Typechecker visitor encountered an error");
            CodeGenerationVisitor codeGenerationVisitor = new CodeGenerationVisitor("Codegen_output.cpp", new List <string>());

            parser.Root.Accept(codeGenerationVisitor);
            Assert.IsTrue(CodeGenerationVisitor.HasError, "Code gen visitor encountered an error");
        }
Beispiel #17
0
        /// <summary>
        /// The entry point of the compiler.
        /// Here the user must provide a set of compiler flags, in order for the compiler to produce a satisfying product.
        /// The user must provide a filepath to the file they wish to compile. Otherwise the compiler will halt and exit with an exit code of 1.
        /// Compiler flags can be provided to activate additional functionality.
        /// **Compiler flags**
        /// `-d` or `--dryrun` Runs the compiler without producing an output.
        /// `-o` or `--output` Tells the compiler not to write to the Arduino, and instead produce a file.
        /// `-v` or `--verbose` Prints additional information when compiling.
        /// `-b` or `--boilerplate` Generates a boilerplate file for your code.
        /// `-l` or `--logfile` (Must be followed by a file path) Prints additional information when compiling.
        /// `-p` or `--port` (Must be followed by a port number) Specifies the port to upload to.
        /// `-a` or `--arduino` (Must be followed by an Arduino model) Specifies the arduino model you're uploading to. (Default: UNO)
        /// `-pr` or `--proc` (Must be followed by a valid processor) Specifies the arduino processor you're uploading to. (Default: atmega328p)
        /// `-pp` or `--prettyprinter` Print the abstract syntax tree.
        /// **Compiler exit code**
        /// `0` Compilation finished with no errors.
        /// `1` A file path was not provided to the compiler for compilation.
        /// `20` The file provided was not encoded as a UTF-8 file.
        /// `5` An error was encountered while scanning the input program. This is usually caused by an unclosed string, comment, or parenthesis.
        /// `4` An error was encountered in the parser. This is usually due to an invalidly structured program.
        /// `3` An error was encountered in the type checker. This happens when two types are mismatched, either on assignment or within an expression. Furthermore, this can be caused by not defining a called function, or a function being defined multiple times.
        /// `2` This error is encountered when the code generator can not find the output file for the intermediate representation code.
        /// `23` This error is encountered when the dryrun flag is invoked, but the compiler can not find the output file for the intermediate representation code.
        /// </summary>
        /// <param name="args">The arguments passed to the compiler from the terminal.</param>
        /// <returns>An exit code representing the state the compiler exited in.</returns>
        public static int Main(string[] args)
        {
            Stopwatch timer = new Stopwatch();

            timer.Start();
            options        = ParseOptions(args);
            verbosePrinter = new VerbosePrinter(options);
            if (options?.InputFile == null)
            {
                Help();
                verbosePrinter.Error("Input file was not specified.");
                return(1);
            }
            if (options.Boilerpate)
            {
                using (StreamReader reader = new StreamReader(AppContext.BaseDirectory + "/boilerplate"))
                {
                    verbosePrinter.Info("Reading boilerplate template");
                    string content = reader.ReadToEnd();
                    using (StreamWriter writer = new StreamWriter(options.InputFile))
                    {
                        verbosePrinter.Info("Writing boilerplate template to file");
                        writer.Write(content);
                    }
                }
                verbosePrinter.Info("Done.");
                return(0);
            }

            verbosePrinter.Info("Initialising file.");
            using (StreamReader reader = new StreamReader(options.InputFile))
            {
                try
                {
                    verbosePrinter.Info("Checking encoding...");
                    FileChecker.CheckEncoding(reader);
                    verbosePrinter.Info($" Encoding was {reader.CurrentEncoding}.");
                }
                catch (EncodingNotSupportedException e)
                {
                    verbosePrinter.Error("File not encoded correctly.");
                    Console.Error.WriteLine(e.Message);
                    return(20);
                }
                Tokeniser tokeniser = new Tokeniser(reader);
                verbosePrinter.Info("Generating tokens...");
                tokeniser.GenerateTokens();
                if (Tokeniser.HasError)
                {
                    verbosePrinter.Error("Encountered syntax errors. Stopping.");
                    return(5);
                }
                verbosePrinter.Info($" Generated {tokeniser.Tokens.Count} tokens.");
                if (options.Verbose)
                {
                    foreach (var token in tokeniser.Tokens)
                    {
                        verbosePrinter.Info(token);
                    }
                }
                verbosePrinter.Info("Generating parse table");
                List <ScannerToken> tokens = tokeniser.Tokens.ToList();
                Parser.Parser       parser = new Parser.Parser(tokens);
                string debugMessage        = "";
                parser.Parse(out debugMessage);
                verbosePrinter.Info(debugMessage);
                if (Parser.Parser.HasError)
                {
                    verbosePrinter.Error("Encountered an error state in the parser. Stopping.");
                    return(4);
                }
                if (options.PrettyPrinter)
                {
                    parser.Root.Accept(new PrettyPrinter());
                }
                try {
                    parser.Root.Accept(new TypeChecker(GetPWMSet()));
                } catch {
                    verbosePrinter.Error("Encountered an error in the type checker. Stopping.");
                    return(3);
                }
                if (TypeChecker.HasError)
                {
                    verbosePrinter.Error("Encountered an error in the type checker. Stopping.");
                    return(3);
                }

                string path = AppContext.BaseDirectory;

                try
                {
                    if (File.Exists($"{path}PrecompiledBinaries/tmp/sketch/output.cpp"))
                    {
                        File.Delete($"{path}PrecompiledBinaries/tmp/sketch/output.cpp");
                    }
                    parser.Root.Accept(new CodeGenerationVisitor($"{path}PrecompiledBinaries/tmp/sketch/output.cpp", GetPWMSet()));
                }
                catch (FileNotFoundException e)
                {
                    verbosePrinter.Error("Encountered an error in code generation. Stopping.");
                    Console.Error.WriteLine(e.Message);
                    return(2);
                }
                if (CodeGenerationVisitor.HasError)
                {
                    return(10);
                }
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.FreeBSD))
                {
                    Console.WriteLine("We're on Linux!");
                    if (options.Port == "COM0")
                    {
                        Console.Error.WriteLine($"Error: No Port Provided. The compiler will try to find one available.");
                        string[] devices = "ls /dev/tty*".Bash().Split("\n");
                        if (devices.Any(str => str.Contains("ACM")))
                        {
                            options.Port = devices.First(str => str.Contains("ACM"));
                        }
                    }
                    path = path.Replace(" ", "\\ ");
                    $"chmod -R a+x {path}".Bash();
                    $"{path}PrecompiledBinaries/hardware/tools/avr/bin/avr-g++ {(options.Verbose ? "-v" : "")} -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu={options.Processor} -DF_CPU=16000000L -DARDUINO=10811 -DARDUINO_AVR_{options.Arduino.ToUpper()} -DARDUINO_ARCH_AVR -I{path}PrecompiledBinaries/arduino/avr/cores/arduino -I{path}PrecompiledBinaries/hardware/arduino/avr/variants/standard {path}PrecompiledBinaries/tmp/sketch/output.cpp -o /dev/null".Bash();

                    $"{path}PrecompiledBinaries/hardware/tools/avr/bin/avr-g++ {(options.Verbose ? "-v" : "")} -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu={options.Processor} -DF_CPU=16000000L -DARDUINO=10811 -DARDUINO_AVR_{options.Arduino.ToUpper()} -DARDUINO_ARCH_AVR -I{path}PrecompiledBinaries/arduino/avr/cores/arduino -I{path}PrecompiledBinaries/hardware/arduino/avr/variants/standard {path}PrecompiledBinaries/tmp/sketch/output.cpp -o {path}PrecompiledBinaries/tmp/Preproc/ctags_target_for_gcc_minus_e.cpp".Bash();

                    $"{path}PrecompiledBinaries/tools-builder/ctags/5.8-arduino11/ctags -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives {path}PrecompiledBinaries/tmp/Preproc/ctags_target_for_gcc_minus_e.cpp".Bash();

                    $"{path}PrecompiledBinaries/hardware/tools/avr/bin/avr-g++ {(options.Verbose ? "-v" : "")} -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu={options.Processor} -DF_CPU=16000000L -DARDUINO=10811 -DARDUINO_AVR_{options.Arduino.ToUpper()} -DARDUINO_ARCH_AVR -I{path}PrecompiledBinaries/arduino/avr/cores/arduino -I{path}PrecompiledBinaries/hardware/arduino/avr/variants/standard {path}PrecompiledBinaries/tmp/sketch/output.cpp -o {path}PrecompiledBinaries/tmp/sketch/output.cpp.o".Bash();

                    $"{path}PrecompiledBinaries/hardware/tools/avr/bin/avr-gcc {(options.Verbose ? "-v" : "")} -w -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu={options.Processor} -o {path}PrecompiledBinaries/tmp/output.cpp.elf {path}PrecompiledBinaries/tmp/sketch/output.cpp.o {path}PrecompiledBinaries/randomAFile.a -L{path}PrecompiledBinaries/tmp -lm".Bash();

                    $"{path}PrecompiledBinaries/hardware/tools/avr/bin/avr-objcopy {(options.Verbose ? "-v" : "")} -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 {path}PrecompiledBinaries/tmp/output.cpp.elf {path}PrecompiledBinaries/tmp/output.cpp.eep".Bash();

                    $"{path}PrecompiledBinaries/hardware/tools/avr/bin/avr-objcopy {(options.Verbose ? "-v" : "")} -O ihex -R .eeprom {path}PrecompiledBinaries/tmp/output.cpp.elf {path}PrecompiledBinaries/tmp/output.cpp.hex".Bash();

                    if (!options.OutputFile || options.DryRun)
                    {
                        $"{path}PrecompiledBinaries/unix/avrdude {(options.Verbose ? "-v" : "")} -C{path}PrecompiledBinaries/etc/avrdude.conf -v -p{options.Processor} -carduino -P{options.Port} -b115200 -D -Uflash:w:{path}PrecompiledBinaries/tmp/output.cpp.hex:i".Bash();
                    }
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    Console.WriteLine("We're on Windows!");
                    if (options.Port == "COM0")
                    {
                        Console.Error.WriteLine($"Error: No Port Provided. The compiler will try to find one available.");
                        ProcessStartInfo psi = new ProcessStartInfo();
                        psi.FileName               = "powershell";
                        psi.UseShellExecute        = false;
                        psi.RedirectStandardOutput = true;

                        psi.Arguments = "[System.IO.Ports.SerialPort]::getportnames()";
                        Process  p       = Process.Start(psi);
                        string[] devices = p.StandardOutput.ReadToEnd().Split("\n");
                        p.WaitForExit();
                        if (devices.Any(str => str.Contains("COM")))
                        {
                            options.Port = devices.Last(str => str.Contains("COM"));
                        }
                    }
                    path = path.Replace('/', '\\');


                    $"\"{path}PrecompiledBinaries\\win\\avr-g++\" {(options.Verbose ? "-v" : "")} -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu={options.Processor} -DF_CPU=16000000L -DARDUINO=10812 -DARDUINO_AVR_{options.Arduino.ToUpper()} -DARDUINO_ARCH_AVR \"-I{path}PrecompiledBinaries\\arduino\\avr\\cores\\arduino\" \"-I{path}PrecompiledBinaries\\arduino\\avr\\variants\\standard\" \"{path}PrecompiledBinaries\\tmp\\sketch\\output.cpp\" -o nul".Cmd();

                    $"\"{path}PrecompiledBinaries\\win\\avr-g++\" {(options.Verbose ? "-v" : "")} -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu={options.Processor} -DF_CPU=16000000L -DARDUINO=10812 -DARDUINO_AVR_{options.Arduino.ToUpper()} -DARDUINO_ARCH_AVR \"-I{path}PrecompiledBinaries\\arduino\\avr\\cores\\arduino\" \"-I{path}PrecompiledBinaries\\arduino\\avr\\variants\\standard\" \"{path}PrecompiledBinaries\\tmp\\sketch\\output.cpp\" -o \"{path}PrecompiledBinaries\\tmp\\Preproc\\ctags_target_for_gcc_minus_e.cpp\"".Cmd();

                    $"\"{path}PrecompiledBinaries\\win\\ctags.exe\" {(options.Verbose ? "-v" : "")} -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives \"{path}PrecompiledBinaries\\tmp\\Preproc\\ctags_target_for_gcc_minus_e.cpp\"".Cmd();

                    $"\"{path}PrecompiledBinaries\\win\\avr-g++.exe\" {(options.Verbose ? "-v" : "")} -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu={options.Processor} -DF_CPU=16000000L -DARDUINO=10812 -DARDUINO_AVR_{options.Arduino.ToUpper()} -DARDUINO_ARCH_AVR \"-I{path}PrecompiledBinaries\\arduino\\avr\\cores\\arduino\" \"-I{path}PrecompiledBinaries\\arduino\\avr\\variants\\standard\" \"{path}PrecompiledBinaries\\tmp\\sketch\\output.cpp\" -o \"{path}PrecompiledBinaries\\tmp\\sketch\\output.cpp.o\"".Cmd();

                    $"\"{path}PrecompiledBinaries\\win\\avr-gcc.exe\" {(options.Verbose ? "-v" : "")} -w -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu={options.Processor} -o \"{path}PrecompiledBinaries\\tmp\\output.cpp.elf\" \"{path}PrecompiledBinaries\\tmp\\sketch\\output.cpp.o\" \"{path}PrecompiledBinaries\\randomAFile.a\" \"-L{path}PrecompiledBinaries\\tmp\" -lm".Cmd();

                    $"\"{path}PrecompiledBinaries\\win\\avr-objcopy.exe\" {(options.Verbose ? "-v" : "")} -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 \"{path}PrecompiledBinaries\\tmp\\output.cpp.elf\" \"{path}PrecompiledBinaries\\tmp\\output.cpp.eep\"".Cmd();

                    $"\"{path}PrecompiledBinaries\\win\\avr-objcopy.exe\" {(options.Verbose ? "-v" : "")} -O ihex -R .eeprom \"{path}PrecompiledBinaries\\tmp\\output.cpp.elf\" \"{path}PrecompiledBinaries\\tmp\\output.cpp.hex\"".Cmd();

                    if (!options.OutputFile || options.DryRun)
                    {
                        $"\"{path}PrecompiledBinaries\\win\\avrdude\" {(options.Verbose ? "-v" : "")} \"-C{path}PrecompiledBinaries\\etc\\avrdude.conf\" -v -p{options.Processor} -carduino -P{options.Port} -b115200 -D \"-Uflash:w:{path}PrecompiledBinaries\\tmp\\output.cpp.hex:i\"".Cmd();
                    }
                }
                else
                {
                    verbosePrinter.Error("OS not supported! Stopping.");
                }
                if (options.DryRun)
                {
                    try
                    {
                        File.Delete($"{path}PrecompiledBinaries/tmp/sketch/output.cpp");
                        return(0);
                    }
                    catch (FileNotFoundException e)
                    {
                        verbosePrinter.Error("Encountered an error in code generation. Stopping.");
                        Console.Error.WriteLine(e.Message);
                        return(23);
                    }
                }

                //TODO further compilation
                //"C:\\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++" -c -g -Os -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10812 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IC:\\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino" "-IC:\\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard" "C:\Users\bruger\Documents\aau\4semester\\P4\github\\P4-program\Tests\CodeGeneration.Tests\bin\Debug\netcoreapp3.1\Codegen_output.cpp" -o "C:\Users\bruger\Documents\aau\4semester\\P4\github\\P4-program\Tests\CodeGeneration.Tests\bin\Debug\netcoreapp3.1\Codegen_output.cpp.o"
            }

            timer.Stop();
            verbosePrinter.Info($"\nCompilation took {timer.Elapsed.TotalSeconds} seconds.");
            return(0);
        }