Example #1
0
        public void HandleEmitURCL(Action <string> emit, IEnumerable <UrclInstruction> instructions)
        {
            var optimizer = new UrclOptimizer
            {
                CullCreateLabel                = true,
                CullRedundantMoves             = true,
                CullRedundantStackOps          = true,
                ReplaceImmZeroWithZeroRegister = true,
                Compatibility = Configuration.Compatibility
            };

            foreach (var inst in optimizer.Optimize(instructions.ToArray()))
            {
                emit(inst.ToString());
            }
        }
Example #2
0
        public static void HandleConfiguration(Configuration configuration)
        {
            if (configuration.ApiPort > 0)
            {
                var modules = new ModuleLoader();
                var tcp     = new TcpListener(new IPEndPoint(IPAddress.Loopback, configuration.ApiPort));

                modules.Load(configuration);
                tcp.Start();

                while (true)
                {
                    try
                    {
                        using var connection = tcp.AcceptTcpClient();
                        using var stream     = connection.GetStream();
                        using var reader     = new BinaryReader(stream);
                        using var writer     = new BinaryWriter(stream);

                        var builder     = new ConfigurationBuilder();
                        var configCount = ushort.Parse(reader.ReadString());
                        for (ushort i = 0; i < configCount; i++)
                        {
                            builder.Configure(reader.ReadString(), writer.Write);
                        }

                        writer.Write(string.Empty);
                        stream.Flush();

                        var           lang         = reader.ReadString().ToLower();
                        var           outType      = reader.ReadString().ToLower();
                        var           selectedTier = reader.ReadString().ToLower();
                        OperationType tier;

                        switch (selectedTier)
                        {
                        case "core":
                            tier = OperationType.Pragma;
                            break;

                        case "basic":
                            tier = OperationType.Basic;
                            break;

                        case "complex":
                            tier = OperationType.Complex;
                            break;

                        case "any":
                            tier = OperationType.CustomPragma;
                            break;

                        default:
                            writer.Write($"Invalid platform target \"{selectedTier}\"");
                            writer.Write(string.Empty);
                            stream.Flush();
                            continue;
                        }

                        var lineCount = ulong.Parse(reader.ReadString());

                        if (lineCount == 0)
                        {
                            continue;
                        }

                        var lines = new List <string>();

                        for (ulong i = 0; i < lineCount; i++)
                        {
                            lines.Add(reader.ReadString());
                        }

                        IEnumerable <UrclInstruction> instructions;

                        try
                        {
                            if (lang != "urcl")
                            {
                                var source = lines;
                                lines = new List <string>();
                                bool hasError = false;

                                if (!modules.ExecuteFileHandler(lang, source, lines.Add, (msg) =>
                                {
                                    hasError = true;
                                    writer.Write(msg);
                                }))
                                {
                                    throw new ParserError($"Format \"{lang}\" is not supported.");
                                }

                                if (hasError)
                                {
                                    throw new ParserError("The source was not compiled successfully.");
                                }
                            }

                            var optimizer = new UrclOptimizer
                            {
                                Compatibility = tier,
                                ReplaceImmZeroWithZeroRegister = true,
                                CullRedundantMoves             = true,
                                CullCreateLabel = true
                            };

                            instructions = optimizer.Optimize(new Parser().Parse(lines, (imp) =>
                            {
                                throw new ParserError("Imports are not supported via the API.");
                            }).ToArray());

                            if (outType == "emulate")
                            {
                                EmulatorHost.Emulator(configuration, instructions, writer.Write, () => { }, false);
                            }
                            else if (outType == "dump")
                            {
                                foreach (var inst in instructions)
                                {
                                    writer.Write(inst.ToString());
                                }
                                writer.Write(string.Empty);
                                stream.Flush();
                                continue;
                            }
                            else
                            {
                                throw new ParserError($"Invalid output type \"{outType}\".");
                            }
                        }
                        catch (ParserError ex)
                        {
                            writer.Write(ex.Message);
                            writer.Write(string.Empty);
                            stream.Flush();
                            continue;
                        }
                        catch (TargetInvocationException ex)
                        {
                            writer.Write(ex.InnerException.Message);
                            writer.Write(string.Empty);
                            stream.Flush();
                            continue;
                        }
                        catch (Exception ex)
                        {
                            writer.Write(ex.Message);
                            writer.Write(string.Empty);
                            continue;
                        }

                        writer.Write(string.Empty);
                        stream.Flush();
                    }
                    catch (Exception ex)
                    {
                        Console.Error.WriteLine($"API: {ex}");
                    }
                }
            }
        }