Exemple #1
0
 /// <summary>
 /// Adds an assembly line to the compilation
 /// </summary>
 /// <param name="line">Line to add</param>
 /// <param name="context">The context that generates this line</param>
 /// <returns>The newly added line</returns>
 private SourceLineBase AddLine(SourceLineBase line, ParserRuleContext context)
 {
     line.SourceText      = CurrentSourceText;
     line.SourceLine      = CurrentSourceLine;
     line.FirstColumn     = FirstColumn;
     line.FirstPosition   = FirstPosition;
     line.LastPosition    = LastPosition;
     line.ParserException = context.exception;
     line.Label           = CurrentLabel;
     line.LabelSpan       = LabelSpan;
     line.KeywordSpan     = KeywordSpan;
     line.NumberSpans     = NumberSpans;
     line.StringSpans     = StringSpans;
     line.FunctionSpans   = FunctionSpans;
     line.SemiVarSpans    = SemiVarSpans;
     line.MacroParamSpans = MacroParamSpans;
     line.MacroParamNames = MacroParamNames;
     line.IdentifierSpans = IdentifierSpans;
     line.StatementSpans  = StatementSpans;
     line.OperandSpans    = OperandSpans;
     line.MnemonicSpans   = MnemonicSpans;
     line.Comment         = CurrentComment;
     line.CommentSpan     = CommentSpan;
     line.IssueToEmit     = IssueToEmit;
     line.InstructionSpan = KeywordSpan != null
         ? new TextSpan(KeywordSpan.Start, LastInstructionPos + 1)
         : new TextSpan(FirstColumn, FirstColumn);
     Compilation.Lines.Add(line);
     LastAsmLine = line;
     if (line is ISupportsFieldAssignment fieldAssignment)
     {
         fieldAssignment.IsFieldAssignment = IsFieldAssignment;
     }
     return(line);
 }
Exemple #2
0
        private void AssertFilename(SourceLineBase line, string expectedFileName)
        {
            var includeLine = line as IncludeDirective;

            includeLine.ShouldNotBeNull();
            includeLine.Filename.ShouldBe(expectedFileName);
        }
 public AssemblerErrorInfo(SourceFileItem sourceItem, string errorCode, SourceLineBase line, params object[] parameters)
 {
     ErrorCode = errorCode;
     Line      = line?.SourceLine ?? 0;
     Column    = line?.FirstColumn ?? 0;
     Message   = Errors.GetMessage(ErrorCode, parameters);
     Filename  = sourceItem?.Filename;
 }
Exemple #4
0
 /// <summary>Initializes a new instance of the <see cref="T:System.Object" /> class.</summary>
 public FixupEntry(SourceLineBase sourceLine, FixupType type, int segmentIndex, int offset, ExpressionNode expression, string label = null)
 {
     SourceLine   = sourceLine;
     Type         = type;
     SegmentIndex = segmentIndex;
     Offset       = offset;
     Expression   = expression;
     Label        = label;
 }
Exemple #5
0
        /// <summary>
        /// Reports the specified error
        /// </summary>
        /// <param name="errorCode">Code of error</param>
        /// <param name="line">Source line associated with the error</param>
        /// <param name="parameters">Optional error message parameters</param>
        public void ReportError(string errorCode, SourceLineBase line, params object[] parameters)
        {
            var sourceItem = line != null
                ? Output.SourceFileList[line.FileIndex]
                : null;

            Output.Errors.Add(new AssemblerErrorInfo(sourceItem, errorCode, line, parameters));
            ReportScopeError(errorCode);
        }
Exemple #6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="T:System.Object" /> class.
 /// </summary>
 public FixupEntry(IEvaluationContext parentContext, AssemblyModule module,
                   SourceLineBase sourceLine, FixupType type,
                   int segmentIndex, int offset, ExpressionNode expression, string label = null,
                   Dictionary <ushort, byte> structBytes = null)
 {
     ParentContext = parentContext;
     Module        = module;
     SourceLine    = sourceLine;
     Type          = type;
     SegmentIndex  = segmentIndex;
     Offset        = offset;
     Expression    = expression;
     Resolved      = false;
     Label         = label;
     StructBytes   = structBytes;
 }
Exemple #7
0
 /// <summary>
 /// Adds an assebmbly line to the compilation
 /// </summary>
 /// <param name="line">Line to add</param>
 /// <param name="context">The context that generates this line</param>
 /// <returns>The newly added line</returns>
 private SourceLineBase AddLine(SourceLineBase line, ParserRuleContext context)
 {
     line.SourceLine      = _sourceLine;
     line.Position        = _firstPos;
     line.ParserException = context.exception;
     line.Label           = _label;
     line.LabelSpan       = _labelSpan;
     line.KeywordSpan     = _keywordSpan;
     line.Numbers         = _numbers;
     line.Identifiers     = _identifiers;
     line.Comment         = _comment;
     line.CommentSpan     = _commentSpan;
     Compilation.Lines.Add(line);
     LastAsmLine = line;
     return(line);
 }
        /// <summary>
        /// Evaluates the specified expression.
        /// </summary>
        /// <param name="opLine">Assembly line with operation</param>
        /// <param name="expr">Expression to evaluate</param>
        /// <returns>
        /// Null, if the expression cannot be evaluated, or evaluation
        /// results an error (e.g. divide by zero)
        /// </returns>
        public ExpressionValue Eval(SourceLineBase opLine, ExpressionNode expr)
        {
            if (expr == null)
            {
                throw new ArgumentNullException(nameof(expr));
            }
            if (!expr.ReadyToEvaluate(this))
            {
                return(ExpressionValue.NonEvaluated);
            }
            ExpressionNode.ClearErrors();
            var result = expr.Evaluate(this);

            // --- Certain symbols may not bee be evaluated
            if (result == ExpressionValue.Error)
            {
                ReportError(Errors.Z0200, opLine, expr.EvaluationError);
            }
            return(result);
        }
Exemple #9
0
        /// <summary>
        /// Evaluates the specified expression.
        /// </summary>
        /// <param name="opLine">Assembly line with operation</param>
        /// <param name="expr">Expression to evaluate</param>
        /// <returns>
        /// Null, if the expression cannot be evaluated, or evaluation
        /// results an error (e.g. divide by zero)
        /// </returns>
        public ushort?EvalImmediate(SourceLineBase opLine, ExpressionNode expr)
        {
            if (expr == null)
            {
                throw new ArgumentNullException(nameof(expr));
            }
            if (!expr.ReadyToEvaluate(this))
            {
                ReportError(Errors.Z0201, opLine);
                return(null);
            }
            var result = expr.Evaluate(this);

            if (expr.EvaluationError == null)
            {
                return(result);
            }

            ReportError(Errors.Z0200, opLine, expr.EvaluationError);
            return(null);
        }
        /// <summary>
        /// Records fixup information
        /// </summary>
        /// <param name="opLine">The operation line</param>
        /// <param name="type">Fixup type</param>
        /// <param name="expression">Fixup expression</param>
        /// <param name="label">Optional EQU label</param>
        /// <param name="structeBytes">Optional structure bytes</param>
        /// <param name="offset">Fixup offset, if not the current position</param>
        private void RecordFixup(SourceLineBase opLine, FixupType type, ExpressionNode expression,
                                 string label = null, Dictionary <ushort, byte> structeBytes = null, ushort?offset = null)
        {
            var fixupOffset = CurrentSegment.CurrentOffset;

            // --- Translate field invocation fixups so that field-related fixups will be
            // --- processed only after other fixups.
            if (IsInStructInvocation)
            {
                fixupOffset = _currentStructStartOffset + _currentStructOffset;
                if (type == FixupType.Bit8)
                {
                    type = FixupType.FieldBit8;
                }
                else if (type == FixupType.Bit16)
                {
                    type = FixupType.FieldBit16;
                }
            }

            // --- Create to fixup entry to resolve
            var fixup = new FixupEntry(this, CurrentModule, opLine, type, Output.Segments.Count - 1,
                                       offset ?? fixupOffset,
                                       expression, label, structeBytes);

            // --- Record fixups in every local scope up to the root
            foreach (var scope in CurrentModule.LocalScopes)
            {
                scope.Fixups.Add(fixup);
            }

            // --- Record fixup in every module up to the root
            var currentModule = CurrentModule;

            while (currentModule != null)
            {
                currentModule.Fixups.Add(fixup);
                currentModule = currentModule.ParentModule;
            }
        }
        /// <summary>
        /// Evaluates the specified expression.
        /// </summary>
        /// <param name="opLine">Assembly line with operation</param>
        /// <param name="expr">Expression to evaluate</param>
        /// <returns>
        /// Null, if the expression cannot be evaluated, or evaluation
        /// results an error (e.g. divide by zero)
        /// </returns>
        public ExpressionValue EvalImmediate(SourceLineBase opLine, ExpressionNode expr)
        {
            if (expr == null)
            {
                throw new ArgumentNullException(nameof(expr));
            }
            ExpressionNode.ClearErrors();
            if (!expr.ReadyToEvaluate(this))
            {
                ReportError(Errors.Z0201, opLine, ExpressionNode.SymbolErrors);
                return(ExpressionValue.NonEvaluated);
            }
            var result = expr.Evaluate(this);

            if (result.IsValid)
            {
                return(result);
            }

            ReportError(Errors.Z0200, opLine, expr.EvaluationError);
            return(ExpressionValue.Error);
        }
Exemple #12
0
 /// <summary>
 /// Records fixup information
 /// </summary>
 /// <param name="opLine">The operation line</param>
 /// <param name="type">Fixup type</param>
 /// <param name="expression">Fixup expression</param>
 /// <param name="label">Optional EQU label</param>
 private void RecordFixup(SourceLineBase opLine, FixupType type, ExpressionNode expression, string label = null)
 {
     _output.Fixups.Add(new FixupEntry(opLine, type, _output.Segments.Count - 1,
                                       CurrentSegment.CurrentOffset, expression, label));
 }
Exemple #13
0
        /// <summary>
        /// Reports the specified error
        /// </summary>
        /// <param name="errorCode">Code of error</param>
        /// <param name="line">Source line associated with the error</param>
        /// <param name="parameters">Optiona error message parameters</param>
        private void ReportError(string errorCode, SourceLineBase line, params object[] parameters)
        {
            var sourceItem = _output.SourceFileList[line.FileIndex];

            _output.Errors.Add(new AssemblerErrorInfo(sourceItem, errorCode, line, parameters));
        }
        /// <summary>
        /// Adds a symbol to the current scope
        /// </summary>
        /// <param name="symbol"></param>
        /// <param name="line">Assembly line</param>
        /// <param name="value"></param>
        public void AddSymbol(string symbol, SourceLineBase line, ExpressionValue value)
        {
            Dictionary <string, AssemblySymbolInfo> GetSymbols() =>
            CurrentModule.LocalScopes.Count > 0
                    ? CurrentModule.LocalScopes.Peek().Symbols
                    : CurrentModule.Symbols;

            if (symbol == "__SET_ATTR2")
            {
                var x = 1;
            }
            var currentScopeIsTemporary = CurrentModule.LocalScopes.Count != 0 &&
                                          CurrentModule.LocalScopes.Peek().IsTemporaryScope;
            var symbolIsTemporary = symbol.StartsWith("`");

            var lookup = GetSymbols();

            if (currentScopeIsTemporary)
            {
                if (!symbolIsTemporary)
                {
                    // --- Remove the previous temporary scope
                    var tempScope = CurrentModule.LocalScopes.Peek();
                    FixupSymbols(tempScope.Fixups, tempScope.Symbols, false);
                    CurrentModule.LocalScopes.Pop();

                    lookup = GetSymbols();
                }
            }
            else
            {
                // --- Create a new temporary scope
                CurrentModule.LocalScopes.Push(new SymbolScope {
                    IsTemporaryScope = true
                });
                if (symbolIsTemporary)
                {
                    // --- Temporary symbol should go into the new temporary scope
                    lookup = GetSymbols();
                }
            }

            if (CurrentModule.LocalScopes.Count > 0)
            {
                // --- We are in a local scope, get the next non-temporary scope
                var localScopes = CurrentModule.LocalScopes;
                var scope       = localScopes.Peek();
                if (scope.IsTemporaryScope)
                {
                    var tmpScope = localScopes.Pop();
                    scope = localScopes.Count > 0 ? localScopes.Peek() : null;
                    localScopes.Push(tmpScope);
                }

                if (scope?.LocalSymbolBookings.Count > 0)
                {
                    // --- We already booked local symbols
                    if (!scope.LocalSymbolBookings.Contains(symbol))
                    {
                        lookup = CurrentModule.Symbols;
                    }
                }
                else
                {
                    if (_options.ProcExplicitLocalsOnly)
                    {
                        lookup = CurrentModule.Symbols;
                    }
                }
            }

            // --- Check for already defined symbols
            if (lookup.TryGetValue(symbol, out var symbolInfo) && symbolInfo.Type == SymbolType.Label)
            {
                ReportError(Errors.Z0040, line, symbol);
                return;
            }

            lookup.Add(symbol, AssemblySymbolInfo.CreateLabel(symbol, value));
        }
 private void AddSpan(TokenType type, int line, int startIndex, SourceLineBase asmLine, TextSpan span)
 {
     AddSpan(type, line, startIndex + span.Start - asmLine.FirstPosition + asmLine.FirstColumn, span.End - span.Start);
 }