コード例 #1
0
ファイル: Parser.cs プロジェクト: arlm/MixEmul
        static SymbolBase ParseLocField(string locField, ParsingStatus status)
        {
            if (locField == "")
            {
                return(null);
            }

            status.LineSection = LineSection.LocationField;

            var symbol = ValueSymbol.ParseDefinition(locField, 0, status);

            if (symbol == null)
            {
                status.ReportParsingError(0, locField.Length, "invalid symbol name");
                return(null);
            }

            if (status.Symbols.Contains(symbol))
            {
                symbol = status.Symbols[symbol.Name];

                if (symbol.IsSymbolDefined && !symbol.IsMultiValuedSymbol)
                {
                    status.ReportParsingError(0, locField.Length, "symbol already defined");
                    return(null);
                }

                return(symbol);
            }

            status.Symbols.Add(symbol);
            return(symbol);
        }
コード例 #2
0
ファイル: Parser.cs プロジェクト: arlm/MixEmul
        /// <summary>
        /// This method is used to handle instructions targeted at the assembler itself.
        /// </summary>
        static bool HandleAssemblyInstruction(string opField, string addressField, SymbolBase symbol, ParsingStatus status)
        {
            IValue expression;

            status.LineSection = LineSection.AddressField;
            switch (opField)
            {
            case "EQU":
                // set value of the instruction symbol (first field) to the value of the expression that is in the address field
                if (symbol != null)
                {
                    expression = WValue.ParseValue(addressField, 0, status);

                    if (!expression.IsValueDefined(status.LocationCounter))
                    {
                        status.ReportParsingError(0, addressField.Length, "expression value is undefined");
                        return(true);
                    }

                    symbol.SetValue(expression.GetSign(status.LocationCounter), expression.GetMagnitude(status.LocationCounter));
                }

                return(true);

            case "ORIG":
                // set the location counter to the value of the expression that is in the address field
                expression = WValue.ParseValue(addressField, 0, status);

                if (!expression.IsValueDefined(status.LocationCounter))
                {
                    status.ReportParsingError(0, addressField.Length, "expression value is undefined");
                    return(true);
                }

                status.LocationCounter = (int)expression.GetValue(status.LocationCounter);

                return(true);

            case "CON":
            case "ALF":
                // these instructions set the value of the memory word at the location counter, which is actually a loader instruction.
                // However, during assembly these memory words must be skipped, which is why we increase the location counter.
                status.LocationCounter++;

                return(true);
            }

            return(false);
        }
コード例 #3
0
ファイル: Parser.cs プロジェクト: arlm/MixEmul
        static ParsedSourceLine ParseLine(string sourceLine, ParsingStatus status)
        {
            if (IsCommentLine(sourceLine))
            {
                return(new ParsedSourceLine(status.LineNumber, sourceLine));
            }

            var lineFields = SplitLine(sourceLine);

            lineFields[locFieldIndex]     = lineFields[locFieldIndex].ToUpper();
            lineFields[opFieldIndex]      = lineFields[opFieldIndex].ToUpper();
            lineFields[addressFieldIndex] = lineFields[addressFieldIndex].ToUpper();

            if (lineFields[opFieldIndex] == "")
            {
                status.ReportParsingError(LineSection.LocationField, 0, sourceLine.Length, "op and address fields are missing");

                return(new ParsedSourceLine(status.LineNumber, lineFields[0], "", "", "", null, null));
            }

            var symbol = ParseLocField(lineFields[locFieldIndex], status);

            // if the location field contains a symbol name, set its value to the location counter
            symbol?.SetValue(status.LocationCounter);

            GetMixOrLoaderInstructionAndParameters(lineFields[opFieldIndex], lineFields[addressFieldIndex], status, out InstructionBase instruction, out IInstructionParameters instructionParameters);

            // the following call must be made even if a MIX or loader instruction was found, as some loader instructions require the assembler to act, as well
            var assemblyInstructionHandled = HandleAssemblyInstruction(lineFields[opFieldIndex], lineFields[addressFieldIndex], symbol, status);

            // if the line isn't a comment or a MIX or loader instruction, it must be an assembler instruction. If not, we don't know the mnemonic
            if (instruction == null && !assemblyInstructionHandled)
            {
                status.ReportParsingError(LineSection.OpField, 0, lineFields[opFieldIndex].Length, "operation mnemonic unknown");
            }

            return(new ParsedSourceLine(status.LineNumber, lineFields[locFieldIndex], lineFields[opFieldIndex], lineFields[addressFieldIndex], lineFields[commentFieldIndex], instruction, instructionParameters));
        }