예제 #1
0
        static void AssembleStrings(SourceLine line)
        {
            if (!line.OperandHasToken)
            {
                throw new ExpressionException(line.Instruction.Position,
                                              $"Instruction \"{line.InstructionName}\" expects one or more string arguments.");
            }

            line.Assembly = new List <byte>();
            var stringBytes = new List <byte>();
            var uninit      = 0;

            foreach (Token child in line.Operand.Children)
            {
                if (child.Children.Count == 0)
                {
                    throw new ExpressionException(child.Position, $"Expected value for instruction \"{line.InstructionName}\".");
                }

                if (child.Children[0].ToString().Equals("?"))
                {
                    if (child.Children.Count > 1)
                    {
                        Assembler.Log.LogEntry(line, child.Children[1].Position,
                                               $"Unexpected expression \"{child.Children[1].Name}\".");
                    }
                    uninit++;
                    Assembler.Output.AddUninitialized(1);
                }
                else
                {
                    if (StringHelper.ExpressionIsAString(child))
                    {
                        stringBytes.AddRange(Assembler.Encoding.GetBytes(StringHelper.GetString(child)));
                    }
                    else
                    {
                        stringBytes.AddRange(BinaryOutput.ConvertToBytes(Evaluator.Evaluate(child)).ToList());
                    }
                }
            }
            switch (line.InstructionName)
            {
            case ".cstring":
                stringBytes.Add(0x00);
                break;

            case ".pstring":
                if (stringBytes.Count > 255)
                {
                    throw new ExpressionException(line.Operand.Position, $"String expression exceeds the maximum length of \".pstring\" directive.");
                }

                stringBytes.Insert(0, Convert.ToByte(stringBytes.Count));
                break;

            case ".lstring":
            case ".nstring":
                if (stringBytes.Any(b => b > 0x7f))
                {
                    throw new ExpressionException(line.Operand.Position, $"One or more elements in expression \"{line.Operand}\" exceeds maximum value.");
                }
                if (line.InstructionName.Equals(".lstring"))
                {
                    stringBytes       = stringBytes.Select(b => Convert.ToByte(b << 1)).ToList();
                    stringBytes[^ 1] |= 1;