Example #1
0
        public string GenerateHTML(ComputerModel model, string stylesheet = null)
        {
            XmlDocument html = (XmlDocument)HtmlTemplate.CloneNode(true);

            GenerateTitle(model, html);
            if (stylesheet != null)
            {
                ReplaceStylesheet(html, stylesheet);
            }
            XmlElement div = html.GetElementsByTagName("div").OfType <XmlElement>().First(e => e.GetAttribute("class") == "boxes");

            foreach (Pin pin in model.Pins.OrderBy(p => p.Offset))
            {
                XmlElement template = (XmlElement)CheckboxTemplate.DocumentElement.CloneNode(true);
                XmlElement input    = (XmlElement)template.GetElementsByTagName("input").Item(0);
                XmlElement label    = (XmlElement)template.GetElementsByTagName("label").Item(0);
                if (pin.Type == PinType.Intermediate)
                {
                    input.SetAttribute("class", "intermediate-box");
                    template.RemoveChild(label);
                }
                else
                {
                    if (pin.FirstOfType)
                    {
                        label.InnerText = string.Format(label.InnerText, pin.NameOfType);
                    }
                    else
                    {
                        template.RemoveChild(label);
                    }
                    if (pin.Type == PinType.Input)
                    {
                        input.SetAttribute("class", "input-box");
                    }
                    else
                    {
                        input.SetAttribute("class", "output-box");
                    }
                }
                foreach (XmlNode node in template.ChildNodes)
                {
                    div.AppendChild(html.ImportNode(node, true));
                }
            }
            StringBuilder str = new StringBuilder();

            str.AppendLine("<!DOCTYPE html>");
            XmlWriterSettings settings = new XmlWriterSettings {
                OmitXmlDeclaration = true
            };

            using (XmlWriter writer = XmlWriter.Create(str, settings)) {
                html.WriteTo(writer);
            }
            return(str.ToString());
        }
Example #2
0
        public string GenerateCSS(ComputerModel model)
        {
            StringBuilder css = new StringBuilder();

            css.AppendLine(CssHeader);
            foreach (TruthTable table in model.TruthTables)
            {
                foreach (bool[] key in table.Table.Keys)
                {
                    bool value = table.Table[key];
                    int  i     = 0;
                    css.Append(".run:checked ~ .boxes ");
                    foreach (Pin pin in table.Inputs.OrderBy(p => p.Offset))
                    {
                        AddressPin(model, css, pin, key[i++]);
                        css.Append(" ~ ");
                    }
                    AddressPin(model, css, table.Output, value);
                    css.Append(", .run:checked ~ .boxes ");
                    i = 0;
                    foreach (Pin pin in table.Inputs.OrderBy(p => p.Offset))
                    {
                        AddressPin(model, css, pin, key[i++]);
                        css.Append(" ~ ");
                    }
                    AddressPin(model, css, table.Output, value);
                    css.Append(" + svg {");
                    css.Append(ValidCss);
                    css.AppendLine(" }");
                    i = 0;
                    css.Append(".run:checked ~ .boxes ");
                    foreach (Pin pin in table.Inputs.OrderBy(p => p.Offset))
                    {
                        AddressPin(model, css, pin, key[i++]);
                        css.Append(" ~ ");
                    }
                    AddressPin(model, css, table.Output, !value);
                    css.Append(", .run:checked ~ .boxes ");
                    i = 0;
                    foreach (Pin pin in table.Inputs.OrderBy(p => p.Offset))
                    {
                        AddressPin(model, css, pin, key[i++]);
                        css.Append(" ~ ");
                    }
                    AddressPin(model, css, table.Output, !value);
                    css.Append(" + svg {");
                    css.Append(InvalidCss);
                    css.AppendLine(" }");
                }
            }
            return(css.ToString());
        }
Example #3
0
 void Run()
 {
     try {
         FileSystemWatcher watcher = new FileSystemWatcher(Directory, string.Concat(ChipName, ".hdl"));
         ComputerModel     model   = GenerateModel();
         lock (ModelLock) {
             CurrentModel = model;
         }
         InitialParseSemaphore.Release();
         while (true)
         {
             watcher.WaitForChanged(WatcherChangeTypes.All);
             Console.WriteLine("Changes detected.  Reparsing file.");
             model = GenerateModel();
             lock (ModelLock) {
                 CurrentModel = model;
             }
         }
     } catch (ThreadInterruptedException) {
     }
 }
Example #4
0
        static void Main(string[] args)
        {
            Options opts = new Options(args);

            if (opts.ParseFailureReason != null)
            {
                Console.Error.WriteLine(opts.ParseFailureReason);
                Console.Error.WriteLine();
                Options.PrintHelp(Console.Error);
                Environment.Exit(1);
            }
            else if (opts.ShowHelp)
            {
                Options.PrintHelp(Console.Out);
            }
            else if (opts.ShowVersion)
            {
                Options.PrintVersion(Console.Out);
            }
            else
            {
                FileParser parser     = new FileParser(opts.Input);
                Translator translator = new Translator();
                if (opts.Output == null)
                {
                    using (HttpListener listener = new HttpListener()) {
                        listener.Prefixes.Add(string.Format("http://+:{0}/", opts.Port));
                        listener.Start();
                        parser.WaitForInitialParse();
                        Console.WriteLine("Listening on http://localhost:{0}/...", opts.Port);
                        while (true)
                        {
                            HttpListenerContext ctx   = listener.GetContext();
                            ComputerModel       model = parser.Model;
                            string content;
                            if (ctx.Request.Url.PathAndQuery == "/style.css")
                            {
                                content = translator.GenerateCSS(model);
                                ctx.Response.ContentType = "text/css";
                            }
                            else
                            {
                                content = translator.GenerateHTML(model);
                                ctx.Response.ContentType = "text/html";
                            }
                            byte[] buffer = Encoding.UTF8.GetBytes(content);
                            ctx.Response.ContentLength64 = buffer.Length;
                            ctx.Response.OutputStream.Write(buffer, 0, buffer.Length);
                            ctx.Response.OutputStream.Close();
                        }
                    }
                }
                else
                {
                    parser.WaitForInitialParse();
                    ComputerModel model = parser.Model;
                    parser.Stop();
                    string stylesheet = Path.Combine(Path.GetDirectoryName(opts.Output), string.Concat(Path.GetFileNameWithoutExtension(opts.Output), ".css"));
                    File.WriteAllText(opts.Output, translator.GenerateHTML(model, Path.GetFileName(stylesheet)));
                    File.WriteAllText(stylesheet, translator.GenerateCSS(model));
                    Console.WriteLine("Document written to {0}", opts.Output);
                }
            }
        }
Example #5
0
        ComputerModel GenerateModel()
        {
            ComputerModel model = new ComputerModel {
                Name = ChipName
            };

            foreach (ReadLine line in ReadFile(ChipName, "", new Dictionary <string, string>()))
            {
                Console.WriteLine(string.Join(" ", line.Tokens));
                switch (line.Tokens[0])
                {
                case "input":
                case "output":
                case "pin":
                    if (line.Tokens.Length != 3)
                    {
                        Console.Error.WriteLine("Invalid {0} command: invalid number of arguments ({1}:{2})", line.Tokens[0], line.FileName, line.LineNumber);
                        return(model);
                    }
                    PinType type;
                    switch (line.Tokens[0])
                    {
                    case "input":
                        type = PinType.Input;
                        break;

                    case "output":
                        type = PinType.Output;
                        break;

                    default:
                        type = PinType.Intermediate;
                        break;
                    }
                    int width;
                    if (!int.TryParse(line.Tokens[2], out width) || width < 1)
                    {
                        Console.Error.WriteLine("Invalid {0} command: invalid width '{1}' ({2}:{3})", line.Tokens[0], line.Tokens[2], line.FileName, line.LineNumber);
                        return(model);
                    }
                    if (width == 1)
                    {
                        model.Pins.Add(new Pin {
                            Type        = type,
                            Name        = line.Tokens[1],
                            NameOfType  = line.Tokens[1],
                            FirstOfType = true
                        });
                    }
                    else
                    {
                        model.Pins.AddRange(Enumerable.Range(1, width).Select(i => new Pin {
                            Type        = type,
                            Name        = string.Format("{0}{1}", line.Tokens[1], width - i),
                            NameOfType  = line.Tokens[1],
                            FirstOfType = i == 1
                        }));
                    }
                    break;

                case "truth":
                    if (line.Tokens.Length < 5)
                    {
                        Console.Error.WriteLine("Invalid truth command: invalid number of arguments ({0}:{1})", line.FileName, line.LineNumber);
                        return(model);
                    }
                    TruthTable table = new TruthTable {
                        Inputs = line.Tokens[1].Split(',').Select(s => model.Pins.FirstOrDefault(p => p.Name == s)).ToList(),
                        Output = model.Pins.FirstOrDefault(p => p.Name == line.Tokens[2] && p.Type != PinType.Input)
                    };
                    if (table.Inputs.Any(p => p == null) || table.Output == null)
                    {
                        Console.Error.WriteLine("Unknown pin reference in truth table ({0}:{1})", line.FileName, line.LineNumber);
                        return(model);
                    }
                    if (line.Tokens.Length != 3 + Math.Pow(2, table.Inputs.Count))
                    {
                        Console.Error.WriteLine("Invalid truth command: invalid number of arguments ({0}:{1})", line.FileName, line.LineNumber);
                        return(model);
                    }
                    bool[] key = new bool[table.Inputs.Count];
                    Array.Fill(key, false);
                    for (int i = 3; i < line.Tokens.Length; ++i)
                    {
                        bool value;
                        switch (line.Tokens[i])
                        {
                        case "0":
                            value = false;
                            break;

                        case "1":
                            value = true;
                            break;

                        default:
                            Console.Error.WriteLine("Invalid truth command: invalid value ({0}:{1})", line.FileName, line.LineNumber);
                            return(model);
                        }
                        bool[] copy = new bool[key.Length];
                        Array.Copy(key, copy, key.Length);
                        table.Table[copy] = value;
                        for (int j = key.Length - 1; j >= 0; --j)
                        {
                            if (key[j])
                            {
                                key[j] = false;
                            }
                            else
                            {
                                key[j] = true;
                                break;
                            }
                        }
                    }
                    model.TruthTables.Add(table);
                    break;

                default:
                    Console.Error.WriteLine("Invalid command '{0}' ({1}:{2})", line.Tokens[0], line.FileName, line.LineNumber);
                    return(model);
                }
            }
            int offset = 0;

            foreach (Pin pin in model.Pins.Where(p => p.Type == PinType.Input))
            {
                pin.Offset = offset++;
            }
            HashSet <Pin> unmapped = model.Pins.Where(p => p.Type == PinType.Intermediate).ToHashSet();

            while (unmapped.Count > 0)
            {
                Pin[] toMap = unmapped.Where(p => model.TruthTables.Where(t => t.Output == p).All(t => t.Inputs.All(p2 => !unmapped.Contains(p2)))).ToArray();
                foreach (Pin pin in toMap)
                {
                    pin.Offset = offset++;
                    unmapped.Remove(pin);
                }
                if (toMap.Length == 0)
                {
                    Console.Error.WriteLine("Unable to map pins without recursion.");
                    Console.Error.WriteLine("The following pins failed:");
                    foreach (Pin pin in unmapped)
                    {
                        Console.Error.WriteLine("    {0}", pin.Name);
                    }
                    return(model);
                }
            }
            foreach (Pin pin in model.Pins.Where(p => p.Type == PinType.Output))
            {
                pin.Offset = offset++;
            }
            return(model);
        }
Example #6
0
 void AddressPin(ComputerModel model, StringBuilder css, Pin pin, bool value)
 {
     css.AppendFormat("input:nth-of-type({0}):{1}", pin.Offset + 1, value ? "checked" : "not(:checked)");
 }
Example #7
0
        void GenerateTitle(ComputerModel model, XmlDocument html)
        {
            XmlElement title = (XmlElement)html.GetElementsByTagName("title").Item(0);

            title.InnerText = string.Format(title.InnerText, model.Name);
        }