예제 #1
0
        public Boolean ParseEntrypoints()
        {
            VerifySyntaxToken(TokenType.OpenBlock, "{");
            while (true)
            {
                if (!Enumerator.HasToken())
                {
                    throw new MicroassemblerParseException(Enumerator.Last, "Pair or } expected");
                }
                if (Enumerator.Current.TokenType == TokenType.CloseBlock)
                {
                    Enumerator.Advance();
                    break;
                }
                if (Enumerator.Current.TokenType == TokenType.Pair)
                {
                    Object[] pair = Enumerator.Current.Value as Object[];
                    Enumerator.Advance();
                    if (!(pair[1] is String))
                    {
                        throw new MicroassemblerParseException(Enumerator.Last, "Entrypoint pair value must be a symbol");
                    }
                    String symbol = (String)pair[1];
                    if (pair[0] is String)
                    {
                        String key = pair[0] as String;
                        switch (key.ToLower())
                        {
                        case "fetch":
                            Microprogram.FetchEntrypoint = symbol;
                            break;

                        case "interrupt":
                            Microprogram.InterruptEntrypoint = symbol;
                            break;

                        default: throw new MicroassemblerParseException(Enumerator.Last, $"Invalid entrypoint '{key}'");
                        }
                    }
                    else if (pair[0] is long)
                    {
                        int entryIndex = Convert.ToInt32(pair[0]);
                        if (Microprogram.InstructionEntrypoints.ContainsKey(entryIndex))
                        {
                            Console.WriteLine($"Warning: Duplicate entrypoint definition on line {Enumerator.Last.Line}, previous value overridden");
                        }
                        Microprogram.InstructionEntrypoints[entryIndex] = symbol;
                    }
                    else
                    {
                        throw new MicroassemblerParseException(Enumerator.Last, "Invalid Entrypoint");
                    }

                    if (Enumerator.HasNext() && Enumerator.Next.TokenType == TokenType.Pair)
                    {
                        VerifySyntaxToken(TokenType.ListDelimeter, ",");
                    }
                    if (Enumerator.HasNext() && Enumerator.Next.TokenType == TokenType.CloseBlock)
                    {
                        DiscardOptionalToken(TokenType.ListDelimeter, ",");
                    }
                }
                else
                {
                    throw new MicroassemblerParseException(Enumerator.Current, "Pair expected");
                }
            }
            return(true);
        }
예제 #2
0
        public Microprogram ParseProgram(String program)
        {
            Microprogram = new Microprogram();
            Enumerator   = Tokenizer.Tokenize(program);
            if (Enumerator == null)
            {
                return(null);
            }
            while (Enumerator.HasToken())
            {
                Token token = Enumerator.Current;
                Enumerator.Advance();
                if (token.TokenType == TokenType.Word)
                {
                    String keyword = (String)token.Value;
                    switch (keyword.ToLower())
                    {
                    case "config":
                        if (!ProcessConfigs())
                        {
                            return(null);
                        }
                        break;

                    case "const":
                        if (!ProcessConstant())
                        {
                            return(null);
                        }
                        break;

                    case "control":
                        if (!ProcessControlWordLabel())
                        {
                            return(null);
                        }
                        break;

                    case "sequence":
                        if (!ProcessSequence())
                        {
                            return(null);
                        }
                        break;

                    case "macro":
                        if (!ProcessMacro())
                        {
                            return(null);
                        }
                        break;

                    case "empty":
                        if (!ParseEmpty())
                        {
                            return(null);
                        }
                        break;

                    case "entrypoints":
                        if (!ParseEntrypoints())
                        {
                            return(null);
                        }
                        break;

                    default:
                        throw new MicroassemblerParseException(token, "Keyword expected");
                    }
                }
                else
                {
                    throw new MicroassemblerParseException(token, "Keyword expected");
                }
            }
            //Config sanity checks
            if (Microprogram.MicroprogramLength <= 0)
            {
                throw new MicroassemblerParseException($"The microprogram length must be greater than zero");
            }
            if (Microprogram.OpcodeWidth <= 0)
            {
                throw new MicroassemblerParseException($"The opcode width must be greater than zero");
            }
            if (Microprogram.ControlWordWidth <= 0)
            {
                throw new MicroassemblerParseException($"The control word width must be greater than zero");
            }
            if (Microprogram.BankSelectorMask.Length <= 0)
            {
                throw new MicroassemblerParseException($"The bank selector width must be greater than zero");
            }
            if (Microprogram.BankSelectorMask.Length + 1 >= Microprogram.ControlWordWidth)
            {
                throw new MicroassemblerParseException($"Control word width of {Microprogram.ControlWordWidth} is invalid, as the bank selector has a width of {Microprogram.BankSelectorMask.Length}");
            }
            //Check control word label lengths
            foreach (ControlWordLabel cw in Microprogram.ControlWordLabels.Values)
            {
                if (cw.Mask.Length <= 0)
                {
                    throw new MicroassemblerParseException($"Control word label {cw.Name} must have a length that is geater than zero");
                }
                if (cw.Mask.Length + Microprogram.BankSelectorMask.Length > Microprogram.ControlWordWidth)
                {
                    throw new MicroassemblerParseException($"Control word label {cw.Name} exceeds the maximum control word width of {Microprogram.ControlWordWidth - Microprogram.BankSelectorMask.Length}");
                }
            }
            return(Microprogram);
        }