/// <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); }
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; }
/// <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; }
/// <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); }
/// <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; }
/// <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); }
/// <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); }
/// <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)); }
/// <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); }