From 399fc573048ce553418a311aee4ea1cf53385750 Mon Sep 17 00:00:00 2001 From: Andrey Eliseev Date: Sun, 25 Jan 2026 17:08:34 +0700 Subject: [PATCH 01/42] [cocas] Add assembly syntax for weak and file-local labels --- cocas/assembler/ast_builder.py | 38 +- cocas/assembler/ast_nodes.py | 5 +- cocas/assembler/code_block.py | 12 +- cocas/assembler/generated/AsmLexer.py | 324 ++--- cocas/assembler/generated/AsmParser.py | 1239 ++++++++++------- cocas/assembler/generated/AsmParserVisitor.py | 37 +- cocas/assembler/generated/MacroLexer.py | 99 +- cocas/assembler/generated/MacroParser.py | 4 +- cocas/assembler/generated/MacroVisitor.py | 2 +- cocas/assembler/grammar/AsmLexer.g4 | 5 +- cocas/assembler/grammar/AsmParser.g4 | 19 +- cocas/assembler/grammar/Macro.g4 | 2 +- cocas/assembler/object_generator.py | 4 +- .../object_file/generated/ObjectFileLexer.py | 4 +- .../object_file/generated/ObjectFileParser.py | 4 +- .../generated/ObjectFileParserVisitor.py | 2 +- cocas/object_module/__init__.py | 1 + cocas/object_module/linkage.py | 6 + 18 files changed, 1075 insertions(+), 732 deletions(-) create mode 100644 cocas/object_module/linkage.py diff --git a/cocas/assembler/ast_builder.py b/cocas/assembler/ast_builder.py index b41850be..e1b10cb9 100644 --- a/cocas/assembler/ast_builder.py +++ b/cocas/assembler/ast_builder.py @@ -5,7 +5,7 @@ from antlr4 import CommonTokenStream, InputStream -from cocas.object_module import CodeLocation +from cocas.object_module import CodeLocation, Linkage from .ast_nodes import ( AbsoluteSectionNode, @@ -66,7 +66,7 @@ def visitProgram(self, ctx: AsmParser.ProgramContext) -> ProgramNode: ret.top_instructions.extend(top) return ret - def visitTop_line(self, ctx: AsmParser.Top_lineContext) -> tuple[list[LabelNode], list[InstructionNode]]: + def visitTop_line(self, ctx: AsmParser.Top_lineContext) -> tuple[list[LabelDeclarationNode], list[InstructionNode]]: shared_externals = [] top_instructions = [] for child in ctx.children: @@ -89,7 +89,7 @@ def visitTop_line(self, ctx: AsmParser.Top_lineContext) -> tuple[list[LabelNode] labels = self.visitStandaloneLabels(child) for i in labels: self.check_label_is_ext(i) - shared_externals.append(i.label) + shared_externals.append(i) return shared_externals, top_instructions @staticmethod @@ -249,18 +249,42 @@ def visitAddr_expr(self, ctx: AsmParser.Addr_exprContext): add_terms.append(term) return RelocatableExpressionNode(None, add_terms, sub_terms, const_term) + def visitLocalLabelSuffix(self, ctx) -> Linkage: + return None + + def visitGlobalLabelSuffix(self, ctx) -> Linkage: + return Linkage.GLOBAL + + def visitFileLabelSuffix(self, ctx) -> Linkage: + return Linkage.FILE_LOCAL + + def visitWeakLabelSuffix(self, ctx) -> Linkage: + return Linkage.WEAK_GLOBAL + + def visitGlobalExtType(self, ctx) -> Linkage: + return Linkage.GLOBAL + + def visitFileExtType(self, ctx) -> Linkage: + return Linkage.FILE_LOCAL + + def visitWeakExtType(self, ctx) -> Linkage: + return Linkage.WEAK_GLOBAL + def visitStandaloneLabels(self, ctx: AsmParser.StandaloneLabelsContext) -> list[LabelDeclarationNode]: label_decl = self.visitLabels_declaration(ctx.labels_declaration()) for i in label_decl: - i.external = ctx.Ext() is not None - if i.entry and i.external: + if ctx.ext_type() is None: + continue + if i.linkage: raise AssemblerException(AssemblerExceptionTag.ASM, self.source_path, ctx.start.line - self.line_offset, f'Label {i.label.name} cannot be both external and entry') + i.linkage = self.visit(ctx.ext_type()) + i.external = True return label_decl def visitLabels_declaration(self, ctx: AsmParser.Labels_declarationContext) -> list[LabelDeclarationNode]: - is_entry = ctx.ANGLE_BRACKET() is not None - return [LabelDeclarationNode(i, is_entry, False) for i in self.visitLabels(ctx.labels())] + linkage = self.visit(ctx.label_suffix()) + return [LabelDeclarationNode(i, linkage, False) for i in self.visitLabels(ctx.labels())] def visitLabels(self, ctx: AsmParser.LabelsContext): return [self.visitLabel(i) for i in ctx.label()] diff --git a/cocas/assembler/ast_nodes.py b/cocas/assembler/ast_nodes.py index 3850e0a2..25cc302d 100644 --- a/cocas/assembler/ast_nodes.py +++ b/cocas/assembler/ast_nodes.py @@ -2,6 +2,7 @@ from typing import Optional from cocas.object_module import CodeLocation +from cocas.object_module import Linkage @dataclass @@ -48,7 +49,7 @@ class RelocatableExpressionNode(LocatableNode): @dataclass class LabelDeclarationNode(LocatableNode): label: LabelNode - entry: bool + linkage: Optional[Linkage] external: bool @@ -125,5 +126,5 @@ class ProgramNode(Node): template_sections: list[TemplateSectionNode] relocatable_sections: list[RelocatableSectionNode] absolute_sections: list[AbsoluteSectionNode] - shared_externals: list[LabelNode] = field(default_factory=list) + shared_externals: list[LabelDeclarationNode] = field(default_factory=list) top_instructions: list[InstructionNode] = field(default_factory=list) diff --git a/cocas/assembler/code_block.py b/cocas/assembler/code_block.py index 91984b19..293629c0 100644 --- a/cocas/assembler/code_block.py +++ b/cocas/assembler/code_block.py @@ -1,7 +1,7 @@ from dataclasses import dataclass from typing import Any, Callable, Type -from cocas.object_module import CodeLocation, ObjectSectionRecord +from cocas.object_module import CodeLocation, ObjectSectionRecord, Linkage from .ast_nodes import ( AbsoluteSectionNode, @@ -30,8 +30,8 @@ def __init__(self, address: int, lines: list, target_instructions: TargetInstruc self.loop_stack: list = [] self.segments: list[ICodeSegment] = [] self.labels: dict[str, int] = dict() - self.ents: set[str] = set() - self.exts: set[str] = set() + self.ents: dict[str, Linkage] = dict() + self.exts: dict[str, Linkage] = dict() self.code_locations: dict[int, CodeLocation] = dict() temp_storage = dict() # variable to save information for future lines self.assemble_lines(lines, temp_storage) @@ -76,11 +76,11 @@ def assemble_label_declaration(self, line: LabelDeclarationNode, __): f'Duplicate label "{label_name}" declaration') if line.external: - self.exts.add(label_name) + self.exts[label_name] = line.linkage else: self.append_label(label_name) - if line.entry: - self.ents.add(label_name) + if line.linkage: + self.ents[label_name] = line.linkage def assemble_instruction(self, line: InstructionNode, temp_storage): for seg in self.target_instructions.assemble_instruction(line, temp_storage): diff --git a/cocas/assembler/generated/AsmLexer.py b/cocas/assembler/generated/AsmLexer.py index ab7b4e8a..f97cd462 100644 --- a/cocas/assembler/generated/AsmLexer.py +++ b/cocas/assembler/generated/AsmLexer.py @@ -1,4 +1,4 @@ -# Generated from assembler/grammar/AsmLexer.g4 by ANTLR 4.13.1 +# Generated from assembler/grammar/AsmLexer.g4 by ANTLR 4.13.2 from antlr4 import * from io import StringIO import sys @@ -10,117 +10,123 @@ def serializedATN(): return [ - 4,0,41,303,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5, + 4,0,44,323,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5, 2,6,7,6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2, 13,7,13,2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7, 19,2,20,7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,2, 26,7,26,2,27,7,27,2,28,7,28,2,29,7,29,2,30,7,30,2,31,7,31,2,32,7, 32,2,33,7,33,2,34,7,34,2,35,7,35,2,36,7,36,2,37,7,37,2,38,7,38,2, - 39,7,39,2,40,7,40,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1, - 1,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,3,1,3,1,3,1,4,1,4,1,4,1, - 4,1,4,1,5,1,5,1,5,1,5,1,6,1,6,1,6,1,6,1,7,1,7,1,7,1,8,1,8,1,8,1, - 9,1,9,1,9,1,10,1,10,1,10,1,10,1,10,1,10,1,11,1,11,1,11,1,11,1,11, - 1,11,1,12,1,12,1,12,1,12,1,12,1,12,1,13,1,13,1,13,1,13,1,13,1,14, - 1,14,1,14,1,14,1,14,1,14,1,14,1,15,1,15,1,15,1,15,1,15,1,15,1,16, - 1,16,1,16,1,16,1,16,1,17,1,17,1,17,1,17,1,17,1,17,1,18,1,18,1,19, - 1,19,1,20,1,20,1,21,1,21,1,22,1,22,1,23,1,23,1,24,1,24,1,25,1,25, - 1,26,1,26,1,27,1,27,1,27,1,28,1,28,1,28,1,29,1,29,5,29,203,8,29, - 10,29,12,29,206,9,29,1,30,1,30,5,30,210,8,30,10,30,12,30,213,9,30, - 1,30,1,30,5,30,217,8,30,10,30,12,30,220,9,30,1,30,1,30,1,31,4,31, - 225,8,31,11,31,12,31,226,1,32,1,32,1,32,1,32,4,32,233,8,32,11,32, - 12,32,234,1,33,1,33,1,33,1,33,4,33,241,8,33,11,33,12,33,242,1,34, - 1,34,4,34,247,8,34,11,34,12,34,248,1,34,1,34,5,34,253,8,34,10,34, - 12,34,256,9,34,1,34,1,34,1,35,1,35,4,35,262,8,35,11,35,12,35,263, - 1,35,1,35,5,35,268,8,35,10,35,12,35,271,9,35,1,35,1,35,1,36,3,36, - 276,8,36,1,36,1,36,1,37,1,37,5,37,282,8,37,10,37,12,37,285,9,37, - 1,37,1,37,1,38,1,38,1,38,1,38,1,39,1,39,1,39,1,39,1,39,4,39,298, - 8,39,11,39,12,39,299,1,40,1,40,0,0,41,1,1,3,2,5,3,7,4,9,5,11,6,13, - 7,15,8,17,9,19,10,21,11,23,12,25,13,27,14,29,15,31,16,33,17,35,18, - 37,19,39,20,41,21,43,22,45,23,47,24,49,25,51,26,53,27,55,28,57,29, - 59,30,61,31,63,32,65,33,67,34,69,35,71,36,73,37,75,38,77,39,79,40, - 81,41,1,0,12,3,0,65,90,95,95,97,122,4,0,48,57,65,90,95,95,97,122, - 5,0,46,46,48,57,65,90,95,95,97,122,1,0,48,57,1,0,48,49,3,0,48,57, - 65,70,97,102,2,0,34,34,92,92,2,0,39,39,92,92,1,0,10,10,2,0,9,9,32, - 32,5,0,43,43,47,57,61,61,65,90,97,122,1,0,0,65534,317,0,1,1,0,0, - 0,0,3,1,0,0,0,0,5,1,0,0,0,0,7,1,0,0,0,0,9,1,0,0,0,0,11,1,0,0,0,0, - 13,1,0,0,0,0,15,1,0,0,0,0,17,1,0,0,0,0,19,1,0,0,0,0,21,1,0,0,0,0, - 23,1,0,0,0,0,25,1,0,0,0,0,27,1,0,0,0,0,29,1,0,0,0,0,31,1,0,0,0,0, - 33,1,0,0,0,0,35,1,0,0,0,0,37,1,0,0,0,0,39,1,0,0,0,0,41,1,0,0,0,0, - 43,1,0,0,0,0,45,1,0,0,0,0,47,1,0,0,0,0,49,1,0,0,0,0,51,1,0,0,0,0, - 53,1,0,0,0,0,55,1,0,0,0,0,57,1,0,0,0,0,59,1,0,0,0,0,61,1,0,0,0,0, - 63,1,0,0,0,0,65,1,0,0,0,0,67,1,0,0,0,0,69,1,0,0,0,0,71,1,0,0,0,0, - 73,1,0,0,0,0,75,1,0,0,0,0,77,1,0,0,0,0,79,1,0,0,0,0,81,1,0,0,0,1, - 83,1,0,0,0,3,89,1,0,0,0,5,95,1,0,0,0,7,104,1,0,0,0,9,107,1,0,0,0, - 11,112,1,0,0,0,13,116,1,0,0,0,15,120,1,0,0,0,17,123,1,0,0,0,19,126, - 1,0,0,0,21,129,1,0,0,0,23,135,1,0,0,0,25,141,1,0,0,0,27,147,1,0, - 0,0,29,152,1,0,0,0,31,159,1,0,0,0,33,165,1,0,0,0,35,170,1,0,0,0, - 37,176,1,0,0,0,39,178,1,0,0,0,41,180,1,0,0,0,43,182,1,0,0,0,45,184, - 1,0,0,0,47,186,1,0,0,0,49,188,1,0,0,0,51,190,1,0,0,0,53,192,1,0, - 0,0,55,194,1,0,0,0,57,197,1,0,0,0,59,200,1,0,0,0,61,207,1,0,0,0, - 63,224,1,0,0,0,65,228,1,0,0,0,67,236,1,0,0,0,69,244,1,0,0,0,71,259, - 1,0,0,0,73,275,1,0,0,0,75,279,1,0,0,0,77,288,1,0,0,0,79,292,1,0, - 0,0,81,301,1,0,0,0,83,84,5,97,0,0,84,85,5,115,0,0,85,86,5,101,0, - 0,86,87,5,99,0,0,87,88,5,116,0,0,88,2,1,0,0,0,89,90,5,98,0,0,90, - 91,5,114,0,0,91,92,5,101,0,0,92,93,5,97,0,0,93,94,5,107,0,0,94,4, - 1,0,0,0,95,96,5,99,0,0,96,97,5,111,0,0,97,98,5,110,0,0,98,99,5,116, - 0,0,99,100,5,105,0,0,100,101,5,110,0,0,101,102,5,117,0,0,102,103, - 5,101,0,0,103,6,1,0,0,0,104,105,5,100,0,0,105,106,5,111,0,0,106, - 8,1,0,0,0,107,108,5,101,0,0,108,109,5,108,0,0,109,110,5,115,0,0, - 110,111,5,101,0,0,111,10,1,0,0,0,112,113,5,101,0,0,113,114,5,110, - 0,0,114,115,5,100,0,0,115,12,1,0,0,0,116,117,5,101,0,0,117,118,5, - 120,0,0,118,119,5,116,0,0,119,14,1,0,0,0,120,121,5,102,0,0,121,122, - 5,105,0,0,122,16,1,0,0,0,123,124,5,105,0,0,124,125,5,102,0,0,125, - 18,1,0,0,0,126,127,5,105,0,0,127,128,5,115,0,0,128,20,1,0,0,0,129, - 130,5,109,0,0,130,131,5,97,0,0,131,132,5,99,0,0,132,133,5,114,0, - 0,133,134,5,111,0,0,134,22,1,0,0,0,135,136,5,114,0,0,136,137,5,115, - 0,0,137,138,5,101,0,0,138,139,5,99,0,0,139,140,5,116,0,0,140,24, - 1,0,0,0,141,142,5,115,0,0,142,143,5,116,0,0,143,144,5,97,0,0,144, - 145,5,121,0,0,145,146,5,115,0,0,146,26,1,0,0,0,147,148,5,116,0,0, - 148,149,5,104,0,0,149,150,5,101,0,0,150,151,5,110,0,0,151,28,1,0, - 0,0,152,153,5,116,0,0,153,154,5,112,0,0,154,155,5,108,0,0,155,156, - 5,97,0,0,156,157,5,116,0,0,157,158,5,101,0,0,158,30,1,0,0,0,159, - 160,5,117,0,0,160,161,5,110,0,0,161,162,5,116,0,0,162,163,5,105, - 0,0,163,164,5,108,0,0,164,32,1,0,0,0,165,166,5,119,0,0,166,167,5, - 101,0,0,167,168,5,110,0,0,168,169,5,100,0,0,169,34,1,0,0,0,170,171, - 5,119,0,0,171,172,5,104,0,0,172,173,5,105,0,0,173,174,5,108,0,0, - 174,175,5,101,0,0,175,36,1,0,0,0,176,177,5,46,0,0,177,38,1,0,0,0, - 178,179,5,44,0,0,179,40,1,0,0,0,180,181,5,43,0,0,181,42,1,0,0,0, - 182,183,5,45,0,0,183,44,1,0,0,0,184,185,5,58,0,0,185,46,1,0,0,0, - 186,187,5,42,0,0,187,48,1,0,0,0,188,189,5,62,0,0,189,50,1,0,0,0, - 190,191,5,40,0,0,191,52,1,0,0,0,192,193,5,41,0,0,193,54,1,0,0,0, - 194,195,5,45,0,0,195,196,5,124,0,0,196,56,1,0,0,0,197,198,5,114, - 0,0,198,199,3,63,31,0,199,58,1,0,0,0,200,204,7,0,0,0,201,203,7,1, - 0,0,202,201,1,0,0,0,203,206,1,0,0,0,204,202,1,0,0,0,204,205,1,0, - 0,0,205,60,1,0,0,0,206,204,1,0,0,0,207,211,7,0,0,0,208,210,7,1,0, - 0,209,208,1,0,0,0,210,213,1,0,0,0,211,209,1,0,0,0,211,212,1,0,0, - 0,212,214,1,0,0,0,213,211,1,0,0,0,214,218,3,37,18,0,215,217,7,2, - 0,0,216,215,1,0,0,0,217,220,1,0,0,0,218,216,1,0,0,0,218,219,1,0, - 0,0,219,221,1,0,0,0,220,218,1,0,0,0,221,222,7,1,0,0,222,62,1,0,0, - 0,223,225,7,3,0,0,224,223,1,0,0,0,225,226,1,0,0,0,226,224,1,0,0, - 0,226,227,1,0,0,0,227,64,1,0,0,0,228,229,5,48,0,0,229,230,5,98,0, - 0,230,232,1,0,0,0,231,233,7,4,0,0,232,231,1,0,0,0,233,234,1,0,0, - 0,234,232,1,0,0,0,234,235,1,0,0,0,235,66,1,0,0,0,236,237,5,48,0, - 0,237,238,5,120,0,0,238,240,1,0,0,0,239,241,7,5,0,0,240,239,1,0, - 0,0,241,242,1,0,0,0,242,240,1,0,0,0,242,243,1,0,0,0,243,68,1,0,0, - 0,244,254,5,34,0,0,245,247,8,6,0,0,246,245,1,0,0,0,247,248,1,0,0, - 0,248,246,1,0,0,0,248,249,1,0,0,0,249,253,1,0,0,0,250,251,5,92,0, - 0,251,253,9,0,0,0,252,246,1,0,0,0,252,250,1,0,0,0,253,256,1,0,0, - 0,254,252,1,0,0,0,254,255,1,0,0,0,255,257,1,0,0,0,256,254,1,0,0, - 0,257,258,5,34,0,0,258,70,1,0,0,0,259,269,5,39,0,0,260,262,8,7,0, - 0,261,260,1,0,0,0,262,263,1,0,0,0,263,261,1,0,0,0,263,264,1,0,0, - 0,264,268,1,0,0,0,265,266,5,92,0,0,266,268,9,0,0,0,267,261,1,0,0, - 0,267,265,1,0,0,0,268,271,1,0,0,0,269,267,1,0,0,0,269,270,1,0,0, - 0,270,272,1,0,0,0,271,269,1,0,0,0,272,273,5,39,0,0,273,72,1,0,0, - 0,274,276,5,13,0,0,275,274,1,0,0,0,275,276,1,0,0,0,276,277,1,0,0, - 0,277,278,5,10,0,0,278,74,1,0,0,0,279,283,5,35,0,0,280,282,8,8,0, - 0,281,280,1,0,0,0,282,285,1,0,0,0,283,281,1,0,0,0,283,284,1,0,0, - 0,284,286,1,0,0,0,285,283,1,0,0,0,286,287,6,37,0,0,287,76,1,0,0, - 0,288,289,7,9,0,0,289,290,1,0,0,0,290,291,6,38,0,0,291,78,1,0,0, - 0,292,293,5,102,0,0,293,294,5,112,0,0,294,295,5,45,0,0,295,297,1, - 0,0,0,296,298,7,10,0,0,297,296,1,0,0,0,298,299,1,0,0,0,299,297,1, - 0,0,0,299,300,1,0,0,0,300,80,1,0,0,0,301,302,7,11,0,0,302,82,1,0, - 0,0,16,0,204,211,218,226,234,242,248,252,254,263,267,269,275,283, - 299,1,6,0,0 + 39,7,39,2,40,7,40,2,41,7,41,2,42,7,42,2,43,7,43,1,0,1,0,1,0,1,0, + 1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2, + 1,2,1,3,1,3,1,3,1,4,1,4,1,4,1,4,1,4,1,5,1,5,1,5,1,5,1,6,1,6,1,6, + 1,6,1,7,1,7,1,7,1,7,1,7,1,8,1,8,1,8,1,8,1,8,1,9,1,9,1,9,1,10,1,10, + 1,10,1,11,1,11,1,11,1,12,1,12,1,12,1,12,1,12,1,12,1,13,1,13,1,13, + 1,13,1,13,1,13,1,14,1,14,1,14,1,14,1,14,1,14,1,15,1,15,1,15,1,15, + 1,15,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,17,1,17,1,17,1,17,1,17, + 1,17,1,18,1,18,1,18,1,18,1,18,1,19,1,19,1,19,1,19,1,19,1,19,1,20, + 1,20,1,21,1,21,1,22,1,22,1,23,1,23,1,24,1,24,1,25,1,25,1,26,1,26, + 1,26,1,27,1,27,1,27,1,28,1,28,1,29,1,29,1,30,1,30,1,30,1,31,1,31, + 1,31,1,32,1,32,5,32,223,8,32,10,32,12,32,226,9,32,1,33,1,33,5,33, + 230,8,33,10,33,12,33,233,9,33,1,33,1,33,5,33,237,8,33,10,33,12,33, + 240,9,33,1,33,1,33,1,34,4,34,245,8,34,11,34,12,34,246,1,35,1,35, + 1,35,1,35,4,35,253,8,35,11,35,12,35,254,1,36,1,36,1,36,1,36,4,36, + 261,8,36,11,36,12,36,262,1,37,1,37,4,37,267,8,37,11,37,12,37,268, + 1,37,1,37,5,37,273,8,37,10,37,12,37,276,9,37,1,37,1,37,1,38,1,38, + 4,38,282,8,38,11,38,12,38,283,1,38,1,38,5,38,288,8,38,10,38,12,38, + 291,9,38,1,38,1,38,1,39,3,39,296,8,39,1,39,1,39,1,40,1,40,5,40,302, + 8,40,10,40,12,40,305,9,40,1,40,1,40,1,41,1,41,1,41,1,41,1,42,1,42, + 1,42,1,42,1,42,4,42,318,8,42,11,42,12,42,319,1,43,1,43,0,0,44,1, + 1,3,2,5,3,7,4,9,5,11,6,13,7,15,8,17,9,19,10,21,11,23,12,25,13,27, + 14,29,15,31,16,33,17,35,18,37,19,39,20,41,21,43,22,45,23,47,24,49, + 25,51,26,53,27,55,28,57,29,59,30,61,31,63,32,65,33,67,34,69,35,71, + 36,73,37,75,38,77,39,79,40,81,41,83,42,85,43,87,44,1,0,12,3,0,65, + 90,95,95,97,122,4,0,48,57,65,90,95,95,97,122,5,0,46,46,48,57,65, + 90,95,95,97,122,1,0,48,57,1,0,48,49,3,0,48,57,65,70,97,102,2,0,34, + 34,92,92,2,0,39,39,92,92,1,0,10,10,2,0,9,9,32,32,5,0,43,43,47,57, + 61,61,65,90,97,122,1,0,0,65534,337,0,1,1,0,0,0,0,3,1,0,0,0,0,5,1, + 0,0,0,0,7,1,0,0,0,0,9,1,0,0,0,0,11,1,0,0,0,0,13,1,0,0,0,0,15,1,0, + 0,0,0,17,1,0,0,0,0,19,1,0,0,0,0,21,1,0,0,0,0,23,1,0,0,0,0,25,1,0, + 0,0,0,27,1,0,0,0,0,29,1,0,0,0,0,31,1,0,0,0,0,33,1,0,0,0,0,35,1,0, + 0,0,0,37,1,0,0,0,0,39,1,0,0,0,0,41,1,0,0,0,0,43,1,0,0,0,0,45,1,0, + 0,0,0,47,1,0,0,0,0,49,1,0,0,0,0,51,1,0,0,0,0,53,1,0,0,0,0,55,1,0, + 0,0,0,57,1,0,0,0,0,59,1,0,0,0,0,61,1,0,0,0,0,63,1,0,0,0,0,65,1,0, + 0,0,0,67,1,0,0,0,0,69,1,0,0,0,0,71,1,0,0,0,0,73,1,0,0,0,0,75,1,0, + 0,0,0,77,1,0,0,0,0,79,1,0,0,0,0,81,1,0,0,0,0,83,1,0,0,0,0,85,1,0, + 0,0,0,87,1,0,0,0,1,89,1,0,0,0,3,95,1,0,0,0,5,101,1,0,0,0,7,110,1, + 0,0,0,9,113,1,0,0,0,11,118,1,0,0,0,13,122,1,0,0,0,15,126,1,0,0,0, + 17,131,1,0,0,0,19,136,1,0,0,0,21,139,1,0,0,0,23,142,1,0,0,0,25,145, + 1,0,0,0,27,151,1,0,0,0,29,157,1,0,0,0,31,163,1,0,0,0,33,168,1,0, + 0,0,35,175,1,0,0,0,37,181,1,0,0,0,39,186,1,0,0,0,41,192,1,0,0,0, + 43,194,1,0,0,0,45,196,1,0,0,0,47,198,1,0,0,0,49,200,1,0,0,0,51,202, + 1,0,0,0,53,204,1,0,0,0,55,207,1,0,0,0,57,210,1,0,0,0,59,212,1,0, + 0,0,61,214,1,0,0,0,63,217,1,0,0,0,65,220,1,0,0,0,67,227,1,0,0,0, + 69,244,1,0,0,0,71,248,1,0,0,0,73,256,1,0,0,0,75,264,1,0,0,0,77,279, + 1,0,0,0,79,295,1,0,0,0,81,299,1,0,0,0,83,308,1,0,0,0,85,312,1,0, + 0,0,87,321,1,0,0,0,89,90,5,97,0,0,90,91,5,115,0,0,91,92,5,101,0, + 0,92,93,5,99,0,0,93,94,5,116,0,0,94,2,1,0,0,0,95,96,5,98,0,0,96, + 97,5,114,0,0,97,98,5,101,0,0,98,99,5,97,0,0,99,100,5,107,0,0,100, + 4,1,0,0,0,101,102,5,99,0,0,102,103,5,111,0,0,103,104,5,110,0,0,104, + 105,5,116,0,0,105,106,5,105,0,0,106,107,5,110,0,0,107,108,5,117, + 0,0,108,109,5,101,0,0,109,6,1,0,0,0,110,111,5,100,0,0,111,112,5, + 111,0,0,112,8,1,0,0,0,113,114,5,101,0,0,114,115,5,108,0,0,115,116, + 5,115,0,0,116,117,5,101,0,0,117,10,1,0,0,0,118,119,5,101,0,0,119, + 120,5,110,0,0,120,121,5,100,0,0,121,12,1,0,0,0,122,123,5,101,0,0, + 123,124,5,120,0,0,124,125,5,116,0,0,125,14,1,0,0,0,126,127,5,102, + 0,0,127,128,5,105,0,0,128,129,5,108,0,0,129,130,5,101,0,0,130,16, + 1,0,0,0,131,132,5,119,0,0,132,133,5,101,0,0,133,134,5,97,0,0,134, + 135,5,107,0,0,135,18,1,0,0,0,136,137,5,102,0,0,137,138,5,105,0,0, + 138,20,1,0,0,0,139,140,5,105,0,0,140,141,5,102,0,0,141,22,1,0,0, + 0,142,143,5,105,0,0,143,144,5,115,0,0,144,24,1,0,0,0,145,146,5,109, + 0,0,146,147,5,97,0,0,147,148,5,99,0,0,148,149,5,114,0,0,149,150, + 5,111,0,0,150,26,1,0,0,0,151,152,5,114,0,0,152,153,5,115,0,0,153, + 154,5,101,0,0,154,155,5,99,0,0,155,156,5,116,0,0,156,28,1,0,0,0, + 157,158,5,115,0,0,158,159,5,116,0,0,159,160,5,97,0,0,160,161,5,121, + 0,0,161,162,5,115,0,0,162,30,1,0,0,0,163,164,5,116,0,0,164,165,5, + 104,0,0,165,166,5,101,0,0,166,167,5,110,0,0,167,32,1,0,0,0,168,169, + 5,116,0,0,169,170,5,112,0,0,170,171,5,108,0,0,171,172,5,97,0,0,172, + 173,5,116,0,0,173,174,5,101,0,0,174,34,1,0,0,0,175,176,5,117,0,0, + 176,177,5,110,0,0,177,178,5,116,0,0,178,179,5,105,0,0,179,180,5, + 108,0,0,180,36,1,0,0,0,181,182,5,119,0,0,182,183,5,101,0,0,183,184, + 5,110,0,0,184,185,5,100,0,0,185,38,1,0,0,0,186,187,5,119,0,0,187, + 188,5,104,0,0,188,189,5,105,0,0,189,190,5,108,0,0,190,191,5,101, + 0,0,191,40,1,0,0,0,192,193,5,46,0,0,193,42,1,0,0,0,194,195,5,44, + 0,0,195,44,1,0,0,0,196,197,5,43,0,0,197,46,1,0,0,0,198,199,5,45, + 0,0,199,48,1,0,0,0,200,201,5,58,0,0,201,50,1,0,0,0,202,203,5,62, + 0,0,203,52,1,0,0,0,204,205,5,58,0,0,205,206,5,62,0,0,206,54,1,0, + 0,0,207,208,5,126,0,0,208,209,5,62,0,0,209,56,1,0,0,0,210,211,5, + 40,0,0,211,58,1,0,0,0,212,213,5,41,0,0,213,60,1,0,0,0,214,215,5, + 45,0,0,215,216,5,124,0,0,216,62,1,0,0,0,217,218,5,114,0,0,218,219, + 3,69,34,0,219,64,1,0,0,0,220,224,7,0,0,0,221,223,7,1,0,0,222,221, + 1,0,0,0,223,226,1,0,0,0,224,222,1,0,0,0,224,225,1,0,0,0,225,66,1, + 0,0,0,226,224,1,0,0,0,227,231,7,0,0,0,228,230,7,1,0,0,229,228,1, + 0,0,0,230,233,1,0,0,0,231,229,1,0,0,0,231,232,1,0,0,0,232,234,1, + 0,0,0,233,231,1,0,0,0,234,238,3,41,20,0,235,237,7,2,0,0,236,235, + 1,0,0,0,237,240,1,0,0,0,238,236,1,0,0,0,238,239,1,0,0,0,239,241, + 1,0,0,0,240,238,1,0,0,0,241,242,7,1,0,0,242,68,1,0,0,0,243,245,7, + 3,0,0,244,243,1,0,0,0,245,246,1,0,0,0,246,244,1,0,0,0,246,247,1, + 0,0,0,247,70,1,0,0,0,248,249,5,48,0,0,249,250,5,98,0,0,250,252,1, + 0,0,0,251,253,7,4,0,0,252,251,1,0,0,0,253,254,1,0,0,0,254,252,1, + 0,0,0,254,255,1,0,0,0,255,72,1,0,0,0,256,257,5,48,0,0,257,258,5, + 120,0,0,258,260,1,0,0,0,259,261,7,5,0,0,260,259,1,0,0,0,261,262, + 1,0,0,0,262,260,1,0,0,0,262,263,1,0,0,0,263,74,1,0,0,0,264,274,5, + 34,0,0,265,267,8,6,0,0,266,265,1,0,0,0,267,268,1,0,0,0,268,266,1, + 0,0,0,268,269,1,0,0,0,269,273,1,0,0,0,270,271,5,92,0,0,271,273,9, + 0,0,0,272,266,1,0,0,0,272,270,1,0,0,0,273,276,1,0,0,0,274,272,1, + 0,0,0,274,275,1,0,0,0,275,277,1,0,0,0,276,274,1,0,0,0,277,278,5, + 34,0,0,278,76,1,0,0,0,279,289,5,39,0,0,280,282,8,7,0,0,281,280,1, + 0,0,0,282,283,1,0,0,0,283,281,1,0,0,0,283,284,1,0,0,0,284,288,1, + 0,0,0,285,286,5,92,0,0,286,288,9,0,0,0,287,281,1,0,0,0,287,285,1, + 0,0,0,288,291,1,0,0,0,289,287,1,0,0,0,289,290,1,0,0,0,290,292,1, + 0,0,0,291,289,1,0,0,0,292,293,5,39,0,0,293,78,1,0,0,0,294,296,5, + 13,0,0,295,294,1,0,0,0,295,296,1,0,0,0,296,297,1,0,0,0,297,298,5, + 10,0,0,298,80,1,0,0,0,299,303,5,35,0,0,300,302,8,8,0,0,301,300,1, + 0,0,0,302,305,1,0,0,0,303,301,1,0,0,0,303,304,1,0,0,0,304,306,1, + 0,0,0,305,303,1,0,0,0,306,307,6,40,0,0,307,82,1,0,0,0,308,309,7, + 9,0,0,309,310,1,0,0,0,310,311,6,41,0,0,311,84,1,0,0,0,312,313,5, + 102,0,0,313,314,5,112,0,0,314,315,5,45,0,0,315,317,1,0,0,0,316,318, + 7,10,0,0,317,316,1,0,0,0,318,319,1,0,0,0,319,317,1,0,0,0,319,320, + 1,0,0,0,320,86,1,0,0,0,321,322,7,11,0,0,322,88,1,0,0,0,16,0,224, + 231,238,246,254,262,268,272,274,283,287,289,295,303,319,1,6,0,0 ] class AsmLexer(Lexer): @@ -136,40 +142,43 @@ class AsmLexer(Lexer): Else = 5 End = 6 Ext = 7 - Fi = 8 - If = 9 - Is = 10 - Macro = 11 - Rsect = 12 - Stays = 13 - Then = 14 - Tplate = 15 - Until = 16 - Wend = 17 - While = 18 - DOT = 19 - COMMA = 20 - PLUS = 21 - MINUS = 22 - COLON = 23 - ASTERISK = 24 - ANGLE_BRACKET = 25 - OPEN_PAREN = 26 - CLOSE_PAREN = 27 - LINE_MARK_MARKER = 28 - REGISTER = 29 - WORD = 30 - WORD_WITH_DOTS = 31 - DECIMAL_NUMBER = 32 - BINARY_NUMBER = 33 - HEX_NUMBER = 34 - STRING = 35 - CHAR = 36 - NEWLINE = 37 - COMMENT = 38 - WS = 39 - BASE64 = 40 - UNEXPECTED_TOKEN = 41 + File = 8 + Weak = 9 + Fi = 10 + If = 11 + Is = 12 + Macro = 13 + Rsect = 14 + Stays = 15 + Then = 16 + Tplate = 17 + Until = 18 + Wend = 19 + While = 20 + DOT = 21 + COMMA = 22 + PLUS = 23 + MINUS = 24 + COLON = 25 + ANGLE_BRACKET = 26 + COLON_ANGLE = 27 + TILDE_ANGLE = 28 + OPEN_PAREN = 29 + CLOSE_PAREN = 30 + LINE_MARK_MARKER = 31 + REGISTER = 32 + WORD = 33 + WORD_WITH_DOTS = 34 + DECIMAL_NUMBER = 35 + BINARY_NUMBER = 36 + HEX_NUMBER = 37 + STRING = 38 + CHAR = 39 + NEWLINE = 40 + COMMENT = 41 + WS = 42 + BASE64 = 43 + UNEXPECTED_TOKEN = 44 channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ] @@ -177,32 +186,35 @@ class AsmLexer(Lexer): literalNames = [ "", "'asect'", "'break'", "'continue'", "'do'", "'else'", "'end'", - "'ext'", "'fi'", "'if'", "'is'", "'macro'", "'rsect'", "'stays'", - "'then'", "'tplate'", "'until'", "'wend'", "'while'", "'.'", - "','", "'+'", "'-'", "':'", "'*'", "'>'", "'('", "')'", "'-|'" ] + "'ext'", "'file'", "'weak'", "'fi'", "'if'", "'is'", "'macro'", + "'rsect'", "'stays'", "'then'", "'tplate'", "'until'", "'wend'", + "'while'", "'.'", "','", "'+'", "'-'", "':'", "'>'", "':>'", + "'~>'", "'('", "')'", "'-|'" ] symbolicNames = [ "", - "Asect", "Break", "Continue", "Do", "Else", "End", "Ext", "Fi", - "If", "Is", "Macro", "Rsect", "Stays", "Then", "Tplate", "Until", - "Wend", "While", "DOT", "COMMA", "PLUS", "MINUS", "COLON", "ASTERISK", - "ANGLE_BRACKET", "OPEN_PAREN", "CLOSE_PAREN", "LINE_MARK_MARKER", - "REGISTER", "WORD", "WORD_WITH_DOTS", "DECIMAL_NUMBER", "BINARY_NUMBER", + "Asect", "Break", "Continue", "Do", "Else", "End", "Ext", "File", + "Weak", "Fi", "If", "Is", "Macro", "Rsect", "Stays", "Then", + "Tplate", "Until", "Wend", "While", "DOT", "COMMA", "PLUS", + "MINUS", "COLON", "ANGLE_BRACKET", "COLON_ANGLE", "TILDE_ANGLE", + "OPEN_PAREN", "CLOSE_PAREN", "LINE_MARK_MARKER", "REGISTER", + "WORD", "WORD_WITH_DOTS", "DECIMAL_NUMBER", "BINARY_NUMBER", "HEX_NUMBER", "STRING", "CHAR", "NEWLINE", "COMMENT", "WS", "BASE64", "UNEXPECTED_TOKEN" ] ruleNames = [ "Asect", "Break", "Continue", "Do", "Else", "End", "Ext", - "Fi", "If", "Is", "Macro", "Rsect", "Stays", "Then", "Tplate", - "Until", "Wend", "While", "DOT", "COMMA", "PLUS", "MINUS", - "COLON", "ASTERISK", "ANGLE_BRACKET", "OPEN_PAREN", "CLOSE_PAREN", - "LINE_MARK_MARKER", "REGISTER", "WORD", "WORD_WITH_DOTS", - "DECIMAL_NUMBER", "BINARY_NUMBER", "HEX_NUMBER", "STRING", - "CHAR", "NEWLINE", "COMMENT", "WS", "BASE64", "UNEXPECTED_TOKEN" ] + "File", "Weak", "Fi", "If", "Is", "Macro", "Rsect", "Stays", + "Then", "Tplate", "Until", "Wend", "While", "DOT", "COMMA", + "PLUS", "MINUS", "COLON", "ANGLE_BRACKET", "COLON_ANGLE", + "TILDE_ANGLE", "OPEN_PAREN", "CLOSE_PAREN", "LINE_MARK_MARKER", + "REGISTER", "WORD", "WORD_WITH_DOTS", "DECIMAL_NUMBER", + "BINARY_NUMBER", "HEX_NUMBER", "STRING", "CHAR", "NEWLINE", + "COMMENT", "WS", "BASE64", "UNEXPECTED_TOKEN" ] grammarFileName = "AsmLexer.g4" def __init__(self, input=None, output:TextIO = sys.stdout): super().__init__(input, output) - self.checkVersion("4.13.1") + self.checkVersion("4.13.2") self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache()) self._actions = None self._predicates = None diff --git a/cocas/assembler/generated/AsmParser.py b/cocas/assembler/generated/AsmParser.py index af2fcbcb..a5e57fe6 100644 --- a/cocas/assembler/generated/AsmParser.py +++ b/cocas/assembler/generated/AsmParser.py @@ -1,4 +1,4 @@ -# Generated from assembler/grammar/AsmParser.g4 by ANTLR 4.13.1 +# Generated from assembler/grammar/AsmParser.g4 by ANTLR 4.13.2 # encoding: utf-8 from antlr4 import * from io import StringIO @@ -13,147 +13,153 @@ def serializedATN(): return [ - 4,1,41,398,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, + 4,1,44,413,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, 6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2,13,7,13, 2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7,19,2,20, 7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,2,26,7,26, 2,27,7,27,2,28,7,28,2,29,7,29,2,30,7,30,2,31,7,31,2,32,7,32,2,33, 7,33,2,34,7,34,2,35,7,35,2,36,7,36,2,37,7,37,2,38,7,38,2,39,7,39, - 2,40,7,40,2,41,7,41,1,0,5,0,86,8,0,10,0,12,0,89,9,0,1,0,5,0,92,8, - 0,10,0,12,0,95,9,0,1,0,5,0,98,8,0,10,0,12,0,101,9,0,1,0,1,0,1,1, - 5,1,106,8,1,10,1,12,1,109,9,1,1,1,4,1,112,8,1,11,1,12,1,113,1,1, - 5,1,117,8,1,10,1,12,1,120,9,1,1,1,5,1,123,8,1,10,1,12,1,126,9,1, - 1,1,1,1,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,3,2,139,8,2,1,3,1,3, - 1,3,4,3,144,8,3,11,3,12,3,145,1,4,1,4,1,4,4,4,151,8,4,11,4,12,4, - 152,1,5,1,5,1,5,4,5,158,8,5,11,5,12,5,159,1,6,1,6,1,7,1,7,1,7,1, - 7,1,7,1,7,1,7,5,7,171,8,7,10,7,12,7,174,9,7,1,8,1,8,1,8,1,8,3,8, - 180,8,8,1,8,4,8,183,8,8,11,8,12,8,184,1,8,1,8,1,8,1,8,1,8,1,8,1, - 9,1,9,1,10,1,10,1,11,1,11,4,11,199,8,11,11,11,12,11,200,1,12,1,12, - 4,12,205,8,12,11,12,12,12,206,1,13,1,13,1,14,1,14,3,14,213,8,14, - 1,14,4,14,216,8,14,11,14,12,14,217,1,14,3,14,221,8,14,1,14,1,14, - 3,14,225,8,14,1,14,4,14,228,8,14,11,14,12,14,229,3,14,232,8,14,1, - 15,1,15,1,15,1,16,1,16,1,16,5,16,240,8,16,10,16,12,16,243,9,16,1, - 17,1,17,1,17,5,17,248,8,17,10,17,12,17,251,9,17,1,18,1,18,4,18,255, - 8,18,11,18,12,18,256,1,18,1,18,1,18,3,18,262,8,18,1,18,1,18,4,18, - 266,8,18,11,18,12,18,267,1,19,5,19,271,8,19,10,19,12,19,274,9,19, - 1,19,1,19,4,19,278,8,19,11,19,12,19,279,1,19,1,19,4,19,284,8,19, - 11,19,12,19,285,3,19,288,8,19,1,20,1,20,1,20,1,20,4,20,294,8,20, - 11,20,12,20,295,1,21,1,21,1,21,1,21,1,22,1,22,4,22,304,8,22,11,22, - 12,22,305,1,22,1,22,1,23,1,23,1,24,1,24,1,25,1,25,4,25,316,8,25, - 11,25,12,25,317,1,25,1,25,1,25,1,25,4,25,324,8,25,11,25,12,25,325, - 1,25,1,25,1,25,4,25,331,8,25,11,25,12,25,332,1,26,1,26,1,27,1,27, - 4,27,339,8,27,11,27,12,27,340,1,27,1,27,1,27,1,27,4,27,347,8,27, - 11,27,12,27,348,1,28,1,28,1,28,1,28,1,28,3,28,356,8,28,1,29,1,29, - 1,29,1,29,1,29,1,30,1,30,5,30,365,8,30,10,30,12,30,368,9,30,1,31, - 3,31,371,8,31,1,31,1,31,1,32,1,32,1,32,1,33,1,33,3,33,380,8,33,1, - 34,1,34,1,35,1,35,1,36,1,36,1,37,1,37,1,38,1,38,1,39,1,39,1,40,1, - 40,1,41,1,41,1,41,0,0,42,0,2,4,6,8,10,12,14,16,18,20,22,24,26,28, - 30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72, - 74,76,78,80,82,0,4,2,0,23,23,25,25,1,0,21,22,1,0,32,34,2,0,1,18, - 30,31,407,0,87,1,0,0,0,2,107,1,0,0,0,4,138,1,0,0,0,6,140,1,0,0,0, - 8,147,1,0,0,0,10,154,1,0,0,0,12,161,1,0,0,0,14,172,1,0,0,0,16,175, - 1,0,0,0,18,192,1,0,0,0,20,194,1,0,0,0,22,196,1,0,0,0,24,202,1,0, - 0,0,26,208,1,0,0,0,28,231,1,0,0,0,30,233,1,0,0,0,32,236,1,0,0,0, - 34,244,1,0,0,0,36,252,1,0,0,0,38,272,1,0,0,0,40,289,1,0,0,0,42,297, - 1,0,0,0,44,301,1,0,0,0,46,309,1,0,0,0,48,311,1,0,0,0,50,313,1,0, - 0,0,52,334,1,0,0,0,54,336,1,0,0,0,56,355,1,0,0,0,58,357,1,0,0,0, - 60,362,1,0,0,0,62,370,1,0,0,0,64,374,1,0,0,0,66,379,1,0,0,0,68,381, - 1,0,0,0,70,383,1,0,0,0,72,385,1,0,0,0,74,387,1,0,0,0,76,389,1,0, - 0,0,78,391,1,0,0,0,80,393,1,0,0,0,82,395,1,0,0,0,84,86,5,37,0,0, - 85,84,1,0,0,0,86,89,1,0,0,0,87,85,1,0,0,0,87,88,1,0,0,0,88,93,1, - 0,0,0,89,87,1,0,0,0,90,92,3,26,13,0,91,90,1,0,0,0,92,95,1,0,0,0, - 93,91,1,0,0,0,93,94,1,0,0,0,94,99,1,0,0,0,95,93,1,0,0,0,96,98,3, - 4,2,0,97,96,1,0,0,0,98,101,1,0,0,0,99,97,1,0,0,0,99,100,1,0,0,0, - 100,102,1,0,0,0,101,99,1,0,0,0,102,103,5,6,0,0,103,1,1,0,0,0,104, - 106,5,37,0,0,105,104,1,0,0,0,106,109,1,0,0,0,107,105,1,0,0,0,107, - 108,1,0,0,0,108,111,1,0,0,0,109,107,1,0,0,0,110,112,3,16,8,0,111, - 110,1,0,0,0,112,113,1,0,0,0,113,111,1,0,0,0,113,114,1,0,0,0,114, - 118,1,0,0,0,115,117,3,26,13,0,116,115,1,0,0,0,117,120,1,0,0,0,118, - 116,1,0,0,0,118,119,1,0,0,0,119,124,1,0,0,0,120,118,1,0,0,0,121, - 123,3,4,2,0,122,121,1,0,0,0,123,126,1,0,0,0,124,122,1,0,0,0,124, - 125,1,0,0,0,125,127,1,0,0,0,126,124,1,0,0,0,127,128,5,6,0,0,128, - 3,1,0,0,0,129,130,3,6,3,0,130,131,3,12,6,0,131,139,1,0,0,0,132,133, - 3,8,4,0,133,134,3,12,6,0,134,139,1,0,0,0,135,136,3,10,5,0,136,137, - 3,12,6,0,137,139,1,0,0,0,138,129,1,0,0,0,138,132,1,0,0,0,138,135, - 1,0,0,0,139,5,1,0,0,0,140,141,5,1,0,0,141,143,3,80,40,0,142,144, - 5,37,0,0,143,142,1,0,0,0,144,145,1,0,0,0,145,143,1,0,0,0,145,146, - 1,0,0,0,146,7,1,0,0,0,147,148,5,12,0,0,148,150,3,82,41,0,149,151, - 5,37,0,0,150,149,1,0,0,0,151,152,1,0,0,0,152,150,1,0,0,0,152,153, - 1,0,0,0,153,9,1,0,0,0,154,155,5,15,0,0,155,157,3,82,41,0,156,158, - 5,37,0,0,157,156,1,0,0,0,158,159,1,0,0,0,159,157,1,0,0,0,159,160, - 1,0,0,0,160,11,1,0,0,0,161,162,3,14,7,0,162,13,1,0,0,0,163,171,3, - 22,11,0,164,171,3,24,12,0,165,171,3,28,14,0,166,171,3,36,18,0,167, - 171,3,50,25,0,168,171,3,54,27,0,169,171,3,16,8,0,170,163,1,0,0,0, - 170,164,1,0,0,0,170,165,1,0,0,0,170,166,1,0,0,0,170,167,1,0,0,0, - 170,168,1,0,0,0,170,169,1,0,0,0,171,174,1,0,0,0,172,170,1,0,0,0, - 172,173,1,0,0,0,173,15,1,0,0,0,174,172,1,0,0,0,175,176,5,28,0,0, - 176,177,3,18,9,0,177,179,3,20,10,0,178,180,5,30,0,0,179,178,1,0, - 0,0,179,180,1,0,0,0,180,182,1,0,0,0,181,183,5,37,0,0,182,181,1,0, - 0,0,183,184,1,0,0,0,184,182,1,0,0,0,184,185,1,0,0,0,185,186,1,0, - 0,0,186,187,6,8,-1,0,187,188,6,8,-1,0,188,189,6,8,-1,0,189,190,6, - 8,-1,0,190,191,6,8,-1,0,191,17,1,0,0,0,192,193,5,32,0,0,193,19,1, - 0,0,0,194,195,5,40,0,0,195,21,1,0,0,0,196,198,5,2,0,0,197,199,5, - 37,0,0,198,197,1,0,0,0,199,200,1,0,0,0,200,198,1,0,0,0,200,201,1, - 0,0,0,201,23,1,0,0,0,202,204,5,3,0,0,203,205,5,37,0,0,204,203,1, - 0,0,0,205,206,1,0,0,0,206,204,1,0,0,0,206,207,1,0,0,0,207,25,1,0, - 0,0,208,209,3,28,14,0,209,27,1,0,0,0,210,212,3,30,15,0,211,213,5, - 7,0,0,212,211,1,0,0,0,212,213,1,0,0,0,213,215,1,0,0,0,214,216,5, - 37,0,0,215,214,1,0,0,0,216,217,1,0,0,0,217,215,1,0,0,0,217,218,1, - 0,0,0,218,232,1,0,0,0,219,221,3,30,15,0,220,219,1,0,0,0,220,221, - 1,0,0,0,221,222,1,0,0,0,222,224,3,72,36,0,223,225,3,34,17,0,224, - 223,1,0,0,0,224,225,1,0,0,0,225,227,1,0,0,0,226,228,5,37,0,0,227, - 226,1,0,0,0,228,229,1,0,0,0,229,227,1,0,0,0,229,230,1,0,0,0,230, - 232,1,0,0,0,231,210,1,0,0,0,231,220,1,0,0,0,232,29,1,0,0,0,233,234, - 3,32,16,0,234,235,7,0,0,0,235,31,1,0,0,0,236,241,3,70,35,0,237,238, - 5,20,0,0,238,240,3,70,35,0,239,237,1,0,0,0,240,243,1,0,0,0,241,239, - 1,0,0,0,241,242,1,0,0,0,242,33,1,0,0,0,243,241,1,0,0,0,244,249,3, - 56,28,0,245,246,5,20,0,0,246,248,3,56,28,0,247,245,1,0,0,0,248,251, - 1,0,0,0,249,247,1,0,0,0,249,250,1,0,0,0,250,35,1,0,0,0,251,249,1, - 0,0,0,252,254,5,9,0,0,253,255,5,37,0,0,254,253,1,0,0,0,255,256,1, - 0,0,0,256,254,1,0,0,0,256,257,1,0,0,0,257,258,1,0,0,0,258,259,3, - 38,19,0,259,261,3,14,7,0,260,262,3,44,22,0,261,260,1,0,0,0,261,262, - 1,0,0,0,262,263,1,0,0,0,263,265,5,8,0,0,264,266,5,37,0,0,265,264, - 1,0,0,0,266,267,1,0,0,0,267,265,1,0,0,0,267,268,1,0,0,0,268,37,1, - 0,0,0,269,271,3,40,20,0,270,269,1,0,0,0,271,274,1,0,0,0,272,270, - 1,0,0,0,272,273,1,0,0,0,273,275,1,0,0,0,274,272,1,0,0,0,275,277, - 3,42,21,0,276,278,5,37,0,0,277,276,1,0,0,0,278,279,1,0,0,0,279,277, - 1,0,0,0,279,280,1,0,0,0,280,287,1,0,0,0,281,283,5,14,0,0,282,284, - 5,37,0,0,283,282,1,0,0,0,284,285,1,0,0,0,285,283,1,0,0,0,285,286, - 1,0,0,0,286,288,1,0,0,0,287,281,1,0,0,0,287,288,1,0,0,0,288,39,1, - 0,0,0,289,290,3,42,21,0,290,291,5,20,0,0,291,293,3,48,24,0,292,294, - 5,37,0,0,293,292,1,0,0,0,294,295,1,0,0,0,295,293,1,0,0,0,295,296, - 1,0,0,0,296,41,1,0,0,0,297,298,3,14,7,0,298,299,5,10,0,0,299,300, - 3,46,23,0,300,43,1,0,0,0,301,303,5,5,0,0,302,304,5,37,0,0,303,302, - 1,0,0,0,304,305,1,0,0,0,305,303,1,0,0,0,305,306,1,0,0,0,306,307, - 1,0,0,0,307,308,3,14,7,0,308,45,1,0,0,0,309,310,5,30,0,0,310,47, - 1,0,0,0,311,312,5,30,0,0,312,49,1,0,0,0,313,315,5,18,0,0,314,316, - 5,37,0,0,315,314,1,0,0,0,316,317,1,0,0,0,317,315,1,0,0,0,317,318, - 1,0,0,0,318,319,1,0,0,0,319,320,3,52,26,0,320,321,5,13,0,0,321,323, - 3,46,23,0,322,324,5,37,0,0,323,322,1,0,0,0,324,325,1,0,0,0,325,323, - 1,0,0,0,325,326,1,0,0,0,326,327,1,0,0,0,327,328,3,14,7,0,328,330, - 5,17,0,0,329,331,5,37,0,0,330,329,1,0,0,0,331,332,1,0,0,0,332,330, - 1,0,0,0,332,333,1,0,0,0,333,51,1,0,0,0,334,335,3,14,7,0,335,53,1, - 0,0,0,336,338,5,4,0,0,337,339,5,37,0,0,338,337,1,0,0,0,339,340,1, - 0,0,0,340,338,1,0,0,0,340,341,1,0,0,0,341,342,1,0,0,0,342,343,3, - 14,7,0,343,344,5,16,0,0,344,346,3,46,23,0,345,347,5,37,0,0,346,345, - 1,0,0,0,347,348,1,0,0,0,348,346,1,0,0,0,348,349,1,0,0,0,349,55,1, - 0,0,0,350,356,3,78,39,0,351,356,3,74,37,0,352,356,3,76,38,0,353, - 356,3,60,30,0,354,356,3,58,29,0,355,350,1,0,0,0,355,351,1,0,0,0, - 355,352,1,0,0,0,355,353,1,0,0,0,355,354,1,0,0,0,356,57,1,0,0,0,357, - 358,3,68,34,0,358,359,5,26,0,0,359,360,3,60,30,0,360,361,5,27,0, - 0,361,59,1,0,0,0,362,366,3,62,31,0,363,365,3,64,32,0,364,363,1,0, - 0,0,365,368,1,0,0,0,366,364,1,0,0,0,366,367,1,0,0,0,367,61,1,0,0, - 0,368,366,1,0,0,0,369,371,7,1,0,0,370,369,1,0,0,0,370,371,1,0,0, - 0,371,372,1,0,0,0,372,373,3,66,33,0,373,63,1,0,0,0,374,375,7,1,0, - 0,375,376,3,66,33,0,376,65,1,0,0,0,377,380,3,80,40,0,378,380,3,70, - 35,0,379,377,1,0,0,0,379,378,1,0,0,0,380,67,1,0,0,0,381,382,3,82, - 41,0,382,69,1,0,0,0,383,384,3,82,41,0,384,71,1,0,0,0,385,386,5,30, - 0,0,386,73,1,0,0,0,387,388,5,35,0,0,388,75,1,0,0,0,389,390,5,29, - 0,0,390,77,1,0,0,0,391,392,5,36,0,0,392,79,1,0,0,0,393,394,7,2,0, - 0,394,81,1,0,0,0,395,396,7,3,0,0,396,83,1,0,0,0,43,87,93,99,107, - 113,118,124,138,145,152,159,170,172,179,184,200,206,212,217,220, - 224,229,231,241,249,256,261,267,272,279,285,287,295,305,317,325, - 332,340,348,355,366,370,379 + 2,40,7,40,2,41,7,41,2,42,7,42,2,43,7,43,1,0,5,0,90,8,0,10,0,12,0, + 93,9,0,1,0,5,0,96,8,0,10,0,12,0,99,9,0,1,0,5,0,102,8,0,10,0,12,0, + 105,9,0,1,0,1,0,1,1,5,1,110,8,1,10,1,12,1,113,9,1,1,1,4,1,116,8, + 1,11,1,12,1,117,1,1,5,1,121,8,1,10,1,12,1,124,9,1,1,1,5,1,127,8, + 1,10,1,12,1,130,9,1,1,1,1,1,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2, + 3,2,143,8,2,1,3,1,3,1,3,4,3,148,8,3,11,3,12,3,149,1,4,1,4,1,4,4, + 4,155,8,4,11,4,12,4,156,1,5,1,5,1,5,4,5,162,8,5,11,5,12,5,163,1, + 6,1,6,1,7,1,7,1,7,1,7,1,7,1,7,1,7,5,7,175,8,7,10,7,12,7,178,9,7, + 1,8,1,8,1,8,1,8,3,8,184,8,8,1,8,4,8,187,8,8,11,8,12,8,188,1,8,1, + 8,1,8,1,8,1,8,1,8,1,9,1,9,1,10,1,10,1,11,1,11,4,11,203,8,11,11,11, + 12,11,204,1,12,1,12,4,12,209,8,12,11,12,12,12,210,1,13,1,13,1,14, + 1,14,1,14,3,14,218,8,14,1,15,1,15,1,15,1,15,3,15,224,8,15,1,16,1, + 16,3,16,228,8,16,1,16,4,16,231,8,16,11,16,12,16,232,1,16,3,16,236, + 8,16,1,16,1,16,3,16,240,8,16,1,16,4,16,243,8,16,11,16,12,16,244, + 3,16,247,8,16,1,17,1,17,1,17,1,18,1,18,1,18,5,18,255,8,18,10,18, + 12,18,258,9,18,1,19,1,19,1,19,5,19,263,8,19,10,19,12,19,266,9,19, + 1,20,1,20,4,20,270,8,20,11,20,12,20,271,1,20,1,20,1,20,3,20,277, + 8,20,1,20,1,20,4,20,281,8,20,11,20,12,20,282,1,21,5,21,286,8,21, + 10,21,12,21,289,9,21,1,21,1,21,4,21,293,8,21,11,21,12,21,294,1,21, + 1,21,4,21,299,8,21,11,21,12,21,300,3,21,303,8,21,1,22,1,22,1,22, + 1,22,4,22,309,8,22,11,22,12,22,310,1,23,1,23,1,23,1,23,1,24,1,24, + 4,24,319,8,24,11,24,12,24,320,1,24,1,24,1,25,1,25,1,26,1,26,1,27, + 1,27,4,27,331,8,27,11,27,12,27,332,1,27,1,27,1,27,1,27,4,27,339, + 8,27,11,27,12,27,340,1,27,1,27,1,27,4,27,346,8,27,11,27,12,27,347, + 1,28,1,28,1,29,1,29,4,29,354,8,29,11,29,12,29,355,1,29,1,29,1,29, + 1,29,4,29,362,8,29,11,29,12,29,363,1,30,1,30,1,30,1,30,1,30,3,30, + 371,8,30,1,31,1,31,1,31,1,31,1,31,1,32,1,32,5,32,380,8,32,10,32, + 12,32,383,9,32,1,33,3,33,386,8,33,1,33,1,33,1,34,1,34,1,34,1,35, + 1,35,3,35,395,8,35,1,36,1,36,1,37,1,37,1,38,1,38,1,39,1,39,1,40, + 1,40,1,41,1,41,1,42,1,42,1,43,1,43,1,43,0,0,44,0,2,4,6,8,10,12,14, + 16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58, + 60,62,64,66,68,70,72,74,76,78,80,82,84,86,0,3,1,0,23,24,1,0,35,37, + 2,0,1,20,33,34,425,0,91,1,0,0,0,2,111,1,0,0,0,4,142,1,0,0,0,6,144, + 1,0,0,0,8,151,1,0,0,0,10,158,1,0,0,0,12,165,1,0,0,0,14,176,1,0,0, + 0,16,179,1,0,0,0,18,196,1,0,0,0,20,198,1,0,0,0,22,200,1,0,0,0,24, + 206,1,0,0,0,26,212,1,0,0,0,28,217,1,0,0,0,30,223,1,0,0,0,32,246, + 1,0,0,0,34,248,1,0,0,0,36,251,1,0,0,0,38,259,1,0,0,0,40,267,1,0, + 0,0,42,287,1,0,0,0,44,304,1,0,0,0,46,312,1,0,0,0,48,316,1,0,0,0, + 50,324,1,0,0,0,52,326,1,0,0,0,54,328,1,0,0,0,56,349,1,0,0,0,58,351, + 1,0,0,0,60,370,1,0,0,0,62,372,1,0,0,0,64,377,1,0,0,0,66,385,1,0, + 0,0,68,389,1,0,0,0,70,394,1,0,0,0,72,396,1,0,0,0,74,398,1,0,0,0, + 76,400,1,0,0,0,78,402,1,0,0,0,80,404,1,0,0,0,82,406,1,0,0,0,84,408, + 1,0,0,0,86,410,1,0,0,0,88,90,5,40,0,0,89,88,1,0,0,0,90,93,1,0,0, + 0,91,89,1,0,0,0,91,92,1,0,0,0,92,97,1,0,0,0,93,91,1,0,0,0,94,96, + 3,26,13,0,95,94,1,0,0,0,96,99,1,0,0,0,97,95,1,0,0,0,97,98,1,0,0, + 0,98,103,1,0,0,0,99,97,1,0,0,0,100,102,3,4,2,0,101,100,1,0,0,0,102, + 105,1,0,0,0,103,101,1,0,0,0,103,104,1,0,0,0,104,106,1,0,0,0,105, + 103,1,0,0,0,106,107,5,6,0,0,107,1,1,0,0,0,108,110,5,40,0,0,109,108, + 1,0,0,0,110,113,1,0,0,0,111,109,1,0,0,0,111,112,1,0,0,0,112,115, + 1,0,0,0,113,111,1,0,0,0,114,116,3,16,8,0,115,114,1,0,0,0,116,117, + 1,0,0,0,117,115,1,0,0,0,117,118,1,0,0,0,118,122,1,0,0,0,119,121, + 3,26,13,0,120,119,1,0,0,0,121,124,1,0,0,0,122,120,1,0,0,0,122,123, + 1,0,0,0,123,128,1,0,0,0,124,122,1,0,0,0,125,127,3,4,2,0,126,125, + 1,0,0,0,127,130,1,0,0,0,128,126,1,0,0,0,128,129,1,0,0,0,129,131, + 1,0,0,0,130,128,1,0,0,0,131,132,5,6,0,0,132,3,1,0,0,0,133,134,3, + 6,3,0,134,135,3,12,6,0,135,143,1,0,0,0,136,137,3,8,4,0,137,138,3, + 12,6,0,138,143,1,0,0,0,139,140,3,10,5,0,140,141,3,12,6,0,141,143, + 1,0,0,0,142,133,1,0,0,0,142,136,1,0,0,0,142,139,1,0,0,0,143,5,1, + 0,0,0,144,145,5,1,0,0,145,147,3,84,42,0,146,148,5,40,0,0,147,146, + 1,0,0,0,148,149,1,0,0,0,149,147,1,0,0,0,149,150,1,0,0,0,150,7,1, + 0,0,0,151,152,5,14,0,0,152,154,3,86,43,0,153,155,5,40,0,0,154,153, + 1,0,0,0,155,156,1,0,0,0,156,154,1,0,0,0,156,157,1,0,0,0,157,9,1, + 0,0,0,158,159,5,17,0,0,159,161,3,86,43,0,160,162,5,40,0,0,161,160, + 1,0,0,0,162,163,1,0,0,0,163,161,1,0,0,0,163,164,1,0,0,0,164,11,1, + 0,0,0,165,166,3,14,7,0,166,13,1,0,0,0,167,175,3,22,11,0,168,175, + 3,24,12,0,169,175,3,32,16,0,170,175,3,40,20,0,171,175,3,54,27,0, + 172,175,3,58,29,0,173,175,3,16,8,0,174,167,1,0,0,0,174,168,1,0,0, + 0,174,169,1,0,0,0,174,170,1,0,0,0,174,171,1,0,0,0,174,172,1,0,0, + 0,174,173,1,0,0,0,175,178,1,0,0,0,176,174,1,0,0,0,176,177,1,0,0, + 0,177,15,1,0,0,0,178,176,1,0,0,0,179,180,5,31,0,0,180,181,3,18,9, + 0,181,183,3,20,10,0,182,184,5,33,0,0,183,182,1,0,0,0,183,184,1,0, + 0,0,184,186,1,0,0,0,185,187,5,40,0,0,186,185,1,0,0,0,187,188,1,0, + 0,0,188,186,1,0,0,0,188,189,1,0,0,0,189,190,1,0,0,0,190,191,6,8, + -1,0,191,192,6,8,-1,0,192,193,6,8,-1,0,193,194,6,8,-1,0,194,195, + 6,8,-1,0,195,17,1,0,0,0,196,197,5,35,0,0,197,19,1,0,0,0,198,199, + 5,43,0,0,199,21,1,0,0,0,200,202,5,2,0,0,201,203,5,40,0,0,202,201, + 1,0,0,0,203,204,1,0,0,0,204,202,1,0,0,0,204,205,1,0,0,0,205,23,1, + 0,0,0,206,208,5,3,0,0,207,209,5,40,0,0,208,207,1,0,0,0,209,210,1, + 0,0,0,210,208,1,0,0,0,210,211,1,0,0,0,211,25,1,0,0,0,212,213,3,32, + 16,0,213,27,1,0,0,0,214,218,5,7,0,0,215,218,5,8,0,0,216,218,5,9, + 0,0,217,214,1,0,0,0,217,215,1,0,0,0,217,216,1,0,0,0,218,29,1,0,0, + 0,219,224,5,25,0,0,220,224,5,26,0,0,221,224,5,27,0,0,222,224,5,28, + 0,0,223,219,1,0,0,0,223,220,1,0,0,0,223,221,1,0,0,0,223,222,1,0, + 0,0,224,31,1,0,0,0,225,227,3,34,17,0,226,228,3,28,14,0,227,226,1, + 0,0,0,227,228,1,0,0,0,228,230,1,0,0,0,229,231,5,40,0,0,230,229,1, + 0,0,0,231,232,1,0,0,0,232,230,1,0,0,0,232,233,1,0,0,0,233,247,1, + 0,0,0,234,236,3,34,17,0,235,234,1,0,0,0,235,236,1,0,0,0,236,237, + 1,0,0,0,237,239,3,76,38,0,238,240,3,38,19,0,239,238,1,0,0,0,239, + 240,1,0,0,0,240,242,1,0,0,0,241,243,5,40,0,0,242,241,1,0,0,0,243, + 244,1,0,0,0,244,242,1,0,0,0,244,245,1,0,0,0,245,247,1,0,0,0,246, + 225,1,0,0,0,246,235,1,0,0,0,247,33,1,0,0,0,248,249,3,36,18,0,249, + 250,3,30,15,0,250,35,1,0,0,0,251,256,3,74,37,0,252,253,5,22,0,0, + 253,255,3,74,37,0,254,252,1,0,0,0,255,258,1,0,0,0,256,254,1,0,0, + 0,256,257,1,0,0,0,257,37,1,0,0,0,258,256,1,0,0,0,259,264,3,60,30, + 0,260,261,5,22,0,0,261,263,3,60,30,0,262,260,1,0,0,0,263,266,1,0, + 0,0,264,262,1,0,0,0,264,265,1,0,0,0,265,39,1,0,0,0,266,264,1,0,0, + 0,267,269,5,11,0,0,268,270,5,40,0,0,269,268,1,0,0,0,270,271,1,0, + 0,0,271,269,1,0,0,0,271,272,1,0,0,0,272,273,1,0,0,0,273,274,3,42, + 21,0,274,276,3,14,7,0,275,277,3,48,24,0,276,275,1,0,0,0,276,277, + 1,0,0,0,277,278,1,0,0,0,278,280,5,10,0,0,279,281,5,40,0,0,280,279, + 1,0,0,0,281,282,1,0,0,0,282,280,1,0,0,0,282,283,1,0,0,0,283,41,1, + 0,0,0,284,286,3,44,22,0,285,284,1,0,0,0,286,289,1,0,0,0,287,285, + 1,0,0,0,287,288,1,0,0,0,288,290,1,0,0,0,289,287,1,0,0,0,290,292, + 3,46,23,0,291,293,5,40,0,0,292,291,1,0,0,0,293,294,1,0,0,0,294,292, + 1,0,0,0,294,295,1,0,0,0,295,302,1,0,0,0,296,298,5,16,0,0,297,299, + 5,40,0,0,298,297,1,0,0,0,299,300,1,0,0,0,300,298,1,0,0,0,300,301, + 1,0,0,0,301,303,1,0,0,0,302,296,1,0,0,0,302,303,1,0,0,0,303,43,1, + 0,0,0,304,305,3,46,23,0,305,306,5,22,0,0,306,308,3,52,26,0,307,309, + 5,40,0,0,308,307,1,0,0,0,309,310,1,0,0,0,310,308,1,0,0,0,310,311, + 1,0,0,0,311,45,1,0,0,0,312,313,3,14,7,0,313,314,5,12,0,0,314,315, + 3,50,25,0,315,47,1,0,0,0,316,318,5,5,0,0,317,319,5,40,0,0,318,317, + 1,0,0,0,319,320,1,0,0,0,320,318,1,0,0,0,320,321,1,0,0,0,321,322, + 1,0,0,0,322,323,3,14,7,0,323,49,1,0,0,0,324,325,5,33,0,0,325,51, + 1,0,0,0,326,327,5,33,0,0,327,53,1,0,0,0,328,330,5,20,0,0,329,331, + 5,40,0,0,330,329,1,0,0,0,331,332,1,0,0,0,332,330,1,0,0,0,332,333, + 1,0,0,0,333,334,1,0,0,0,334,335,3,56,28,0,335,336,5,15,0,0,336,338, + 3,50,25,0,337,339,5,40,0,0,338,337,1,0,0,0,339,340,1,0,0,0,340,338, + 1,0,0,0,340,341,1,0,0,0,341,342,1,0,0,0,342,343,3,14,7,0,343,345, + 5,19,0,0,344,346,5,40,0,0,345,344,1,0,0,0,346,347,1,0,0,0,347,345, + 1,0,0,0,347,348,1,0,0,0,348,55,1,0,0,0,349,350,3,14,7,0,350,57,1, + 0,0,0,351,353,5,4,0,0,352,354,5,40,0,0,353,352,1,0,0,0,354,355,1, + 0,0,0,355,353,1,0,0,0,355,356,1,0,0,0,356,357,1,0,0,0,357,358,3, + 14,7,0,358,359,5,18,0,0,359,361,3,50,25,0,360,362,5,40,0,0,361,360, + 1,0,0,0,362,363,1,0,0,0,363,361,1,0,0,0,363,364,1,0,0,0,364,59,1, + 0,0,0,365,371,3,82,41,0,366,371,3,78,39,0,367,371,3,80,40,0,368, + 371,3,64,32,0,369,371,3,62,31,0,370,365,1,0,0,0,370,366,1,0,0,0, + 370,367,1,0,0,0,370,368,1,0,0,0,370,369,1,0,0,0,371,61,1,0,0,0,372, + 373,3,72,36,0,373,374,5,29,0,0,374,375,3,64,32,0,375,376,5,30,0, + 0,376,63,1,0,0,0,377,381,3,66,33,0,378,380,3,68,34,0,379,378,1,0, + 0,0,380,383,1,0,0,0,381,379,1,0,0,0,381,382,1,0,0,0,382,65,1,0,0, + 0,383,381,1,0,0,0,384,386,7,0,0,0,385,384,1,0,0,0,385,386,1,0,0, + 0,386,387,1,0,0,0,387,388,3,70,35,0,388,67,1,0,0,0,389,390,7,0,0, + 0,390,391,3,70,35,0,391,69,1,0,0,0,392,395,3,84,42,0,393,395,3,74, + 37,0,394,392,1,0,0,0,394,393,1,0,0,0,395,71,1,0,0,0,396,397,3,86, + 43,0,397,73,1,0,0,0,398,399,3,86,43,0,399,75,1,0,0,0,400,401,5,33, + 0,0,401,77,1,0,0,0,402,403,5,38,0,0,403,79,1,0,0,0,404,405,5,32, + 0,0,405,81,1,0,0,0,406,407,5,39,0,0,407,83,1,0,0,0,408,409,7,1,0, + 0,409,85,1,0,0,0,410,411,7,2,0,0,411,87,1,0,0,0,45,91,97,103,111, + 117,122,128,142,149,156,163,174,176,183,188,204,210,217,223,227, + 232,235,239,244,246,256,264,271,276,282,287,294,300,302,310,320, + 332,340,347,355,363,370,381,385,394 ] class AsmParser ( Parser ): @@ -167,19 +173,21 @@ class AsmParser ( Parser ): sharedContextCache = PredictionContextCache() literalNames = [ "", "'asect'", "'break'", "'continue'", "'do'", - "'else'", "'end'", "'ext'", "'fi'", "'if'", "'is'", - "'macro'", "'rsect'", "'stays'", "'then'", "'tplate'", - "'until'", "'wend'", "'while'", "'.'", "','", "'+'", - "'-'", "':'", "'*'", "'>'", "'('", "')'", "'-|'" ] + "'else'", "'end'", "'ext'", "'file'", "'weak'", "'fi'", + "'if'", "'is'", "'macro'", "'rsect'", "'stays'", "'then'", + "'tplate'", "'until'", "'wend'", "'while'", "'.'", + "','", "'+'", "'-'", "':'", "'>'", "':>'", "'~>'", + "'('", "')'", "'-|'" ] symbolicNames = [ "", "Asect", "Break", "Continue", "Do", "Else", - "End", "Ext", "Fi", "If", "Is", "Macro", "Rsect", - "Stays", "Then", "Tplate", "Until", "Wend", "While", - "DOT", "COMMA", "PLUS", "MINUS", "COLON", "ASTERISK", - "ANGLE_BRACKET", "OPEN_PAREN", "CLOSE_PAREN", "LINE_MARK_MARKER", - "REGISTER", "WORD", "WORD_WITH_DOTS", "DECIMAL_NUMBER", - "BINARY_NUMBER", "HEX_NUMBER", "STRING", "CHAR", "NEWLINE", - "COMMENT", "WS", "BASE64", "UNEXPECTED_TOKEN" ] + "End", "Ext", "File", "Weak", "Fi", "If", "Is", "Macro", + "Rsect", "Stays", "Then", "Tplate", "Until", "Wend", + "While", "DOT", "COMMA", "PLUS", "MINUS", "COLON", + "ANGLE_BRACKET", "COLON_ANGLE", "TILDE_ANGLE", "OPEN_PAREN", + "CLOSE_PAREN", "LINE_MARK_MARKER", "REGISTER", "WORD", + "WORD_WITH_DOTS", "DECIMAL_NUMBER", "BINARY_NUMBER", + "HEX_NUMBER", "STRING", "CHAR", "NEWLINE", "COMMENT", + "WS", "BASE64", "UNEXPECTED_TOKEN" ] RULE_program_nomacros = 0 RULE_program = 1 @@ -195,40 +203,43 @@ class AsmParser ( Parser ): RULE_break_statement = 11 RULE_continue_statement = 12 RULE_top_line = 13 - RULE_line = 14 - RULE_labels_declaration = 15 - RULE_labels = 16 - RULE_arguments = 17 - RULE_conditional = 18 - RULE_conditions = 19 - RULE_connective_condition = 20 - RULE_condition = 21 - RULE_else_clause = 22 - RULE_branch_mnemonic = 23 - RULE_conjunction = 24 - RULE_while_loop = 25 - RULE_while_condition = 26 - RULE_until_loop = 27 - RULE_argument = 28 - RULE_byte_expr = 29 - RULE_addr_expr = 30 - RULE_first_term = 31 - RULE_add_term = 32 - RULE_term = 33 - RULE_byte_specifier = 34 - RULE_label = 35 - RULE_instruction = 36 - RULE_string = 37 - RULE_register = 38 - RULE_character = 39 - RULE_number = 40 - RULE_name = 41 + RULE_ext_type = 14 + RULE_label_suffix = 15 + RULE_line = 16 + RULE_labels_declaration = 17 + RULE_labels = 18 + RULE_arguments = 19 + RULE_conditional = 20 + RULE_conditions = 21 + RULE_connective_condition = 22 + RULE_condition = 23 + RULE_else_clause = 24 + RULE_branch_mnemonic = 25 + RULE_conjunction = 26 + RULE_while_loop = 27 + RULE_while_condition = 28 + RULE_until_loop = 29 + RULE_argument = 30 + RULE_byte_expr = 31 + RULE_addr_expr = 32 + RULE_first_term = 33 + RULE_add_term = 34 + RULE_term = 35 + RULE_byte_specifier = 36 + RULE_label = 37 + RULE_instruction = 38 + RULE_string = 39 + RULE_register = 40 + RULE_character = 41 + RULE_number = 42 + RULE_name = 43 ruleNames = [ "program_nomacros", "program", "section", "asect_header", "rsect_header", "tplate_header", "section_body", "code_block", "line_mark", "line_number", "filepath", "break_statement", - "continue_statement", "top_line", "line", "labels_declaration", - "labels", "arguments", "conditional", "conditions", "connective_condition", + "continue_statement", "top_line", "ext_type", "label_suffix", + "line", "labels_declaration", "labels", "arguments", + "conditional", "conditions", "connective_condition", "condition", "else_clause", "branch_mnemonic", "conjunction", "while_loop", "while_condition", "until_loop", "argument", "byte_expr", "addr_expr", "first_term", "add_term", "term", @@ -243,44 +254,47 @@ class AsmParser ( Parser ): Else=5 End=6 Ext=7 - Fi=8 - If=9 - Is=10 - Macro=11 - Rsect=12 - Stays=13 - Then=14 - Tplate=15 - Until=16 - Wend=17 - While=18 - DOT=19 - COMMA=20 - PLUS=21 - MINUS=22 - COLON=23 - ASTERISK=24 - ANGLE_BRACKET=25 - OPEN_PAREN=26 - CLOSE_PAREN=27 - LINE_MARK_MARKER=28 - REGISTER=29 - WORD=30 - WORD_WITH_DOTS=31 - DECIMAL_NUMBER=32 - BINARY_NUMBER=33 - HEX_NUMBER=34 - STRING=35 - CHAR=36 - NEWLINE=37 - COMMENT=38 - WS=39 - BASE64=40 - UNEXPECTED_TOKEN=41 + File=8 + Weak=9 + Fi=10 + If=11 + Is=12 + Macro=13 + Rsect=14 + Stays=15 + Then=16 + Tplate=17 + Until=18 + Wend=19 + While=20 + DOT=21 + COMMA=22 + PLUS=23 + MINUS=24 + COLON=25 + ANGLE_BRACKET=26 + COLON_ANGLE=27 + TILDE_ANGLE=28 + OPEN_PAREN=29 + CLOSE_PAREN=30 + LINE_MARK_MARKER=31 + REGISTER=32 + WORD=33 + WORD_WITH_DOTS=34 + DECIMAL_NUMBER=35 + BINARY_NUMBER=36 + HEX_NUMBER=37 + STRING=38 + CHAR=39 + NEWLINE=40 + COMMENT=41 + WS=42 + BASE64=43 + UNEXPECTED_TOKEN=44 def __init__(self, input:TokenStream, output:TextIO = sys.stdout): super().__init__(input, output) - self.checkVersion("4.13.1") + self.checkVersion("4.13.2") self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache) self._predicates = None @@ -341,38 +355,38 @@ def program_nomacros(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 87 + self.state = 91 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==37: - self.state = 84 + while _la==40: + self.state = 88 self.match(AsmParser.NEWLINE) - self.state = 89 + self.state = 93 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 93 + self.state = 97 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,1,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 90 + self.state = 94 self.top_line() - self.state = 95 + self.state = 99 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,1,self._ctx) - self.state = 99 + self.state = 103 self._errHandler.sync(self) _la = self._input.LA(1) - while (((_la) & ~0x3f) == 0 and ((1 << _la) & 36866) != 0): - self.state = 96 + while (((_la) & ~0x3f) == 0 and ((1 << _la) & 147458) != 0): + self.state = 100 self.section() - self.state = 101 + self.state = 105 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 102 + self.state = 106 self.match(AsmParser.End) except RecognitionException as re: localctx.exception = re @@ -439,50 +453,50 @@ def program(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 107 + self.state = 111 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==37: - self.state = 104 + while _la==40: + self.state = 108 self.match(AsmParser.NEWLINE) - self.state = 109 + self.state = 113 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 111 + self.state = 115 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 110 + self.state = 114 self.line_mark() - self.state = 113 + self.state = 117 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==28): + if not (_la==31): break - self.state = 118 + self.state = 122 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,5,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 115 + self.state = 119 self.top_line() - self.state = 120 + self.state = 124 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,5,self._ctx) - self.state = 124 + self.state = 128 self._errHandler.sync(self) _la = self._input.LA(1) - while (((_la) & ~0x3f) == 0 and ((1 << _la) & 36866) != 0): - self.state = 121 + while (((_la) & ~0x3f) == 0 and ((1 << _la) & 147458) != 0): + self.state = 125 self.section() - self.state = 126 + self.state = 130 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 127 + self.state = 131 self.match(AsmParser.End) except RecognitionException as re: localctx.exception = re @@ -576,31 +590,31 @@ def section(self): localctx = AsmParser.SectionContext(self, self._ctx, self.state) self.enterRule(localctx, 4, self.RULE_section) try: - self.state = 138 + self.state = 142 self._errHandler.sync(self) token = self._input.LA(1) if token in [1]: localctx = AsmParser.AbsoluteSectionContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 129 + self.state = 133 self.asect_header() - self.state = 130 + self.state = 134 self.section_body() pass - elif token in [12]: + elif token in [14]: localctx = AsmParser.RelocatableSectionContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 132 + self.state = 136 self.rsect_header() - self.state = 133 + self.state = 137 self.section_body() pass - elif token in [15]: + elif token in [17]: localctx = AsmParser.TemplateSectionContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 135 + self.state = 139 self.tplate_header() - self.state = 136 + self.state = 140 self.section_body() pass else: @@ -654,20 +668,20 @@ def asect_header(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 140 + self.state = 144 self.match(AsmParser.Asect) - self.state = 141 + self.state = 145 self.number() - self.state = 143 + self.state = 147 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 142 + self.state = 146 self.match(AsmParser.NEWLINE) - self.state = 145 + self.state = 149 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==37): + if not (_la==40): break except RecognitionException as re: @@ -718,20 +732,20 @@ def rsect_header(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 147 + self.state = 151 self.match(AsmParser.Rsect) - self.state = 148 + self.state = 152 self.name() - self.state = 150 + self.state = 154 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 149 + self.state = 153 self.match(AsmParser.NEWLINE) - self.state = 152 + self.state = 156 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==37): + if not (_la==40): break except RecognitionException as re: @@ -782,20 +796,20 @@ def tplate_header(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 154 + self.state = 158 self.match(AsmParser.Tplate) - self.state = 155 + self.state = 159 self.name() - self.state = 157 + self.state = 161 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 156 + self.state = 160 self.match(AsmParser.NEWLINE) - self.state = 159 + self.state = 163 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==37): + if not (_la==40): break except RecognitionException as re: @@ -836,7 +850,7 @@ def section_body(self): self.enterRule(localctx, 12, self.RULE_section_body) try: self.enterOuterAlt(localctx, 1) - self.state = 161 + self.state = 165 self.code_block() except RecognitionException as re: localctx.exception = re @@ -921,51 +935,51 @@ def code_block(self): self.enterRule(localctx, 14, self.RULE_code_block) try: self.enterOuterAlt(localctx, 1) - self.state = 172 + self.state = 176 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,12,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 170 + self.state = 174 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,11,self._ctx) if la_ == 1: - self.state = 163 + self.state = 167 self.break_statement() pass elif la_ == 2: - self.state = 164 + self.state = 168 self.continue_statement() pass elif la_ == 3: - self.state = 165 + self.state = 169 self.line() pass elif la_ == 4: - self.state = 166 + self.state = 170 self.conditional() pass elif la_ == 5: - self.state = 167 + self.state = 171 self.while_loop() pass elif la_ == 6: - self.state = 168 + self.state = 172 self.until_loop() pass elif la_ == 7: - self.state = 169 + self.state = 173 self.line_mark() pass - self.state = 174 + self.state = 178 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,12,self._ctx) @@ -1028,30 +1042,30 @@ def line_mark(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 175 + self.state = 179 self.match(AsmParser.LINE_MARK_MARKER) - self.state = 176 + self.state = 180 localctx._line_number = self.line_number() - self.state = 177 + self.state = 181 localctx._filepath = self.filepath() - self.state = 179 + self.state = 183 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==30: - self.state = 178 + if _la==33: + self.state = 182 self.match(AsmParser.WORD) - self.state = 182 + self.state = 186 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 181 + self.state = 185 self.match(AsmParser.NEWLINE) - self.state = 184 + self.state = 188 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==37): + if not (_la==40): break self.current_line = int((None if localctx._line_number is None else self._input.getText(localctx._line_number.start,localctx._line_number.stop))) @@ -1096,7 +1110,7 @@ def line_number(self): self.enterRule(localctx, 18, self.RULE_line_number) try: self.enterOuterAlt(localctx, 1) - self.state = 192 + self.state = 196 self.match(AsmParser.DECIMAL_NUMBER) except RecognitionException as re: localctx.exception = re @@ -1135,7 +1149,7 @@ def filepath(self): self.enterRule(localctx, 20, self.RULE_filepath) try: self.enterOuterAlt(localctx, 1) - self.state = 194 + self.state = 198 self.match(AsmParser.BASE64) except RecognitionException as re: localctx.exception = re @@ -1181,18 +1195,18 @@ def break_statement(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 196 + self.state = 200 self.match(AsmParser.Break) - self.state = 198 + self.state = 202 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 197 + self.state = 201 self.match(AsmParser.NEWLINE) - self.state = 200 + self.state = 204 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==37): + if not (_la==40): break except RecognitionException as re: @@ -1239,18 +1253,18 @@ def continue_statement(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 202 + self.state = 206 self.match(AsmParser.Continue) - self.state = 204 + self.state = 208 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 203 + self.state = 207 self.match(AsmParser.NEWLINE) - self.state = 206 + self.state = 210 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==37): + if not (_la==40): break except RecognitionException as re: @@ -1291,7 +1305,7 @@ def top_line(self): self.enterRule(localctx, 26, self.RULE_top_line) try: self.enterOuterAlt(localctx, 1) - self.state = 208 + self.state = 212 self.line() except RecognitionException as re: localctx.exception = re @@ -1302,6 +1316,236 @@ def top_line(self): return localctx + class Ext_typeContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + + def getRuleIndex(self): + return AsmParser.RULE_ext_type + + + def copyFrom(self, ctx:ParserRuleContext): + super().copyFrom(ctx) + + + + class WeakExtTypeContext(Ext_typeContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a AsmParser.Ext_typeContext + super().__init__(parser) + self.copyFrom(ctx) + + def Weak(self): + return self.getToken(AsmParser.Weak, 0) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitWeakExtType" ): + return visitor.visitWeakExtType(self) + else: + return visitor.visitChildren(self) + + + class GlobalExtTypeContext(Ext_typeContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a AsmParser.Ext_typeContext + super().__init__(parser) + self.copyFrom(ctx) + + def Ext(self): + return self.getToken(AsmParser.Ext, 0) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitGlobalExtType" ): + return visitor.visitGlobalExtType(self) + else: + return visitor.visitChildren(self) + + + class FileExtTypeContext(Ext_typeContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a AsmParser.Ext_typeContext + super().__init__(parser) + self.copyFrom(ctx) + + def File(self): + return self.getToken(AsmParser.File, 0) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitFileExtType" ): + return visitor.visitFileExtType(self) + else: + return visitor.visitChildren(self) + + + + def ext_type(self): + + localctx = AsmParser.Ext_typeContext(self, self._ctx, self.state) + self.enterRule(localctx, 28, self.RULE_ext_type) + try: + self.state = 217 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [7]: + localctx = AsmParser.GlobalExtTypeContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 214 + self.match(AsmParser.Ext) + pass + elif token in [8]: + localctx = AsmParser.FileExtTypeContext(self, localctx) + self.enterOuterAlt(localctx, 2) + self.state = 215 + self.match(AsmParser.File) + pass + elif token in [9]: + localctx = AsmParser.WeakExtTypeContext(self, localctx) + self.enterOuterAlt(localctx, 3) + self.state = 216 + self.match(AsmParser.Weak) + pass + else: + raise NoViableAltException(self) + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + + class Label_suffixContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + + def getRuleIndex(self): + return AsmParser.RULE_label_suffix + + + def copyFrom(self, ctx:ParserRuleContext): + super().copyFrom(ctx) + + + + class LocalLabelSuffixContext(Label_suffixContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a AsmParser.Label_suffixContext + super().__init__(parser) + self.copyFrom(ctx) + + def COLON(self): + return self.getToken(AsmParser.COLON, 0) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitLocalLabelSuffix" ): + return visitor.visitLocalLabelSuffix(self) + else: + return visitor.visitChildren(self) + + + class WeakLabelSuffixContext(Label_suffixContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a AsmParser.Label_suffixContext + super().__init__(parser) + self.copyFrom(ctx) + + def TILDE_ANGLE(self): + return self.getToken(AsmParser.TILDE_ANGLE, 0) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitWeakLabelSuffix" ): + return visitor.visitWeakLabelSuffix(self) + else: + return visitor.visitChildren(self) + + + class GlobalLabelSuffixContext(Label_suffixContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a AsmParser.Label_suffixContext + super().__init__(parser) + self.copyFrom(ctx) + + def ANGLE_BRACKET(self): + return self.getToken(AsmParser.ANGLE_BRACKET, 0) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitGlobalLabelSuffix" ): + return visitor.visitGlobalLabelSuffix(self) + else: + return visitor.visitChildren(self) + + + class FileLabelSuffixContext(Label_suffixContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a AsmParser.Label_suffixContext + super().__init__(parser) + self.copyFrom(ctx) + + def COLON_ANGLE(self): + return self.getToken(AsmParser.COLON_ANGLE, 0) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitFileLabelSuffix" ): + return visitor.visitFileLabelSuffix(self) + else: + return visitor.visitChildren(self) + + + + def label_suffix(self): + + localctx = AsmParser.Label_suffixContext(self, self._ctx, self.state) + self.enterRule(localctx, 30, self.RULE_label_suffix) + try: + self.state = 223 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [25]: + localctx = AsmParser.LocalLabelSuffixContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 219 + self.match(AsmParser.COLON) + pass + elif token in [26]: + localctx = AsmParser.GlobalLabelSuffixContext(self, localctx) + self.enterOuterAlt(localctx, 2) + self.state = 220 + self.match(AsmParser.ANGLE_BRACKET) + pass + elif token in [27]: + localctx = AsmParser.FileLabelSuffixContext(self, localctx) + self.enterOuterAlt(localctx, 3) + self.state = 221 + self.match(AsmParser.COLON_ANGLE) + pass + elif token in [28]: + localctx = AsmParser.WeakLabelSuffixContext(self, localctx) + self.enterOuterAlt(localctx, 4) + self.state = 222 + self.match(AsmParser.TILDE_ANGLE) + pass + else: + raise NoViableAltException(self) + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class LineContext(ParserRuleContext): __slots__ = 'parser' @@ -1356,8 +1600,9 @@ def __init__(self, parser, ctx:ParserRuleContext): # actually a AsmParser.LineCo def labels_declaration(self): return self.getTypedRuleContext(AsmParser.Labels_declarationContext,0) - def Ext(self): - return self.getToken(AsmParser.Ext, 0) + def ext_type(self): + return self.getTypedRuleContext(AsmParser.Ext_typeContext,0) + def NEWLINE(self, i:int=None): if i is None: return self.getTokens(AsmParser.NEWLINE) @@ -1375,35 +1620,35 @@ def accept(self, visitor:ParseTreeVisitor): def line(self): localctx = AsmParser.LineContext(self, self._ctx, self.state) - self.enterRule(localctx, 28, self.RULE_line) + self.enterRule(localctx, 32, self.RULE_line) self._la = 0 # Token type try: - self.state = 231 + self.state = 246 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,22,self._ctx) + la_ = self._interp.adaptivePredict(self._input,24,self._ctx) if la_ == 1: localctx = AsmParser.StandaloneLabelsContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 210 + self.state = 225 self.labels_declaration() - self.state = 212 + self.state = 227 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==7: - self.state = 211 - self.match(AsmParser.Ext) + if (((_la) & ~0x3f) == 0 and ((1 << _la) & 896) != 0): + self.state = 226 + self.ext_type() - self.state = 215 + self.state = 230 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 214 + self.state = 229 self.match(AsmParser.NEWLINE) - self.state = 217 + self.state = 232 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==37): + if not (_la==40): break pass @@ -1411,34 +1656,34 @@ def line(self): elif la_ == 2: localctx = AsmParser.InstructionLineContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 220 + self.state = 235 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,19,self._ctx) + la_ = self._interp.adaptivePredict(self._input,21,self._ctx) if la_ == 1: - self.state = 219 + self.state = 234 self.labels_declaration() - self.state = 222 + self.state = 237 self.instruction() - self.state = 224 + self.state = 239 self._errHandler.sync(self) _la = self._input.LA(1) - if (((_la) & ~0x3f) == 0 and ((1 << _la) & 136908898302) != 0): - self.state = 223 + if (((_la) & ~0x3f) == 0 and ((1 << _la) & 1095243923454) != 0): + self.state = 238 self.arguments() - self.state = 227 + self.state = 242 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 226 + self.state = 241 self.match(AsmParser.NEWLINE) - self.state = 229 + self.state = 244 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==37): + if not (_la==40): break pass @@ -1464,11 +1709,9 @@ def labels(self): return self.getTypedRuleContext(AsmParser.LabelsContext,0) - def COLON(self): - return self.getToken(AsmParser.COLON, 0) + def label_suffix(self): + return self.getTypedRuleContext(AsmParser.Label_suffixContext,0) - def ANGLE_BRACKET(self): - return self.getToken(AsmParser.ANGLE_BRACKET, 0) def getRuleIndex(self): return AsmParser.RULE_labels_declaration @@ -1485,19 +1728,13 @@ def accept(self, visitor:ParseTreeVisitor): def labels_declaration(self): localctx = AsmParser.Labels_declarationContext(self, self._ctx, self.state) - self.enterRule(localctx, 30, self.RULE_labels_declaration) - self._la = 0 # Token type + self.enterRule(localctx, 34, self.RULE_labels_declaration) try: self.enterOuterAlt(localctx, 1) - self.state = 233 + self.state = 248 self.labels() - self.state = 234 - _la = self._input.LA(1) - if not(_la==23 or _la==25): - self._errHandler.recoverInline(self) - else: - self._errHandler.reportMatch(self) - self.consume() + self.state = 249 + self.label_suffix() except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -1542,21 +1779,21 @@ def accept(self, visitor:ParseTreeVisitor): def labels(self): localctx = AsmParser.LabelsContext(self, self._ctx, self.state) - self.enterRule(localctx, 32, self.RULE_labels) + self.enterRule(localctx, 36, self.RULE_labels) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 236 + self.state = 251 self.label() - self.state = 241 + self.state = 256 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==20: - self.state = 237 + while _la==22: + self.state = 252 self.match(AsmParser.COMMA) - self.state = 238 + self.state = 253 self.label() - self.state = 243 + self.state = 258 self._errHandler.sync(self) _la = self._input.LA(1) @@ -1604,21 +1841,21 @@ def accept(self, visitor:ParseTreeVisitor): def arguments(self): localctx = AsmParser.ArgumentsContext(self, self._ctx, self.state) - self.enterRule(localctx, 34, self.RULE_arguments) + self.enterRule(localctx, 38, self.RULE_arguments) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 244 + self.state = 259 self.argument() - self.state = 249 + self.state = 264 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==20: - self.state = 245 + while _la==22: + self.state = 260 self.match(AsmParser.COMMA) - self.state = 246 + self.state = 261 self.argument() - self.state = 251 + self.state = 266 self._errHandler.sync(self) _la = self._input.LA(1) @@ -1677,48 +1914,48 @@ def accept(self, visitor:ParseTreeVisitor): def conditional(self): localctx = AsmParser.ConditionalContext(self, self._ctx, self.state) - self.enterRule(localctx, 36, self.RULE_conditional) + self.enterRule(localctx, 40, self.RULE_conditional) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 252 + self.state = 267 self.match(AsmParser.If) - self.state = 254 + self.state = 269 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 253 + self.state = 268 self.match(AsmParser.NEWLINE) - self.state = 256 + self.state = 271 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==37): + if not (_la==40): break - self.state = 258 + self.state = 273 self.conditions() - self.state = 259 + self.state = 274 self.code_block() - self.state = 261 + self.state = 276 self._errHandler.sync(self) _la = self._input.LA(1) if _la==5: - self.state = 260 + self.state = 275 self.else_clause() - self.state = 263 + self.state = 278 self.match(AsmParser.Fi) - self.state = 265 + self.state = 280 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 264 + self.state = 279 self.match(AsmParser.NEWLINE) - self.state = 267 + self.state = 282 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==37): + if not (_la==40): break except RecognitionException as re: @@ -1772,51 +2009,51 @@ def accept(self, visitor:ParseTreeVisitor): def conditions(self): localctx = AsmParser.ConditionsContext(self, self._ctx, self.state) - self.enterRule(localctx, 38, self.RULE_conditions) + self.enterRule(localctx, 42, self.RULE_conditions) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 272 + self.state = 287 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,28,self._ctx) + _alt = self._interp.adaptivePredict(self._input,30,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 269 + self.state = 284 self.connective_condition() - self.state = 274 + self.state = 289 self._errHandler.sync(self) - _alt = self._interp.adaptivePredict(self._input,28,self._ctx) + _alt = self._interp.adaptivePredict(self._input,30,self._ctx) - self.state = 275 + self.state = 290 self.condition() - self.state = 277 + self.state = 292 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 276 + self.state = 291 self.match(AsmParser.NEWLINE) - self.state = 279 + self.state = 294 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==37): + if not (_la==40): break - self.state = 287 + self.state = 302 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,31,self._ctx) + la_ = self._interp.adaptivePredict(self._input,33,self._ctx) if la_ == 1: - self.state = 281 + self.state = 296 self.match(AsmParser.Then) - self.state = 283 + self.state = 298 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 282 + self.state = 297 self.match(AsmParser.NEWLINE) - self.state = 285 + self.state = 300 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==37): + if not (_la==40): break @@ -1869,26 +2106,26 @@ def accept(self, visitor:ParseTreeVisitor): def connective_condition(self): localctx = AsmParser.Connective_conditionContext(self, self._ctx, self.state) - self.enterRule(localctx, 40, self.RULE_connective_condition) + self.enterRule(localctx, 44, self.RULE_connective_condition) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 289 + self.state = 304 self.condition() - self.state = 290 + self.state = 305 self.match(AsmParser.COMMA) - self.state = 291 + self.state = 306 self.conjunction() - self.state = 293 + self.state = 308 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 292 + self.state = 307 self.match(AsmParser.NEWLINE) - self.state = 295 + self.state = 310 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==37): + if not (_la==40): break except RecognitionException as re: @@ -1933,14 +2170,14 @@ def accept(self, visitor:ParseTreeVisitor): def condition(self): localctx = AsmParser.ConditionContext(self, self._ctx, self.state) - self.enterRule(localctx, 42, self.RULE_condition) + self.enterRule(localctx, 46, self.RULE_condition) try: self.enterOuterAlt(localctx, 1) - self.state = 297 + self.state = 312 self.code_block() - self.state = 298 + self.state = 313 self.match(AsmParser.Is) - self.state = 299 + self.state = 314 self.branch_mnemonic() except RecognitionException as re: localctx.exception = re @@ -1986,25 +2223,25 @@ def accept(self, visitor:ParseTreeVisitor): def else_clause(self): localctx = AsmParser.Else_clauseContext(self, self._ctx, self.state) - self.enterRule(localctx, 44, self.RULE_else_clause) + self.enterRule(localctx, 48, self.RULE_else_clause) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 301 + self.state = 316 self.match(AsmParser.Else) - self.state = 303 + self.state = 318 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 302 + self.state = 317 self.match(AsmParser.NEWLINE) - self.state = 305 + self.state = 320 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==37): + if not (_la==40): break - self.state = 307 + self.state = 322 self.code_block() except RecognitionException as re: localctx.exception = re @@ -2040,10 +2277,10 @@ def accept(self, visitor:ParseTreeVisitor): def branch_mnemonic(self): localctx = AsmParser.Branch_mnemonicContext(self, self._ctx, self.state) - self.enterRule(localctx, 46, self.RULE_branch_mnemonic) + self.enterRule(localctx, 50, self.RULE_branch_mnemonic) try: self.enterOuterAlt(localctx, 1) - self.state = 309 + self.state = 324 self.match(AsmParser.WORD) except RecognitionException as re: localctx.exception = re @@ -2079,10 +2316,10 @@ def accept(self, visitor:ParseTreeVisitor): def conjunction(self): localctx = AsmParser.ConjunctionContext(self, self._ctx, self.state) - self.enterRule(localctx, 48, self.RULE_conjunction) + self.enterRule(localctx, 52, self.RULE_conjunction) try: self.enterOuterAlt(localctx, 1) - self.state = 311 + self.state = 326 self.match(AsmParser.WORD) except RecognitionException as re: localctx.exception = re @@ -2142,56 +2379,56 @@ def accept(self, visitor:ParseTreeVisitor): def while_loop(self): localctx = AsmParser.While_loopContext(self, self._ctx, self.state) - self.enterRule(localctx, 50, self.RULE_while_loop) + self.enterRule(localctx, 54, self.RULE_while_loop) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 313 + self.state = 328 self.match(AsmParser.While) - self.state = 315 + self.state = 330 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 314 + self.state = 329 self.match(AsmParser.NEWLINE) - self.state = 317 + self.state = 332 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==37): + if not (_la==40): break - self.state = 319 + self.state = 334 self.while_condition() - self.state = 320 + self.state = 335 self.match(AsmParser.Stays) - self.state = 321 + self.state = 336 self.branch_mnemonic() - self.state = 323 + self.state = 338 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 322 + self.state = 337 self.match(AsmParser.NEWLINE) - self.state = 325 + self.state = 340 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==37): + if not (_la==40): break - self.state = 327 + self.state = 342 self.code_block() - self.state = 328 + self.state = 343 self.match(AsmParser.Wend) - self.state = 330 + self.state = 345 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 329 + self.state = 344 self.match(AsmParser.NEWLINE) - self.state = 332 + self.state = 347 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==37): + if not (_la==40): break except RecognitionException as re: @@ -2229,10 +2466,10 @@ def accept(self, visitor:ParseTreeVisitor): def while_condition(self): localctx = AsmParser.While_conditionContext(self, self._ctx, self.state) - self.enterRule(localctx, 52, self.RULE_while_condition) + self.enterRule(localctx, 56, self.RULE_while_condition) try: self.enterOuterAlt(localctx, 1) - self.state = 334 + self.state = 349 self.code_block() except RecognitionException as re: localctx.exception = re @@ -2285,40 +2522,40 @@ def accept(self, visitor:ParseTreeVisitor): def until_loop(self): localctx = AsmParser.Until_loopContext(self, self._ctx, self.state) - self.enterRule(localctx, 54, self.RULE_until_loop) + self.enterRule(localctx, 58, self.RULE_until_loop) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 336 + self.state = 351 self.match(AsmParser.Do) - self.state = 338 + self.state = 353 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 337 + self.state = 352 self.match(AsmParser.NEWLINE) - self.state = 340 + self.state = 355 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==37): + if not (_la==40): break - self.state = 342 + self.state = 357 self.code_block() - self.state = 343 + self.state = 358 self.match(AsmParser.Until) - self.state = 344 + self.state = 359 self.branch_mnemonic() - self.state = 346 + self.state = 361 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 345 + self.state = 360 self.match(AsmParser.NEWLINE) - self.state = 348 + self.state = 363 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==37): + if not (_la==40): break except RecognitionException as re: @@ -2372,38 +2609,38 @@ def accept(self, visitor:ParseTreeVisitor): def argument(self): localctx = AsmParser.ArgumentContext(self, self._ctx, self.state) - self.enterRule(localctx, 56, self.RULE_argument) + self.enterRule(localctx, 60, self.RULE_argument) try: - self.state = 355 + self.state = 370 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input,39,self._ctx) + la_ = self._interp.adaptivePredict(self._input,41,self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 350 + self.state = 365 self.character() pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 351 + self.state = 366 self.string() pass elif la_ == 3: self.enterOuterAlt(localctx, 3) - self.state = 352 + self.state = 367 self.register() pass elif la_ == 4: self.enterOuterAlt(localctx, 4) - self.state = 353 + self.state = 368 self.addr_expr() pass elif la_ == 5: self.enterOuterAlt(localctx, 5) - self.state = 354 + self.state = 369 self.byte_expr() pass @@ -2453,16 +2690,16 @@ def accept(self, visitor:ParseTreeVisitor): def byte_expr(self): localctx = AsmParser.Byte_exprContext(self, self._ctx, self.state) - self.enterRule(localctx, 58, self.RULE_byte_expr) + self.enterRule(localctx, 62, self.RULE_byte_expr) try: self.enterOuterAlt(localctx, 1) - self.state = 357 + self.state = 372 self.byte_specifier() - self.state = 358 + self.state = 373 self.match(AsmParser.OPEN_PAREN) - self.state = 359 + self.state = 374 self.addr_expr() - self.state = 360 + self.state = 375 self.match(AsmParser.CLOSE_PAREN) except RecognitionException as re: localctx.exception = re @@ -2506,19 +2743,19 @@ def accept(self, visitor:ParseTreeVisitor): def addr_expr(self): localctx = AsmParser.Addr_exprContext(self, self._ctx, self.state) - self.enterRule(localctx, 60, self.RULE_addr_expr) + self.enterRule(localctx, 64, self.RULE_addr_expr) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 362 + self.state = 377 self.first_term() - self.state = 366 + self.state = 381 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==21 or _la==22: - self.state = 363 + while _la==23 or _la==24: + self.state = 378 self.add_term() - self.state = 368 + self.state = 383 self._errHandler.sync(self) _la = self._input.LA(1) @@ -2563,24 +2800,24 @@ def accept(self, visitor:ParseTreeVisitor): def first_term(self): localctx = AsmParser.First_termContext(self, self._ctx, self.state) - self.enterRule(localctx, 62, self.RULE_first_term) + self.enterRule(localctx, 66, self.RULE_first_term) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 370 + self.state = 385 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==21 or _la==22: - self.state = 369 + if _la==23 or _la==24: + self.state = 384 _la = self._input.LA(1) - if not(_la==21 or _la==22): + if not(_la==23 or _la==24): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) self.consume() - self.state = 372 + self.state = 387 self.term() except RecognitionException as re: localctx.exception = re @@ -2623,18 +2860,18 @@ def accept(self, visitor:ParseTreeVisitor): def add_term(self): localctx = AsmParser.Add_termContext(self, self._ctx, self.state) - self.enterRule(localctx, 64, self.RULE_add_term) + self.enterRule(localctx, 68, self.RULE_add_term) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 374 + self.state = 389 _la = self._input.LA(1) - if not(_la==21 or _la==22): + if not(_la==23 or _la==24): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) self.consume() - self.state = 375 + self.state = 390 self.term() except RecognitionException as re: localctx.exception = re @@ -2675,19 +2912,19 @@ def accept(self, visitor:ParseTreeVisitor): def term(self): localctx = AsmParser.TermContext(self, self._ctx, self.state) - self.enterRule(localctx, 66, self.RULE_term) + self.enterRule(localctx, 70, self.RULE_term) try: - self.state = 379 + self.state = 394 self._errHandler.sync(self) token = self._input.LA(1) - if token in [32, 33, 34]: + if token in [35, 36, 37]: self.enterOuterAlt(localctx, 1) - self.state = 377 + self.state = 392 self.number() pass - elif token in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 30, 31]: + elif token in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 33, 34]: self.enterOuterAlt(localctx, 2) - self.state = 378 + self.state = 393 self.label() pass else: @@ -2728,10 +2965,10 @@ def accept(self, visitor:ParseTreeVisitor): def byte_specifier(self): localctx = AsmParser.Byte_specifierContext(self, self._ctx, self.state) - self.enterRule(localctx, 68, self.RULE_byte_specifier) + self.enterRule(localctx, 72, self.RULE_byte_specifier) try: self.enterOuterAlt(localctx, 1) - self.state = 381 + self.state = 396 self.name() except RecognitionException as re: localctx.exception = re @@ -2768,10 +3005,10 @@ def accept(self, visitor:ParseTreeVisitor): def label(self): localctx = AsmParser.LabelContext(self, self._ctx, self.state) - self.enterRule(localctx, 70, self.RULE_label) + self.enterRule(localctx, 74, self.RULE_label) try: self.enterOuterAlt(localctx, 1) - self.state = 383 + self.state = 398 self.name() except RecognitionException as re: localctx.exception = re @@ -2807,10 +3044,10 @@ def accept(self, visitor:ParseTreeVisitor): def instruction(self): localctx = AsmParser.InstructionContext(self, self._ctx, self.state) - self.enterRule(localctx, 72, self.RULE_instruction) + self.enterRule(localctx, 76, self.RULE_instruction) try: self.enterOuterAlt(localctx, 1) - self.state = 385 + self.state = 400 self.match(AsmParser.WORD) except RecognitionException as re: localctx.exception = re @@ -2846,10 +3083,10 @@ def accept(self, visitor:ParseTreeVisitor): def string(self): localctx = AsmParser.StringContext(self, self._ctx, self.state) - self.enterRule(localctx, 74, self.RULE_string) + self.enterRule(localctx, 78, self.RULE_string) try: self.enterOuterAlt(localctx, 1) - self.state = 387 + self.state = 402 self.match(AsmParser.STRING) except RecognitionException as re: localctx.exception = re @@ -2885,10 +3122,10 @@ def accept(self, visitor:ParseTreeVisitor): def register(self): localctx = AsmParser.RegisterContext(self, self._ctx, self.state) - self.enterRule(localctx, 76, self.RULE_register) + self.enterRule(localctx, 80, self.RULE_register) try: self.enterOuterAlt(localctx, 1) - self.state = 389 + self.state = 404 self.match(AsmParser.REGISTER) except RecognitionException as re: localctx.exception = re @@ -2924,10 +3161,10 @@ def accept(self, visitor:ParseTreeVisitor): def character(self): localctx = AsmParser.CharacterContext(self, self._ctx, self.state) - self.enterRule(localctx, 78, self.RULE_character) + self.enterRule(localctx, 82, self.RULE_character) try: self.enterOuterAlt(localctx, 1) - self.state = 391 + self.state = 406 self.match(AsmParser.CHAR) except RecognitionException as re: localctx.exception = re @@ -2969,13 +3206,13 @@ def accept(self, visitor:ParseTreeVisitor): def number(self): localctx = AsmParser.NumberContext(self, self._ctx, self.state) - self.enterRule(localctx, 80, self.RULE_number) + self.enterRule(localctx, 84, self.RULE_number) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 393 + self.state = 408 _la = self._input.LA(1) - if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 30064771072) != 0)): + if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 240518168576) != 0)): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) @@ -3017,6 +3254,12 @@ def End(self): def Ext(self): return self.getToken(AsmParser.Ext, 0) + def File(self): + return self.getToken(AsmParser.File, 0) + + def Weak(self): + return self.getToken(AsmParser.Weak, 0) + def Fi(self): return self.getToken(AsmParser.Fi, 0) @@ -3071,13 +3314,13 @@ def accept(self, visitor:ParseTreeVisitor): def name(self): localctx = AsmParser.NameContext(self, self._ctx, self.state) - self.enterRule(localctx, 82, self.RULE_name) + self.enterRule(localctx, 86, self.RULE_name) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 395 + self.state = 410 _la = self._input.LA(1) - if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 3221749758) != 0)): + if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 25771900926) != 0)): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) diff --git a/cocas/assembler/generated/AsmParserVisitor.py b/cocas/assembler/generated/AsmParserVisitor.py index 07593466..37dfe73a 100644 --- a/cocas/assembler/generated/AsmParserVisitor.py +++ b/cocas/assembler/generated/AsmParserVisitor.py @@ -1,4 +1,4 @@ -# Generated from assembler/grammar/AsmParser.g4 by ANTLR 4.13.1 +# Generated from assembler/grammar/AsmParser.g4 by ANTLR 4.13.2 from antlr4 import * if "." in __name__: from .AsmParser import AsmParser @@ -92,6 +92,41 @@ def visitTop_line(self, ctx:AsmParser.Top_lineContext): return self.visitChildren(ctx) + # Visit a parse tree produced by AsmParser#globalExtType. + def visitGlobalExtType(self, ctx:AsmParser.GlobalExtTypeContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by AsmParser#fileExtType. + def visitFileExtType(self, ctx:AsmParser.FileExtTypeContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by AsmParser#weakExtType. + def visitWeakExtType(self, ctx:AsmParser.WeakExtTypeContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by AsmParser#localLabelSuffix. + def visitLocalLabelSuffix(self, ctx:AsmParser.LocalLabelSuffixContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by AsmParser#globalLabelSuffix. + def visitGlobalLabelSuffix(self, ctx:AsmParser.GlobalLabelSuffixContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by AsmParser#fileLabelSuffix. + def visitFileLabelSuffix(self, ctx:AsmParser.FileLabelSuffixContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by AsmParser#weakLabelSuffix. + def visitWeakLabelSuffix(self, ctx:AsmParser.WeakLabelSuffixContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by AsmParser#standaloneLabels. def visitStandaloneLabels(self, ctx:AsmParser.StandaloneLabelsContext): return self.visitChildren(ctx) diff --git a/cocas/assembler/generated/MacroLexer.py b/cocas/assembler/generated/MacroLexer.py index 7e54d46e..6a773f31 100644 --- a/cocas/assembler/generated/MacroLexer.py +++ b/cocas/assembler/generated/MacroLexer.py @@ -1,4 +1,4 @@ -# Generated from assembler/grammar/Macro.g4 by ANTLR 4.13.1 +# Generated from assembler/grammar/Macro.g4 by ANTLR 4.13.2 from antlr4 import * from io import StringIO import sys @@ -10,57 +10,60 @@ def serializedATN(): return [ - 4,0,17,140,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5, + 4,0,17,145,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5, 2,6,7,6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2, 13,7,13,2,14,7,14,2,15,7,15,2,16,7,16,1,0,1,0,1,0,1,0,1,0,1,0,1, 1,5,1,43,8,1,10,1,12,1,46,9,1,1,1,1,1,1,1,1,1,1,1,1,1,5,1,54,8,1, 10,1,12,1,57,9,1,1,1,3,1,60,8,1,1,1,1,1,1,2,4,2,65,8,2,11,2,12,2, 66,1,3,3,3,70,8,3,1,3,1,3,1,4,1,4,5,4,76,8,4,10,4,12,4,79,9,4,1, - 4,1,4,1,5,1,5,1,6,1,6,1,7,1,7,1,8,1,8,1,9,1,9,4,9,93,8,9,11,9,12, - 9,94,1,9,1,9,5,9,99,8,9,10,9,12,9,102,9,9,1,9,1,9,1,10,1,10,4,10, - 108,8,10,11,10,12,10,109,1,10,1,10,5,10,114,8,10,10,10,12,10,117, - 9,10,1,10,1,10,1,11,1,11,5,11,123,8,11,10,11,12,11,126,9,11,1,12, - 1,12,1,13,1,13,1,14,1,14,1,15,1,15,1,16,4,16,137,8,16,11,16,12,16, - 138,0,0,17,1,1,3,2,5,3,7,4,9,5,11,6,13,7,15,8,17,9,19,10,21,11,23, - 12,25,13,27,14,29,15,31,16,33,17,1,0,9,2,0,9,9,32,32,1,0,10,10,2, - 0,58,58,62,62,3,0,10,10,34,34,92,92,3,0,10,10,39,39,92,92,3,0,65, - 90,95,95,97,122,5,0,46,46,48,57,65,90,95,95,97,122,1,0,48,57,3,0, - 40,41,43,43,45,45,153,0,1,1,0,0,0,0,3,1,0,0,0,0,5,1,0,0,0,0,7,1, - 0,0,0,0,9,1,0,0,0,0,11,1,0,0,0,0,13,1,0,0,0,0,15,1,0,0,0,0,17,1, - 0,0,0,0,19,1,0,0,0,0,21,1,0,0,0,0,23,1,0,0,0,0,25,1,0,0,0,0,27,1, - 0,0,0,0,29,1,0,0,0,0,31,1,0,0,0,0,33,1,0,0,0,1,35,1,0,0,0,3,44,1, - 0,0,0,5,64,1,0,0,0,7,69,1,0,0,0,9,73,1,0,0,0,11,82,1,0,0,0,13,84, - 1,0,0,0,15,86,1,0,0,0,17,88,1,0,0,0,19,90,1,0,0,0,21,105,1,0,0,0, - 23,120,1,0,0,0,25,127,1,0,0,0,27,129,1,0,0,0,29,131,1,0,0,0,31,133, - 1,0,0,0,33,136,1,0,0,0,35,36,5,109,0,0,36,37,5,97,0,0,37,38,5,99, - 0,0,38,39,5,114,0,0,39,40,5,111,0,0,40,2,1,0,0,0,41,43,7,0,0,0,42, - 41,1,0,0,0,43,46,1,0,0,0,44,42,1,0,0,0,44,45,1,0,0,0,45,47,1,0,0, - 0,46,44,1,0,0,0,47,48,5,109,0,0,48,49,5,101,0,0,49,50,5,110,0,0, - 50,51,5,100,0,0,51,55,1,0,0,0,52,54,7,0,0,0,53,52,1,0,0,0,54,57, - 1,0,0,0,55,53,1,0,0,0,55,56,1,0,0,0,56,59,1,0,0,0,57,55,1,0,0,0, - 58,60,5,13,0,0,59,58,1,0,0,0,59,60,1,0,0,0,60,61,1,0,0,0,61,62,5, - 10,0,0,62,4,1,0,0,0,63,65,7,0,0,0,64,63,1,0,0,0,65,66,1,0,0,0,66, - 64,1,0,0,0,66,67,1,0,0,0,67,6,1,0,0,0,68,70,5,13,0,0,69,68,1,0,0, - 0,69,70,1,0,0,0,70,71,1,0,0,0,71,72,5,10,0,0,72,8,1,0,0,0,73,77, - 5,35,0,0,74,76,8,1,0,0,75,74,1,0,0,0,76,79,1,0,0,0,77,75,1,0,0,0, - 77,78,1,0,0,0,78,80,1,0,0,0,79,77,1,0,0,0,80,81,6,4,0,0,81,10,1, - 0,0,0,82,83,5,42,0,0,83,12,1,0,0,0,84,85,5,44,0,0,85,14,1,0,0,0, - 86,87,7,2,0,0,87,16,1,0,0,0,88,89,5,63,0,0,89,18,1,0,0,0,90,100, - 5,34,0,0,91,93,8,3,0,0,92,91,1,0,0,0,93,94,1,0,0,0,94,92,1,0,0,0, - 94,95,1,0,0,0,95,99,1,0,0,0,96,97,5,92,0,0,97,99,9,0,0,0,98,92,1, - 0,0,0,98,96,1,0,0,0,99,102,1,0,0,0,100,98,1,0,0,0,100,101,1,0,0, - 0,101,103,1,0,0,0,102,100,1,0,0,0,103,104,5,34,0,0,104,20,1,0,0, - 0,105,115,5,39,0,0,106,108,8,4,0,0,107,106,1,0,0,0,108,109,1,0,0, - 0,109,107,1,0,0,0,109,110,1,0,0,0,110,114,1,0,0,0,111,112,5,92,0, - 0,112,114,9,0,0,0,113,107,1,0,0,0,113,111,1,0,0,0,114,117,1,0,0, - 0,115,113,1,0,0,0,115,116,1,0,0,0,116,118,1,0,0,0,117,115,1,0,0, - 0,118,119,5,39,0,0,119,22,1,0,0,0,120,124,7,5,0,0,121,123,7,6,0, - 0,122,121,1,0,0,0,123,126,1,0,0,0,124,122,1,0,0,0,124,125,1,0,0, - 0,125,24,1,0,0,0,126,124,1,0,0,0,127,128,7,7,0,0,128,26,1,0,0,0, - 129,130,5,47,0,0,130,28,1,0,0,0,131,132,5,39,0,0,132,30,1,0,0,0, - 133,134,5,36,0,0,134,32,1,0,0,0,135,137,7,8,0,0,136,135,1,0,0,0, - 137,138,1,0,0,0,138,136,1,0,0,0,138,139,1,0,0,0,139,34,1,0,0,0,15, - 0,44,55,59,66,69,77,94,98,100,109,113,115,124,138,1,6,0,0 + 4,1,4,1,5,1,5,1,6,1,6,1,7,1,7,1,7,1,7,1,7,3,7,92,8,7,1,8,1,8,1,9, + 1,9,4,9,98,8,9,11,9,12,9,99,1,9,1,9,5,9,104,8,9,10,9,12,9,107,9, + 9,1,9,1,9,1,10,1,10,4,10,113,8,10,11,10,12,10,114,1,10,1,10,5,10, + 119,8,10,10,10,12,10,122,9,10,1,10,1,10,1,11,1,11,5,11,128,8,11, + 10,11,12,11,131,9,11,1,12,1,12,1,13,1,13,1,14,1,14,1,15,1,15,1,16, + 4,16,142,8,16,11,16,12,16,143,0,0,17,1,1,3,2,5,3,7,4,9,5,11,6,13, + 7,15,8,17,9,19,10,21,11,23,12,25,13,27,14,29,15,31,16,33,17,1,0, + 9,2,0,9,9,32,32,1,0,10,10,2,0,58,58,62,62,3,0,10,10,34,34,92,92, + 3,0,10,10,39,39,92,92,3,0,65,90,95,95,97,122,5,0,46,46,48,57,65, + 90,95,95,97,122,1,0,48,57,3,0,40,41,43,43,45,45,160,0,1,1,0,0,0, + 0,3,1,0,0,0,0,5,1,0,0,0,0,7,1,0,0,0,0,9,1,0,0,0,0,11,1,0,0,0,0,13, + 1,0,0,0,0,15,1,0,0,0,0,17,1,0,0,0,0,19,1,0,0,0,0,21,1,0,0,0,0,23, + 1,0,0,0,0,25,1,0,0,0,0,27,1,0,0,0,0,29,1,0,0,0,0,31,1,0,0,0,0,33, + 1,0,0,0,1,35,1,0,0,0,3,44,1,0,0,0,5,64,1,0,0,0,7,69,1,0,0,0,9,73, + 1,0,0,0,11,82,1,0,0,0,13,84,1,0,0,0,15,91,1,0,0,0,17,93,1,0,0,0, + 19,95,1,0,0,0,21,110,1,0,0,0,23,125,1,0,0,0,25,132,1,0,0,0,27,134, + 1,0,0,0,29,136,1,0,0,0,31,138,1,0,0,0,33,141,1,0,0,0,35,36,5,109, + 0,0,36,37,5,97,0,0,37,38,5,99,0,0,38,39,5,114,0,0,39,40,5,111,0, + 0,40,2,1,0,0,0,41,43,7,0,0,0,42,41,1,0,0,0,43,46,1,0,0,0,44,42,1, + 0,0,0,44,45,1,0,0,0,45,47,1,0,0,0,46,44,1,0,0,0,47,48,5,109,0,0, + 48,49,5,101,0,0,49,50,5,110,0,0,50,51,5,100,0,0,51,55,1,0,0,0,52, + 54,7,0,0,0,53,52,1,0,0,0,54,57,1,0,0,0,55,53,1,0,0,0,55,56,1,0,0, + 0,56,59,1,0,0,0,57,55,1,0,0,0,58,60,5,13,0,0,59,58,1,0,0,0,59,60, + 1,0,0,0,60,61,1,0,0,0,61,62,5,10,0,0,62,4,1,0,0,0,63,65,7,0,0,0, + 64,63,1,0,0,0,65,66,1,0,0,0,66,64,1,0,0,0,66,67,1,0,0,0,67,6,1,0, + 0,0,68,70,5,13,0,0,69,68,1,0,0,0,69,70,1,0,0,0,70,71,1,0,0,0,71, + 72,5,10,0,0,72,8,1,0,0,0,73,77,5,35,0,0,74,76,8,1,0,0,75,74,1,0, + 0,0,76,79,1,0,0,0,77,75,1,0,0,0,77,78,1,0,0,0,78,80,1,0,0,0,79,77, + 1,0,0,0,80,81,6,4,0,0,81,10,1,0,0,0,82,83,5,42,0,0,83,12,1,0,0,0, + 84,85,5,44,0,0,85,14,1,0,0,0,86,92,7,2,0,0,87,88,5,58,0,0,88,92, + 5,62,0,0,89,90,5,126,0,0,90,92,5,62,0,0,91,86,1,0,0,0,91,87,1,0, + 0,0,91,89,1,0,0,0,92,16,1,0,0,0,93,94,5,63,0,0,94,18,1,0,0,0,95, + 105,5,34,0,0,96,98,8,3,0,0,97,96,1,0,0,0,98,99,1,0,0,0,99,97,1,0, + 0,0,99,100,1,0,0,0,100,104,1,0,0,0,101,102,5,92,0,0,102,104,9,0, + 0,0,103,97,1,0,0,0,103,101,1,0,0,0,104,107,1,0,0,0,105,103,1,0,0, + 0,105,106,1,0,0,0,106,108,1,0,0,0,107,105,1,0,0,0,108,109,5,34,0, + 0,109,20,1,0,0,0,110,120,5,39,0,0,111,113,8,4,0,0,112,111,1,0,0, + 0,113,114,1,0,0,0,114,112,1,0,0,0,114,115,1,0,0,0,115,119,1,0,0, + 0,116,117,5,92,0,0,117,119,9,0,0,0,118,112,1,0,0,0,118,116,1,0,0, + 0,119,122,1,0,0,0,120,118,1,0,0,0,120,121,1,0,0,0,121,123,1,0,0, + 0,122,120,1,0,0,0,123,124,5,39,0,0,124,22,1,0,0,0,125,129,7,5,0, + 0,126,128,7,6,0,0,127,126,1,0,0,0,128,131,1,0,0,0,129,127,1,0,0, + 0,129,130,1,0,0,0,130,24,1,0,0,0,131,129,1,0,0,0,132,133,7,7,0,0, + 133,26,1,0,0,0,134,135,5,47,0,0,135,28,1,0,0,0,136,137,5,39,0,0, + 137,30,1,0,0,0,138,139,5,36,0,0,139,32,1,0,0,0,140,142,7,8,0,0,141, + 140,1,0,0,0,142,143,1,0,0,0,143,141,1,0,0,0,143,144,1,0,0,0,144, + 34,1,0,0,0,16,0,44,55,59,66,69,77,91,99,103,105,114,118,120,129, + 143,1,6,0,0 ] class MacroLexer(Lexer): @@ -108,7 +111,7 @@ class MacroLexer(Lexer): def __init__(self, input=None, output:TextIO = sys.stdout): super().__init__(input, output) - self.checkVersion("4.13.1") + self.checkVersion("4.13.2") self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache()) self._actions = None self._predicates = None diff --git a/cocas/assembler/generated/MacroParser.py b/cocas/assembler/generated/MacroParser.py index 5a8ee2dc..bad410cc 100644 --- a/cocas/assembler/generated/MacroParser.py +++ b/cocas/assembler/generated/MacroParser.py @@ -1,4 +1,4 @@ -# Generated from assembler/grammar/Macro.g4 by ANTLR 4.13.1 +# Generated from assembler/grammar/Macro.g4 by ANTLR 4.13.2 # encoding: utf-8 from antlr4 import * from io import StringIO @@ -167,7 +167,7 @@ class MacroParser ( Parser ): def __init__(self, input:TokenStream, output:TextIO = sys.stdout): super().__init__(input, output) - self.checkVersion("4.13.1") + self.checkVersion("4.13.2") self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache) self._predicates = None diff --git a/cocas/assembler/generated/MacroVisitor.py b/cocas/assembler/generated/MacroVisitor.py index e9143ab5..409171e5 100644 --- a/cocas/assembler/generated/MacroVisitor.py +++ b/cocas/assembler/generated/MacroVisitor.py @@ -1,4 +1,4 @@ -# Generated from assembler/grammar/Macro.g4 by ANTLR 4.13.1 +# Generated from assembler/grammar/Macro.g4 by ANTLR 4.13.2 from antlr4 import * if "." in __name__: from .MacroParser import MacroParser diff --git a/cocas/assembler/grammar/AsmLexer.g4 b/cocas/assembler/grammar/AsmLexer.g4 index 75026512..1f33677b 100644 --- a/cocas/assembler/grammar/AsmLexer.g4 +++ b/cocas/assembler/grammar/AsmLexer.g4 @@ -7,6 +7,8 @@ Do : 'do' ; Else : 'else' ; End : 'end' ; Ext : 'ext' ; +File : 'file' ; +Weak : 'weak' ; Fi : 'fi' ; If : 'if' ; Is : 'is' ; @@ -24,8 +26,9 @@ COMMA : ',' ; PLUS : '+' ; MINUS : '-' ; COLON : ':' ; -ASTERISK : '*' ; ANGLE_BRACKET : '>' ; +COLON_ANGLE : ':>' ; +TILDE_ANGLE : '~>' ; OPEN_PAREN : '(' ; CLOSE_PAREN : ')' ; LINE_MARK_MARKER: '-|'; diff --git a/cocas/assembler/grammar/AsmParser.g4 b/cocas/assembler/grammar/AsmParser.g4 index b70df4a8..09ca3ce0 100644 --- a/cocas/assembler/grammar/AsmParser.g4 +++ b/cocas/assembler/grammar/AsmParser.g4 @@ -58,12 +58,25 @@ continue_statement : Continue NEWLINE+ ; top_line: line; +ext_type + : Ext # globalExtType + | File # fileExtType + | Weak # weakExtType + ; + +label_suffix + : COLON # localLabelSuffix + | ANGLE_BRACKET # globalLabelSuffix + | COLON_ANGLE # fileLabelSuffix + | TILDE_ANGLE # weakLabelSuffix + ; + line - : labels_declaration Ext? NEWLINE+ # standaloneLabels + : labels_declaration ext_type? NEWLINE+ # standaloneLabels | labels_declaration? instruction arguments? NEWLINE+ # instructionLine ; -labels_declaration: labels (COLON | ANGLE_BRACKET) ; +labels_declaration: labels label_suffix ; labels: label (COMMA label)*; arguments : argument (COMMA argument)* ; @@ -115,6 +128,8 @@ name | Else | End | Ext + | File + | Weak | Fi | If | Is diff --git a/cocas/assembler/grammar/Macro.g4 b/cocas/assembler/grammar/Macro.g4 index 1d5dfbb9..d1ceada2 100644 --- a/cocas/assembler/grammar/Macro.g4 +++ b/cocas/assembler/grammar/Macro.g4 @@ -34,7 +34,7 @@ COMMENT : '#'~[\n]* -> skip ; ASTERISK : '*' ; COMMA : ',' ; -LABEL_END : [:>] ; +LABEL_END : ':' | '>' | ':>' | '~>' ; QUESTION_MARK : '?' ; STRING: '"' (~[\\"\n]+ | '\\' .)* '"' ; CHAR : '\'' (~[\\'\n]+ | '\\' .)* '\'' ; diff --git a/cocas/assembler/object_generator.py b/cocas/assembler/object_generator.py index caf89cc7..a8e44f2f 100644 --- a/cocas/assembler/object_generator.py +++ b/cocas/assembler/object_generator.py @@ -36,7 +36,7 @@ def __init__(self, sn: TemplateSectionNode, target_instructions: TargetInstructi if line.external: raise AssemblerException(AssemblerExceptionTag.TPLATE, line.location.file, line.location.line, 'External labels not allowed in templates') - elif line.entry: + elif line.linkage: raise AssemblerException(AssemblerExceptionTag.TPLATE, line.location.file, line.location.line, 'Ents not allowed in templates') else: @@ -129,7 +129,7 @@ def generate_object_module(pn: ProgramNode, target_instructions: TargetInstructi asects = [Section(asect, target_instructions) for asect in pn.absolute_sections] rsects = [Section(rsect, target_instructions) for rsect in pn.relocatable_sections] - shared_externals = set(map(lambda x: x.name, pn.shared_externals)) + shared_externals = dict(map(lambda x: (x.label.name, x.linkage), pn.shared_externals)) for i in itertools.chain(asects, rsects): i.exts |= shared_externals asects.sort(key=lambda s: s.address) diff --git a/cocas/object_file/generated/ObjectFileLexer.py b/cocas/object_file/generated/ObjectFileLexer.py index 382a278b..cb9fa11e 100644 --- a/cocas/object_file/generated/ObjectFileLexer.py +++ b/cocas/object_file/generated/ObjectFileLexer.py @@ -1,4 +1,4 @@ -# Generated from object_file/grammar/ObjectFileLexer.g4 by ANTLR 4.13.1 +# Generated from object_file/grammar/ObjectFileLexer.g4 by ANTLR 4.13.2 from antlr4 import * from io import StringIO import sys @@ -148,7 +148,7 @@ class ObjectFileLexer(Lexer): def __init__(self, input=None, output:TextIO = sys.stdout): super().__init__(input, output) - self.checkVersion("4.13.1") + self.checkVersion("4.13.2") self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache()) self._actions = None self._predicates = None diff --git a/cocas/object_file/generated/ObjectFileParser.py b/cocas/object_file/generated/ObjectFileParser.py index 06e85b04..e64c2078 100644 --- a/cocas/object_file/generated/ObjectFileParser.py +++ b/cocas/object_file/generated/ObjectFileParser.py @@ -1,4 +1,4 @@ -# Generated from object_file/grammar/ObjectFileParser.g4 by ANTLR 4.13.1 +# Generated from object_file/grammar/ObjectFileParser.g4 by ANTLR 4.13.2 # encoding: utf-8 from antlr4 import * from io import StringIO @@ -175,7 +175,7 @@ class ObjectFileParser ( Parser ): def __init__(self, input:TokenStream, output:TextIO = sys.stdout): super().__init__(input, output) - self.checkVersion("4.13.1") + self.checkVersion("4.13.2") self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache) self._predicates = None diff --git a/cocas/object_file/generated/ObjectFileParserVisitor.py b/cocas/object_file/generated/ObjectFileParserVisitor.py index 615aefb0..f88dddd7 100644 --- a/cocas/object_file/generated/ObjectFileParserVisitor.py +++ b/cocas/object_file/generated/ObjectFileParserVisitor.py @@ -1,4 +1,4 @@ -# Generated from object_file/grammar/ObjectFileParser.g4 by ANTLR 4.13.1 +# Generated from object_file/grammar/ObjectFileParser.g4 by ANTLR 4.13.2 from antlr4 import * if "." in __name__: from .ObjectFileParser import ObjectFileParser diff --git a/cocas/object_module/__init__.py b/cocas/object_module/__init__.py index 035dce12..4b3862cf 100644 --- a/cocas/object_module/__init__.py +++ b/cocas/object_module/__init__.py @@ -4,3 +4,4 @@ from .external_entry import ExternalEntry from .location import CodeLocation from .object_module import ObjectModule, ObjectSectionRecord +from .linkage import Linkage diff --git a/cocas/object_module/linkage.py b/cocas/object_module/linkage.py new file mode 100644 index 00000000..988abdbe --- /dev/null +++ b/cocas/object_module/linkage.py @@ -0,0 +1,6 @@ +from enum import Enum + +class Linkage(Enum): + FILE_LOCAL = 1 + GLOBAL = 2 + WEAK_GLOBAL = 3 From 074a96638fba32af7625ca7f88186749ea655341 Mon Sep 17 00:00:00 2001 From: reVInotip Date: Tue, 27 Jan 2026 22:40:16 +0700 Subject: [PATCH 02/42] [cocas] Added support for outputting attributes in a symbol declaration (NTRY command) in accordance with the specification --- cocas/assembler/code_block.py | 7 ++++- cocas/linker/linker.py | 2 +- cocas/object_file/object_export.py | 16 +++++++----- cocas/object_module/attributes.py | 16 ++++++++++++ cocas/object_module/entry.py | 31 +++++++++++++++++++++++ cocas/object_module/external_entry.py | 4 +++ cocas/object_module/external_entry_key.py | 30 ++++++++++++++++++++++ cocas/object_module/object_module.py | 5 ++-- 8 files changed, 100 insertions(+), 11 deletions(-) create mode 100644 cocas/object_module/attributes.py create mode 100644 cocas/object_module/entry.py create mode 100644 cocas/object_module/external_entry_key.py diff --git a/cocas/assembler/code_block.py b/cocas/assembler/code_block.py index 293629c0..0f525c40 100644 --- a/cocas/assembler/code_block.py +++ b/cocas/assembler/code_block.py @@ -19,6 +19,7 @@ ) from .exceptions import AssemblerException, AssemblerExceptionTag, CdmTempException from .targets import ICodeSegment, TargetInstructions +from ..object_module.entry import Entry @dataclass @@ -179,7 +180,11 @@ def __init__(self, sn: SectionNode, target_instructions: TargetInstructions): super().__init__(address, sn.lines, target_instructions) def to_object_section_record(self, labels: dict[str, int], templates: dict[str, dict[str, int]]): - entries = dict(p for p in self.labels.items() if p[0] in self.ents) + entries = { + key: Entry(label, self.ents[key]) + for key, label in self.labels.items() + if key in self.ents + } out = ObjectSectionRecord(self.name, self.address, bytearray(), entries, [], self.code_locations) for seg in self.segments: seg.fill(out, self, labels, templates) diff --git a/cocas/linker/linker.py b/cocas/linker/linker.py index 55043be8..c32074c5 100644 --- a/cocas/linker/linker.py +++ b/cocas/linker/linker.py @@ -60,7 +60,7 @@ def gather_ents(sects: list[ObjectSectionRecord], sect_addresses: dict[str, int] for ent_name in sect.entries: if ent_name in ents: raise LinkerException(f'Duplicate entries "{ent_name}"') - ents[ent_name] = sect.entries[ent_name] + sect_addresses[sect.name] + ents[ent_name] = sect.entries[ent_name].address + sect_addresses[sect.name] return ents diff --git a/cocas/object_file/object_export.py b/cocas/object_file/object_export.py index 77760011..00d8cdb9 100644 --- a/cocas/object_file/object_export.py +++ b/cocas/object_file/object_export.py @@ -70,8 +70,8 @@ def export_object(objs: list[ObjectModule], target: str, debug: bool) -> list[st if debug: result += export_code_locations(asect.code_locations) for asect in obj.asects: - for label, address in asect.entries.items(): - result.append(f'NTRY {label} {address:02x}\n') + for label, entry in asect.entries.items(): + result.append(f'NTRY {label} {entry}\n') for rsect in obj.rsects: result.append(f'NAME {rsect.name}\n') if rsect.alignment != target_params.default_alignment: @@ -81,15 +81,17 @@ def export_object(objs: list[ObjectModule], target: str, debug: bool) -> list[st if debug: result += export_code_locations(rsect.code_locations) result.append(f'REL {" ".join(map(str, rsect.relocatable))}\n') - for label, address in rsect.entries.items(): - result.append(f'NTRY {label} {address:02x}\n') + for label, entry in rsect.entries.items(): + result.append(f'NTRY {label} {entry}\n') external = defaultdict(list) for sect in (obj.asects if asects_exist else []) + obj.rsects: for label, entries in sect.external.items(): for entry in entries: - external[label].append((sect.name, entry)) - for label, entries in external.items(): - result.append(f'XTRN {label}: {" ".join(map(sect_entry_to_str, entries))}\n') + # I'm not sure that attributes should be included in the grouping + label_with_attrs = f"{label}{entry.get_attrs_str()}" + external[label_with_attrs].append((sect.name, entry)) + for label_with_attrs, entries in external.items(): + result.append(f'XTRN {label_with_attrs}: {" ".join(map(sect_entry_to_str, entries))}\n') pass return result diff --git a/cocas/object_module/attributes.py b/cocas/object_module/attributes.py new file mode 100644 index 00000000..b0f339c7 --- /dev/null +++ b/cocas/object_module/attributes.py @@ -0,0 +1,16 @@ +from enum import Enum + +class Attributes(Enum): + LOCAL = 1, + WEAK = 2 + + def __str__(self): + match self: + case Attributes.LOCAL: + return "LOCAL" + case Attributes.WEAK: + return "WEAK" + case _: + pass # do something + + \ No newline at end of file diff --git a/cocas/object_module/entry.py b/cocas/object_module/entry.py new file mode 100644 index 00000000..c48b7bd4 --- /dev/null +++ b/cocas/object_module/entry.py @@ -0,0 +1,31 @@ +from dataclasses import dataclass + +from .attributes import Attributes +from .linkage import Linkage + +@dataclass +class Entry: + def __init__(self, address: int, linkage: Linkage): + self.address: int = address + self.attrs: list(Attributes) = list() + match linkage: + case Linkage.FILE_LOCAL: + self.attrs.append(Attributes.LOCAL) + case Linkage.WEAK_GLOBAL: + self.attrs.append(Attributes.WEAK) + case _: + pass + + def __str__(self): + string = "" + if len(self.attrs) > 0: + # ATTR1 +ATTR2 ... +ATTRn + string = " +".join(map(str, self.attrs)) + # +ATTR1 +ATTR2 ... +ATTRn address + return f"+{string} {self.address:02x}" + + return f"{self.address:02x}" + + def __repr__(self): + return str(self) + diff --git a/cocas/object_module/external_entry.py b/cocas/object_module/external_entry.py index 818a32db..a92f29bb 100644 --- a/cocas/object_module/external_entry.py +++ b/cocas/object_module/external_entry.py @@ -1,5 +1,6 @@ from dataclasses import dataclass, field +from .attributes import Attributes @dataclass class ExternalEntry: @@ -29,5 +30,8 @@ def __str__(self): def __repr__(self): return str(self) + def get_attrs_str(self): + return "" + def as_tuple(self): return self.offset, self.entry_bytes, self.sign diff --git a/cocas/object_module/external_entry_key.py b/cocas/object_module/external_entry_key.py new file mode 100644 index 00000000..781a242b --- /dev/null +++ b/cocas/object_module/external_entry_key.py @@ -0,0 +1,30 @@ +from .attributes import Attributes + +class ExternalEntryKey: + """Describes the key for adding ExternalEntry objects to a dictionary. + Contains the label name, attributes, sorted in non-descending order, anb + their string representation.""" + def __init__(self, label: str, attrs: list(Attributes)): + self.label: str = str + self.attrs: attrs = sorted(attrs) + self.key = str + + if len(self.attrs) > 0: + # ATTR1 +ATTR2 ... +ATTRn + string = " +".join(map(str, self.attrs)) + # label +ATTR1 +ATTR2 ... +ATTRn + self.key += f"+{string}" + + def __hash__(self): + return hash(self.key) + + def __eq__(self, other): + if not isinstance(other, type(self)): + return False + return self.key == self.key + + def __str__(self): + return self.key + + def __repr__(self): + return str(self) \ No newline at end of file diff --git a/cocas/object_module/object_module.py b/cocas/object_module/object_module.py index 9972a0e6..45f21bd7 100644 --- a/cocas/object_module/object_module.py +++ b/cocas/object_module/object_module.py @@ -5,6 +5,7 @@ from .external_entry import ExternalEntry from .location import CodeLocation +from .entry import Entry @dataclass @@ -16,8 +17,8 @@ class ObjectSectionRecord: """Address of the section. 0 for every relocatable section""" data: bytearray """Compiled binary image of that section before linking""" - entries: dict[str, int] - """Exported labels of this section and their addresses""" + entries: dict[str, Entry] + """Exported labels of this section and their Entries (address, attributes e.t.c.)""" relocatable: list[ExternalEntry] """Places where the address of this relocatable section should be added""" code_locations: dict[int, CodeLocation] From f994818c9a61d0f6519b135e113a75e74f450a88 Mon Sep 17 00:00:00 2001 From: reVInotip Date: Wed, 28 Jan 2026 12:46:59 +0700 Subject: [PATCH 03/42] [cocas] Added attribute support when navigating to an external label (XTRN command) --- cocas/assembler/code_block.py | 5 +++-- .../external_label_key.py} | 21 ++++++++++++------- cocas/assembler/object_generator.py | 8 +++---- .../assembler/targets/cdm16/code_segments.py | 9 +++++--- cocas/object_file/object_export.py | 8 +++---- cocas/object_module/attributes.py | 6 ++++-- cocas/object_module/linkage.py | 10 +++++++++ cocas/object_module/object_module.py | 4 +++- 8 files changed, 47 insertions(+), 24 deletions(-) rename cocas/{object_module/external_entry_key.py => assembler/external_label_key.py} (54%) diff --git a/cocas/assembler/code_block.py b/cocas/assembler/code_block.py index 0f525c40..c04ebd2f 100644 --- a/cocas/assembler/code_block.py +++ b/cocas/assembler/code_block.py @@ -70,9 +70,10 @@ def assemble_lines(self, lines: list, temp_storage): def assemble_label_declaration(self, line: LabelDeclarationNode, __): label_name = line.label.name + label_linkage = line.linkage if (label_name in self.labels or - label_name in self.ents or - label_name in self.exts): + (label_name in self.ents and label_linkage == self.ents[label_name]) or + (label_name in self.exts and label_linkage == self.exts[label_name])): raise AssemblerException(AssemblerExceptionTag.ASM, line.location.file, line.location.line, f'Duplicate label "{label_name}" declaration') diff --git a/cocas/object_module/external_entry_key.py b/cocas/assembler/external_label_key.py similarity index 54% rename from cocas/object_module/external_entry_key.py rename to cocas/assembler/external_label_key.py index 781a242b..459e9889 100644 --- a/cocas/object_module/external_entry_key.py +++ b/cocas/assembler/external_label_key.py @@ -1,19 +1,26 @@ -from .attributes import Attributes +from ..object_module.linkage import Linkage +from ..object_module.attributes import Attributes +from typing import Optional -class ExternalEntryKey: +class ExternalLabelKey: """Describes the key for adding ExternalEntry objects to a dictionary. Contains the label name, attributes, sorted in non-descending order, anb their string representation.""" - def __init__(self, label: str, attrs: list(Attributes)): - self.label: str = str - self.attrs: attrs = sorted(attrs) - self.key = str + def __init__(self, label: str, linkage_attr: Optional[Linkage] = None): + self.label: str = label + self.attrs: list(Attributes) = [] + self.key: str = label + + if linkage_attr: + attr: Attributes = linkage_attr.to_attribute() + if attr != Attributes.NONE: + self.attrs.append(linkage_attr.to_attribute()) if len(self.attrs) > 0: # ATTR1 +ATTR2 ... +ATTRn string = " +".join(map(str, self.attrs)) # label +ATTR1 +ATTR2 ... +ATTRn - self.key += f"+{string}" + self.key += f" +{string}" def __hash__(self): return hash(self.key) diff --git a/cocas/assembler/object_generator.py b/cocas/assembler/object_generator.py index a8e44f2f..174ef72d 100644 --- a/cocas/assembler/object_generator.py +++ b/cocas/assembler/object_generator.py @@ -138,10 +138,10 @@ def generate_object_module(pn: ProgramNode, target_instructions: TargetInstructi pass # do something update_varying_length(asects, {}, template_fields) - asects_labels = gather_local_labels(asects) + all_labels = gather_local_labels(asects) for rsect in rsects: - update_varying_length([rsect], asects_labels, template_fields) + update_varying_length([rsect], all_labels, template_fields) - asect_objects = [asect.to_object_section_record(asects_labels, template_fields) for asect in asects] - rsect_objects = concat_rsects(map(lambda x: x.to_object_section_record(asects_labels, template_fields), rsects)) + asect_objects = [asect.to_object_section_record(all_labels, template_fields) for asect in asects] + rsect_objects = concat_rsects(map(lambda x: x.to_object_section_record(all_labels, template_fields), rsects)) return ObjectModule(asect_objects, rsect_objects) diff --git a/cocas/assembler/targets/cdm16/code_segments.py b/cocas/assembler/targets/cdm16/code_segments.py index fd9b2990..eb0873f1 100644 --- a/cocas/assembler/targets/cdm16/code_segments.py +++ b/cocas/assembler/targets/cdm16/code_segments.py @@ -6,9 +6,11 @@ from cocas.object_module import CodeLocation, ExternalEntry, ObjectSectionRecord -from ...ast_nodes import LabelNode, RegisterNode, RelocatableExpressionNode, TemplateFieldNode +from ...ast_nodes import LabelNode, LabelDeclarationNode, RegisterNode, RelocatableExpressionNode, TemplateFieldNode from ...exceptions import AssemblerException, AssemblerExceptionTag from .. import IAlignedSegment, IAlignmentPaddingSegment, ICodeSegment, IVaryingLengthSegment +from ...external_label_key import ExternalLabelKey +from ....object_module.linkage import Linkage if TYPE_CHECKING: from ...code_block import Section @@ -294,7 +296,7 @@ class ParsedExpression: relocate_additions: int = field(default=0) asect: dict[str, int] = field(default_factory=dict) rel_labels: dict[str, int] = field(default_factory=dict) - ext_labels: dict[str, int] = field(default_factory=dict) + ext_labels: dict[ExternalLabelKey, int] = field(default_factory=dict) def parse_expression(expr: RelocatableExpressionNode, section: "Section", labels: dict[str, int], @@ -305,7 +307,8 @@ def parse_expression(expr: RelocatableExpressionNode, section: "Section", labels for term, sign in [(t, 1) for t in expr.add_terms] + [(t, -1) for t in expr.sub_terms]: if isinstance(term, LabelNode): if term.name in section.exts: - result.ext_labels[term.name] = result.ext_labels.get(term.name, 0) + sign + result.ext_labels[ExternalLabelKey(term.name, section.exts[term.name])] = \ + result.ext_labels.get(term.name, 0) + sign elif term.name in section.labels and section.name != '$abs': result.rel_labels[term.name] = result.rel_labels.get(term.name, 0) + sign elif term.name in section.labels: diff --git a/cocas/object_file/object_export.py b/cocas/object_file/object_export.py index 00d8cdb9..68940b73 100644 --- a/cocas/object_file/object_export.py +++ b/cocas/object_file/object_export.py @@ -87,11 +87,9 @@ def export_object(objs: list[ObjectModule], target: str, debug: bool) -> list[st for sect in (obj.asects if asects_exist else []) + obj.rsects: for label, entries in sect.external.items(): for entry in entries: - # I'm not sure that attributes should be included in the grouping - label_with_attrs = f"{label}{entry.get_attrs_str()}" - external[label_with_attrs].append((sect.name, entry)) - for label_with_attrs, entries in external.items(): - result.append(f'XTRN {label_with_attrs}: {" ".join(map(sect_entry_to_str, entries))}\n') + external[label].append((sect.name, entry)) + for label, entries in external.items(): + result.append(f'XTRN {label}: {" ".join(map(sect_entry_to_str, entries))}\n') pass return result diff --git a/cocas/object_module/attributes.py b/cocas/object_module/attributes.py index b0f339c7..95823fa5 100644 --- a/cocas/object_module/attributes.py +++ b/cocas/object_module/attributes.py @@ -1,6 +1,7 @@ from enum import Enum class Attributes(Enum): + NONE = 0, LOCAL = 1, WEAK = 2 @@ -10,7 +11,8 @@ def __str__(self): return "LOCAL" case Attributes.WEAK: return "WEAK" + case Attributes.NONE: + return "" case _: pass # do something - - \ No newline at end of file + \ No newline at end of file diff --git a/cocas/object_module/linkage.py b/cocas/object_module/linkage.py index 988abdbe..cf16b0d2 100644 --- a/cocas/object_module/linkage.py +++ b/cocas/object_module/linkage.py @@ -1,6 +1,16 @@ from enum import Enum +from .attributes import Attributes class Linkage(Enum): FILE_LOCAL = 1 GLOBAL = 2 WEAK_GLOBAL = 3 + + def to_attribute(self): + match self: + case Linkage.FILE_LOCAL: + return Attributes.LOCAL + case Linkage.WEAK_GLOBAL: + return Attributes.WEAK + case _: + return Attributes.NONE diff --git a/cocas/object_module/object_module.py b/cocas/object_module/object_module.py index 45f21bd7..8cba8fef 100644 --- a/cocas/object_module/object_module.py +++ b/cocas/object_module/object_module.py @@ -7,6 +7,8 @@ from .location import CodeLocation from .entry import Entry +from ..assembler.external_label_key import ExternalLabelKey + @dataclass class ObjectSectionRecord: @@ -25,7 +27,7 @@ class ObjectSectionRecord: """Mapping between addresses in binary image and locations in the source file""" alignment: int = field(default=1) """If the relocatable section should get address that is a multiple of some number""" - external: defaultdict[str, list[ExternalEntry]] = field(default_factory=lambda: defaultdict(list)) + external: defaultdict[ExternalLabelKey, list[ExternalEntry]] = field(default_factory=lambda: defaultdict(list)) """List of places in section where some external label is used""" From ac6ff7e730045369823a76e0ec823383ce781c86 Mon Sep 17 00:00:00 2001 From: reVInotip Date: Thu, 29 Jan 2026 10:15:17 +0700 Subject: [PATCH 04/42] [cocas] Added compile-time search for file-local label definitions and made some minor refactorings --- cocas/assembler/code_block.py | 4 +++- cocas/assembler/external_label_key.py | 5 ++++- cocas/assembler/object_generator.py | 15 +++++++++++++++ cocas/object_module/concat_rsects.py | 2 +- cocas/object_module/entry.py | 24 +++++++++++------------- cocas/object_module/external_entry.py | 2 -- 6 files changed, 34 insertions(+), 18 deletions(-) diff --git a/cocas/assembler/code_block.py b/cocas/assembler/code_block.py index c04ebd2f..1673ff1a 100644 --- a/cocas/assembler/code_block.py +++ b/cocas/assembler/code_block.py @@ -182,7 +182,9 @@ def __init__(self, sn: SectionNode, target_instructions: TargetInstructions): def to_object_section_record(self, labels: dict[str, int], templates: dict[str, dict[str, int]]): entries = { - key: Entry(label, self.ents[key]) + key: (lambda: (entry := Entry(label), + entry.add_linkage_attribute(self.ents[key]), + entry)[2])() for key, label in self.labels.items() if key in self.ents } diff --git a/cocas/assembler/external_label_key.py b/cocas/assembler/external_label_key.py index 459e9889..646c567a 100644 --- a/cocas/assembler/external_label_key.py +++ b/cocas/assembler/external_label_key.py @@ -34,4 +34,7 @@ def __str__(self): return self.key def __repr__(self): - return str(self) \ No newline at end of file + return str(self) + + def is_file_local(self): + return Attributes.LOCAL in self.attrs \ No newline at end of file diff --git a/cocas/assembler/object_generator.py b/cocas/assembler/object_generator.py index 174ef72d..abb494e0 100644 --- a/cocas/assembler/object_generator.py +++ b/cocas/assembler/object_generator.py @@ -3,6 +3,7 @@ from typing import Any, Union from cocas.object_module import CodeLocation, ObjectModule, concat_rsects +from ..object_module.linkage import Linkage from .ast_nodes import ( InstructionNode, @@ -105,6 +106,7 @@ def label_or_template(label: Union[LabelNode, Any], template_fields: dict[str, d def generate_object_module(pn: ProgramNode, target_instructions: TargetInstructions) -> ObjectModule: templates = [Template(t, target_instructions) for t in pn.template_sections] template_fields = dict([(t.name, t.labels) for t in templates]) + file_local_labels: dict[str, tuple[str, int]] = dict() # LabelDeclarationNode # InstructionNode @@ -121,6 +123,8 @@ def generate_object_module(pn: ProgramNode, target_instructions: TargetInstructi if prefix in template_fields: raise AssemblerException(AssemblerExceptionTag.ASM, line.location.file, line.location.line, f"Label {line.label.name} conflicts with template {prefix}") + if line.linkage == Linkage.FILE_LOCAL: + file_local_labels[line.label.name] = (line.location.file, line.location.line) elif isinstance(line, InstructionNode): for arg in line.arguments: if isinstance(arg, RelocatableExpressionNode): @@ -144,4 +148,15 @@ def generate_object_module(pn: ProgramNode, target_instructions: TargetInstructi asect_objects = [asect.to_object_section_record(all_labels, template_fields) for asect in asects] rsect_objects = concat_rsects(map(lambda x: x.to_object_section_record(all_labels, template_fields), rsects)) + + for obj in itertools.chain(asect_objects, rsect_objects): + for label in obj.entries.keys(): + if label in file_local_labels: + file_local_labels.pop(label) + + if not len(file_local_labels) == 0: + label, (file, line) = next(iter(file_local_labels.items())) + raise AssemblerException(AssemblerExceptionTag.ASM, file, line, + f'Not found file local label(s) implementation: "{label}"') + return ObjectModule(asect_objects, rsect_objects) diff --git a/cocas/object_module/concat_rsects.py b/cocas/object_module/concat_rsects.py index e5dfa58a..1405e6ce 100644 --- a/cocas/object_module/concat_rsects.py +++ b/cocas/object_module/concat_rsects.py @@ -35,7 +35,7 @@ def concat_rsects(rsects: Iterable["ObjectSectionRecord"]) -> list["ObjectSectio same_entries = new.entries.keys() & rsect.entries.keys() if same_entries: raise ValueError(f"Two sections with same name {name} declare label {next(iter(same_entries))}") - new.entries.update({entry: pos + prev_size for entry, pos in rsect.entries.items()}) + new.entries.update({entry_name: entry.address + prev_size for entry_name, entry in rsect.entries.items()}) for pos, loc in rsect.code_locations.items(): new.code_locations[pos + prev_size] = loc for label, exts in rsect.external.items(): diff --git a/cocas/object_module/entry.py b/cocas/object_module/entry.py index c48b7bd4..1ad4f425 100644 --- a/cocas/object_module/entry.py +++ b/cocas/object_module/entry.py @@ -1,21 +1,20 @@ -from dataclasses import dataclass +from dataclasses import dataclass, field +from typing import Optional from .attributes import Attributes from .linkage import Linkage @dataclass class Entry: - def __init__(self, address: int, linkage: Linkage): - self.address: int = address - self.attrs: list(Attributes) = list() - match linkage: - case Linkage.FILE_LOCAL: - self.attrs.append(Attributes.LOCAL) - case Linkage.WEAK_GLOBAL: - self.attrs.append(Attributes.WEAK) - case _: - pass - + address: int + attrs: list[Attributes] = field(default_factory=list) + + def add_linkage_attribute(self, linkage: Optional[Linkage]): + if linkage: + attr: Attributes = linkage.to_attribute() + if attr != Attributes.NONE: + self.attrs.append(linkage.to_attribute()) + def __str__(self): string = "" if len(self.attrs) > 0: @@ -28,4 +27,3 @@ def __str__(self): def __repr__(self): return str(self) - diff --git a/cocas/object_module/external_entry.py b/cocas/object_module/external_entry.py index a92f29bb..b0cbf72e 100644 --- a/cocas/object_module/external_entry.py +++ b/cocas/object_module/external_entry.py @@ -1,7 +1,5 @@ from dataclasses import dataclass, field -from .attributes import Attributes - @dataclass class ExternalEntry: """Describes where and how some unknown at compile time value will be placed over the binary image. From d2b89e56a7eb2a5176377bcbc83586bf5ce87164 Mon Sep 17 00:00:00 2001 From: reVInotip Date: Thu, 29 Jan 2026 14:07:31 +0700 Subject: [PATCH 05/42] [cocas] Refactor code --- cocas/assembler/__init__.py | 1 + cocas/assembler/external_label_key.py | 9 ++++++++- cocas/object_module/__init__.py | 2 ++ cocas/object_module/external_entry.py | 3 --- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/cocas/assembler/__init__.py b/cocas/assembler/__init__.py index d8af4dce..d042f1db 100644 --- a/cocas/assembler/__init__.py +++ b/cocas/assembler/__init__.py @@ -4,3 +4,4 @@ from .exceptions import AssemblerException, AssemblerExceptionTag from .macro_processor import read_mlb from .targets import list_assembler_targets +from .external_label_key import ExternalLabelKey diff --git a/cocas/assembler/external_label_key.py b/cocas/assembler/external_label_key.py index 646c567a..9bdbf6f3 100644 --- a/cocas/assembler/external_label_key.py +++ b/cocas/assembler/external_label_key.py @@ -6,7 +6,9 @@ class ExternalLabelKey: """Describes the key for adding ExternalEntry objects to a dictionary. Contains the label name, attributes, sorted in non-descending order, anb their string representation.""" - def __init__(self, label: str, linkage_attr: Optional[Linkage] = None): + def __init__(self, label: str, + linkage_attr: Optional[Linkage] = None, + attributes: Optional[list[Attributes]] = None): self.label: str = label self.attrs: list(Attributes) = [] self.key: str = label @@ -15,6 +17,11 @@ def __init__(self, label: str, linkage_attr: Optional[Linkage] = None): attr: Attributes = linkage_attr.to_attribute() if attr != Attributes.NONE: self.attrs.append(linkage_attr.to_attribute()) + + if attributes: + self.attrs.extend(attributes) + + self.attrs = sorted(self.attrs) if len(self.attrs) > 0: # ATTR1 +ATTR2 ... +ATTRn diff --git a/cocas/object_module/__init__.py b/cocas/object_module/__init__.py index 4b3862cf..faac2cda 100644 --- a/cocas/object_module/__init__.py +++ b/cocas/object_module/__init__.py @@ -5,3 +5,5 @@ from .location import CodeLocation from .object_module import ObjectModule, ObjectSectionRecord from .linkage import Linkage +from .attributes import Attributes +from .entry import Entry diff --git a/cocas/object_module/external_entry.py b/cocas/object_module/external_entry.py index b0cbf72e..52fd57ab 100644 --- a/cocas/object_module/external_entry.py +++ b/cocas/object_module/external_entry.py @@ -28,8 +28,5 @@ def __str__(self): def __repr__(self): return str(self) - def get_attrs_str(self): - return "" - def as_tuple(self): return self.offset, self.entry_bytes, self.sign From e0633359b6f60abec6fe4aff3ce0c5695f8d3585 Mon Sep 17 00:00:00 2001 From: Proletcultist Date: Wed, 28 Jan 2026 10:30:08 +0700 Subject: [PATCH 06/42] [cocas] Added XTRN and NTRY attributes into object file grammar --- .../object_file/generated/ObjectFileLexer.py | 198 +++--- .../object_file/generated/ObjectFileParser.py | 650 +++++++++++------- .../generated/ObjectFileParserVisitor.py | 10 + cocas/object_file/grammar/ObjectFileLexer.g4 | 5 +- cocas/object_file/grammar/ObjectFileParser.g4 | 8 +- 5 files changed, 521 insertions(+), 350 deletions(-) diff --git a/cocas/object_file/generated/ObjectFileLexer.py b/cocas/object_file/generated/ObjectFileLexer.py index cb9fa11e..b18bb032 100644 --- a/cocas/object_file/generated/ObjectFileLexer.py +++ b/cocas/object_file/generated/ObjectFileLexer.py @@ -10,80 +10,85 @@ def serializedATN(): return [ - 4,0,26,206,6,-1,6,-1,6,-1,6,-1,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3, + 4,0,28,221,6,-1,6,-1,6,-1,6,-1,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3, 7,3,2,4,7,4,2,5,7,5,2,6,7,6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2, 11,7,11,2,12,7,12,2,13,7,13,2,14,7,14,2,15,7,15,2,16,7,16,2,17,7, 17,2,18,7,18,2,19,7,19,2,20,7,20,2,21,7,21,2,22,7,22,2,23,7,23,2, - 24,7,24,2,25,7,25,1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,2,1,2,1,2,1,2,1,2,1,2,1,3,1,3,1,3,1,3,1,4,1,4,1,4,1,4,1,4,1, - 5,1,5,1,5,1,5,1,5,1,6,1,6,1,6,1,6,1,6,1,7,1,7,1,7,1,7,1,7,1,7,1, - 7,1,8,1,8,1,8,1,8,1,9,1,9,1,9,1,9,1,9,1,10,4,10,112,8,10,11,10,12, - 10,113,1,11,1,11,5,11,118,8,11,10,11,12,11,121,9,11,1,11,1,11,5, - 11,125,8,11,10,11,12,11,128,9,11,1,11,1,11,1,12,1,12,1,12,1,12,1, - 12,1,13,1,13,1,14,1,14,1,15,1,15,1,16,1,16,1,17,3,17,146,8,17,1, - 17,4,17,149,8,17,11,17,12,17,150,1,18,4,18,154,8,18,11,18,12,18, - 155,1,18,1,18,1,19,3,19,161,8,19,1,19,4,19,164,8,19,11,19,12,19, - 165,1,19,1,19,1,20,4,20,171,8,20,11,20,12,20,172,1,21,4,21,176,8, - 21,11,21,12,21,177,1,22,4,22,181,8,22,11,22,12,22,182,1,22,1,22, - 1,23,1,23,1,23,1,23,1,23,1,24,4,24,193,8,24,11,24,12,24,194,1,24, - 1,24,1,24,1,25,4,25,201,8,25,11,25,12,25,202,1,25,1,25,0,0,26,5, - 1,7,2,9,3,11,4,13,5,15,6,17,7,19,8,21,9,23,10,25,11,27,12,29,13, - 31,14,33,15,35,16,37,17,39,18,41,19,43,20,45,21,47,22,49,23,51,24, - 53,25,55,26,5,0,1,2,3,4,6,4,0,48,57,65,90,95,95,97,122,3,0,65,90, - 95,95,97,122,5,0,46,46,48,57,65,90,95,95,97,122,2,0,9,9,32,32,6, - 0,9,9,32,32,48,57,65,90,95,95,97,122,2,0,10,10,13,13,214,0,5,1,0, - 0,0,0,7,1,0,0,0,0,9,1,0,0,0,0,11,1,0,0,0,0,13,1,0,0,0,0,15,1,0,0, - 0,0,17,1,0,0,0,0,19,1,0,0,0,0,21,1,0,0,0,0,23,1,0,0,0,0,25,1,0,0, - 0,0,27,1,0,0,0,0,29,1,0,0,0,0,31,1,0,0,0,0,33,1,0,0,0,0,35,1,0,0, - 0,0,37,1,0,0,0,0,39,1,0,0,0,0,41,1,0,0,0,1,43,1,0,0,0,1,45,1,0,0, - 0,2,47,1,0,0,0,2,49,1,0,0,0,2,51,1,0,0,0,3,53,1,0,0,0,4,55,1,0,0, - 0,5,57,1,0,0,0,7,62,1,0,0,0,9,69,1,0,0,0,11,75,1,0,0,0,13,79,1,0, - 0,0,15,84,1,0,0,0,17,89,1,0,0,0,19,94,1,0,0,0,21,101,1,0,0,0,23, - 105,1,0,0,0,25,111,1,0,0,0,27,115,1,0,0,0,29,131,1,0,0,0,31,136, - 1,0,0,0,33,138,1,0,0,0,35,140,1,0,0,0,37,142,1,0,0,0,39,148,1,0, - 0,0,41,153,1,0,0,0,43,163,1,0,0,0,45,170,1,0,0,0,47,175,1,0,0,0, - 49,180,1,0,0,0,51,186,1,0,0,0,53,192,1,0,0,0,55,200,1,0,0,0,57,58, - 5,84,0,0,58,59,5,65,0,0,59,60,5,82,0,0,60,61,5,71,0,0,61,6,1,0,0, - 0,62,63,5,70,0,0,63,64,5,73,0,0,64,65,5,76,0,0,65,66,5,69,0,0,66, - 67,1,0,0,0,67,68,6,1,0,0,68,8,1,0,0,0,69,70,5,65,0,0,70,71,5,66, - 0,0,71,72,5,83,0,0,72,73,1,0,0,0,73,74,6,2,1,0,74,10,1,0,0,0,75, - 76,5,76,0,0,76,77,5,79,0,0,77,78,5,67,0,0,78,12,1,0,0,0,79,80,5, - 78,0,0,80,81,5,84,0,0,81,82,5,82,0,0,82,83,5,89,0,0,83,14,1,0,0, - 0,84,85,5,78,0,0,85,86,5,65,0,0,86,87,5,77,0,0,87,88,5,69,0,0,88, - 16,1,0,0,0,89,90,5,65,0,0,90,91,5,76,0,0,91,92,5,73,0,0,92,93,5, - 71,0,0,93,18,1,0,0,0,94,95,5,68,0,0,95,96,5,65,0,0,96,97,5,84,0, - 0,97,98,5,65,0,0,98,99,1,0,0,0,99,100,6,7,2,0,100,20,1,0,0,0,101, - 102,5,82,0,0,102,103,5,69,0,0,103,104,5,76,0,0,104,22,1,0,0,0,105, - 106,5,88,0,0,106,107,5,84,0,0,107,108,5,82,0,0,108,109,5,78,0,0, - 109,24,1,0,0,0,110,112,7,0,0,0,111,110,1,0,0,0,112,113,1,0,0,0,113, - 111,1,0,0,0,113,114,1,0,0,0,114,26,1,0,0,0,115,119,7,1,0,0,116,118, - 7,0,0,0,117,116,1,0,0,0,118,121,1,0,0,0,119,117,1,0,0,0,119,120, - 1,0,0,0,120,122,1,0,0,0,121,119,1,0,0,0,122,126,3,37,16,0,123,125, - 7,2,0,0,124,123,1,0,0,0,125,128,1,0,0,0,126,124,1,0,0,0,126,127, - 1,0,0,0,127,129,1,0,0,0,128,126,1,0,0,0,129,130,7,0,0,0,130,28,1, - 0,0,0,131,132,5,36,0,0,132,133,5,97,0,0,133,134,5,98,0,0,134,135, - 5,115,0,0,135,30,1,0,0,0,136,137,5,58,0,0,137,32,1,0,0,0,138,139, - 5,45,0,0,139,34,1,0,0,0,140,141,5,43,0,0,141,36,1,0,0,0,142,143, - 5,46,0,0,143,38,1,0,0,0,144,146,5,13,0,0,145,144,1,0,0,0,145,146, - 1,0,0,0,146,147,1,0,0,0,147,149,5,10,0,0,148,145,1,0,0,0,149,150, - 1,0,0,0,150,148,1,0,0,0,150,151,1,0,0,0,151,40,1,0,0,0,152,154,7, - 3,0,0,153,152,1,0,0,0,154,155,1,0,0,0,155,153,1,0,0,0,155,156,1, - 0,0,0,156,157,1,0,0,0,157,158,6,18,3,0,158,42,1,0,0,0,159,161,5, - 13,0,0,160,159,1,0,0,0,160,161,1,0,0,0,161,162,1,0,0,0,162,164,5, - 10,0,0,163,160,1,0,0,0,164,165,1,0,0,0,165,163,1,0,0,0,165,166,1, - 0,0,0,166,167,1,0,0,0,167,168,6,19,4,0,168,44,1,0,0,0,169,171,7, - 4,0,0,170,169,1,0,0,0,171,172,1,0,0,0,172,170,1,0,0,0,172,173,1, - 0,0,0,173,46,1,0,0,0,174,176,7,0,0,0,175,174,1,0,0,0,176,177,1,0, - 0,0,177,175,1,0,0,0,177,178,1,0,0,0,178,48,1,0,0,0,179,181,7,3,0, - 0,180,179,1,0,0,0,181,182,1,0,0,0,182,180,1,0,0,0,182,183,1,0,0, - 0,183,184,1,0,0,0,184,185,6,22,3,0,185,50,1,0,0,0,186,187,5,58,0, - 0,187,188,1,0,0,0,188,189,6,23,4,0,189,190,6,23,2,0,190,52,1,0,0, - 0,191,193,5,32,0,0,192,191,1,0,0,0,193,194,1,0,0,0,194,192,1,0,0, - 0,194,195,1,0,0,0,195,196,1,0,0,0,196,197,6,24,4,0,197,198,6,24, - 5,0,198,54,1,0,0,0,199,201,8,5,0,0,200,199,1,0,0,0,201,202,1,0,0, - 0,202,200,1,0,0,0,202,203,1,0,0,0,203,204,1,0,0,0,204,205,6,25,4, - 0,205,56,1,0,0,0,18,0,1,2,3,4,113,119,126,145,150,155,160,165,172, - 177,182,194,202,6,5,3,0,5,2,0,5,1,0,6,0,0,4,0,0,5,4,0 + 24,7,24,2,25,7,25,2,26,7,26,2,27,7,27,1,0,1,0,1,0,1,0,1,0,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,2,1,2,1,2,1,2,1,2,1,2,1,3,1,3,1,3,1,3,1, + 4,1,4,1,4,1,4,1,4,1,5,1,5,1,5,1,5,1,5,1,6,1,6,1,6,1,6,1,6,1,7,1, + 7,1,7,1,7,1,7,1,7,1,7,1,8,1,8,1,8,1,8,1,9,1,9,1,9,1,9,1,9,1,10,1, + 10,1,10,1,10,1,10,1,11,1,11,1,11,1,11,1,11,1,11,1,12,4,12,127,8, + 12,11,12,12,12,128,1,13,1,13,5,13,133,8,13,10,13,12,13,136,9,13, + 1,13,1,13,5,13,140,8,13,10,13,12,13,143,9,13,1,13,1,13,1,14,1,14, + 1,14,1,14,1,14,1,15,1,15,1,16,1,16,1,17,1,17,1,18,1,18,1,19,3,19, + 161,8,19,1,19,4,19,164,8,19,11,19,12,19,165,1,20,4,20,169,8,20,11, + 20,12,20,170,1,20,1,20,1,21,3,21,176,8,21,1,21,4,21,179,8,21,11, + 21,12,21,180,1,21,1,21,1,22,4,22,186,8,22,11,22,12,22,187,1,23,4, + 23,191,8,23,11,23,12,23,192,1,24,4,24,196,8,24,11,24,12,24,197,1, + 24,1,24,1,25,1,25,1,25,1,25,1,25,1,26,4,26,208,8,26,11,26,12,26, + 209,1,26,1,26,1,26,1,27,4,27,216,8,27,11,27,12,27,217,1,27,1,27, + 0,0,28,5,1,7,2,9,3,11,4,13,5,15,6,17,7,19,8,21,9,23,10,25,11,27, + 12,29,13,31,14,33,15,35,16,37,17,39,18,41,19,43,20,45,21,47,22,49, + 23,51,24,53,25,55,26,57,27,59,28,5,0,1,2,3,4,6,4,0,48,57,65,90,95, + 95,97,122,3,0,65,90,95,95,97,122,5,0,46,46,48,57,65,90,95,95,97, + 122,2,0,9,9,32,32,6,0,9,9,32,32,48,57,65,90,95,95,97,122,2,0,10, + 10,13,13,229,0,5,1,0,0,0,0,7,1,0,0,0,0,9,1,0,0,0,0,11,1,0,0,0,0, + 13,1,0,0,0,0,15,1,0,0,0,0,17,1,0,0,0,0,19,1,0,0,0,0,21,1,0,0,0,0, + 23,1,0,0,0,0,25,1,0,0,0,0,27,1,0,0,0,0,29,1,0,0,0,0,31,1,0,0,0,0, + 33,1,0,0,0,0,35,1,0,0,0,0,37,1,0,0,0,0,39,1,0,0,0,0,41,1,0,0,0,0, + 43,1,0,0,0,0,45,1,0,0,0,1,47,1,0,0,0,1,49,1,0,0,0,2,51,1,0,0,0,2, + 53,1,0,0,0,2,55,1,0,0,0,3,57,1,0,0,0,4,59,1,0,0,0,5,61,1,0,0,0,7, + 66,1,0,0,0,9,73,1,0,0,0,11,79,1,0,0,0,13,83,1,0,0,0,15,88,1,0,0, + 0,17,93,1,0,0,0,19,98,1,0,0,0,21,105,1,0,0,0,23,109,1,0,0,0,25,114, + 1,0,0,0,27,119,1,0,0,0,29,126,1,0,0,0,31,130,1,0,0,0,33,146,1,0, + 0,0,35,151,1,0,0,0,37,153,1,0,0,0,39,155,1,0,0,0,41,157,1,0,0,0, + 43,163,1,0,0,0,45,168,1,0,0,0,47,178,1,0,0,0,49,185,1,0,0,0,51,190, + 1,0,0,0,53,195,1,0,0,0,55,201,1,0,0,0,57,207,1,0,0,0,59,215,1,0, + 0,0,61,62,5,84,0,0,62,63,5,65,0,0,63,64,5,82,0,0,64,65,5,71,0,0, + 65,6,1,0,0,0,66,67,5,70,0,0,67,68,5,73,0,0,68,69,5,76,0,0,69,70, + 5,69,0,0,70,71,1,0,0,0,71,72,6,1,0,0,72,8,1,0,0,0,73,74,5,65,0,0, + 74,75,5,66,0,0,75,76,5,83,0,0,76,77,1,0,0,0,77,78,6,2,1,0,78,10, + 1,0,0,0,79,80,5,76,0,0,80,81,5,79,0,0,81,82,5,67,0,0,82,12,1,0,0, + 0,83,84,5,78,0,0,84,85,5,84,0,0,85,86,5,82,0,0,86,87,5,89,0,0,87, + 14,1,0,0,0,88,89,5,78,0,0,89,90,5,65,0,0,90,91,5,77,0,0,91,92,5, + 69,0,0,92,16,1,0,0,0,93,94,5,65,0,0,94,95,5,76,0,0,95,96,5,73,0, + 0,96,97,5,71,0,0,97,18,1,0,0,0,98,99,5,68,0,0,99,100,5,65,0,0,100, + 101,5,84,0,0,101,102,5,65,0,0,102,103,1,0,0,0,103,104,6,7,2,0,104, + 20,1,0,0,0,105,106,5,82,0,0,106,107,5,69,0,0,107,108,5,76,0,0,108, + 22,1,0,0,0,109,110,5,88,0,0,110,111,5,84,0,0,111,112,5,82,0,0,112, + 113,5,78,0,0,113,24,1,0,0,0,114,115,5,87,0,0,115,116,5,69,0,0,116, + 117,5,65,0,0,117,118,5,75,0,0,118,26,1,0,0,0,119,120,5,76,0,0,120, + 121,5,79,0,0,121,122,5,67,0,0,122,123,5,65,0,0,123,124,5,76,0,0, + 124,28,1,0,0,0,125,127,7,0,0,0,126,125,1,0,0,0,127,128,1,0,0,0,128, + 126,1,0,0,0,128,129,1,0,0,0,129,30,1,0,0,0,130,134,7,1,0,0,131,133, + 7,0,0,0,132,131,1,0,0,0,133,136,1,0,0,0,134,132,1,0,0,0,134,135, + 1,0,0,0,135,137,1,0,0,0,136,134,1,0,0,0,137,141,3,41,18,0,138,140, + 7,2,0,0,139,138,1,0,0,0,140,143,1,0,0,0,141,139,1,0,0,0,141,142, + 1,0,0,0,142,144,1,0,0,0,143,141,1,0,0,0,144,145,7,0,0,0,145,32,1, + 0,0,0,146,147,5,36,0,0,147,148,5,97,0,0,148,149,5,98,0,0,149,150, + 5,115,0,0,150,34,1,0,0,0,151,152,5,58,0,0,152,36,1,0,0,0,153,154, + 5,45,0,0,154,38,1,0,0,0,155,156,5,43,0,0,156,40,1,0,0,0,157,158, + 5,46,0,0,158,42,1,0,0,0,159,161,5,13,0,0,160,159,1,0,0,0,160,161, + 1,0,0,0,161,162,1,0,0,0,162,164,5,10,0,0,163,160,1,0,0,0,164,165, + 1,0,0,0,165,163,1,0,0,0,165,166,1,0,0,0,166,44,1,0,0,0,167,169,7, + 3,0,0,168,167,1,0,0,0,169,170,1,0,0,0,170,168,1,0,0,0,170,171,1, + 0,0,0,171,172,1,0,0,0,172,173,6,20,3,0,173,46,1,0,0,0,174,176,5, + 13,0,0,175,174,1,0,0,0,175,176,1,0,0,0,176,177,1,0,0,0,177,179,5, + 10,0,0,178,175,1,0,0,0,179,180,1,0,0,0,180,178,1,0,0,0,180,181,1, + 0,0,0,181,182,1,0,0,0,182,183,6,21,4,0,183,48,1,0,0,0,184,186,7, + 4,0,0,185,184,1,0,0,0,186,187,1,0,0,0,187,185,1,0,0,0,187,188,1, + 0,0,0,188,50,1,0,0,0,189,191,7,0,0,0,190,189,1,0,0,0,191,192,1,0, + 0,0,192,190,1,0,0,0,192,193,1,0,0,0,193,52,1,0,0,0,194,196,7,3,0, + 0,195,194,1,0,0,0,196,197,1,0,0,0,197,195,1,0,0,0,197,198,1,0,0, + 0,198,199,1,0,0,0,199,200,6,24,3,0,200,54,1,0,0,0,201,202,5,58,0, + 0,202,203,1,0,0,0,203,204,6,25,4,0,204,205,6,25,2,0,205,56,1,0,0, + 0,206,208,5,32,0,0,207,206,1,0,0,0,208,209,1,0,0,0,209,207,1,0,0, + 0,209,210,1,0,0,0,210,211,1,0,0,0,211,212,6,26,4,0,212,213,6,26, + 5,0,213,58,1,0,0,0,214,216,8,5,0,0,215,214,1,0,0,0,216,217,1,0,0, + 0,217,215,1,0,0,0,217,218,1,0,0,0,218,219,1,0,0,0,219,220,6,27,4, + 0,220,60,1,0,0,0,18,0,1,2,3,4,128,134,141,160,165,170,175,180,187, + 192,197,209,217,6,5,3,0,5,2,0,5,1,0,6,0,0,4,0,0,5,4,0 ] class ObjectFileLexer(Lexer): @@ -107,22 +112,24 @@ class ObjectFileLexer(Lexer): DATA = 8 REL = 9 XTRN = 10 - WORD = 11 - WORD_WITH_DOTS = 12 - ABS_SECTION = 13 - COLON = 14 - MINUS = 15 - PLUS = 16 - DOT = 17 - NEWLINE = 18 - WS = 19 - NEWLINE_BYTES = 20 - BYTES = 21 - WORD_ABS = 22 - WS_ABS = 23 - COLON_ABS = 24 - SPACES_FILE = 25 - FILEPATH = 26 + WEAK = 11 + LOCAL = 12 + WORD = 13 + WORD_WITH_DOTS = 14 + ABS_SECTION = 15 + COLON = 16 + MINUS = 17 + PLUS = 18 + DOT = 19 + NEWLINE = 20 + WS = 21 + NEWLINE_BYTES = 22 + BYTES = 23 + WORD_ABS = 24 + WS_ABS = 25 + COLON_ABS = 26 + SPACES_FILE = 27 + FILEPATH = 28 channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ] @@ -130,19 +137,20 @@ class ObjectFileLexer(Lexer): literalNames = [ "", "'TARG'", "'FILE'", "'ABS'", "'LOC'", "'NTRY'", "'NAME'", "'ALIG'", - "'DATA'", "'REL'", "'XTRN'", "'$abs'", "'-'", "'+'", "'.'" ] + "'DATA'", "'REL'", "'XTRN'", "'WEAK'", "'LOCAL'", "'$abs'", + "'-'", "'+'", "'.'" ] symbolicNames = [ "", "TARG", "FILE", "ABS", "LOC", "NTRY", "NAME", "ALIG", "DATA", - "REL", "XTRN", "WORD", "WORD_WITH_DOTS", "ABS_SECTION", "COLON", - "MINUS", "PLUS", "DOT", "NEWLINE", "WS", "NEWLINE_BYTES", "BYTES", - "WORD_ABS", "WS_ABS", "COLON_ABS", "SPACES_FILE", "FILEPATH" ] + "REL", "XTRN", "WEAK", "LOCAL", "WORD", "WORD_WITH_DOTS", "ABS_SECTION", + "COLON", "MINUS", "PLUS", "DOT", "NEWLINE", "WS", "NEWLINE_BYTES", + "BYTES", "WORD_ABS", "WS_ABS", "COLON_ABS", "SPACES_FILE", "FILEPATH" ] ruleNames = [ "TARG", "FILE", "ABS", "LOC", "NTRY", "NAME", "ALIG", - "DATA", "REL", "XTRN", "WORD", "WORD_WITH_DOTS", "ABS_SECTION", - "COLON", "MINUS", "PLUS", "DOT", "NEWLINE", "WS", "NEWLINE_BYTES", - "BYTES", "WORD_ABS", "WS_ABS", "COLON_ABS", "SPACES_FILE", - "FILEPATH" ] + "DATA", "REL", "XTRN", "WEAK", "LOCAL", "WORD", "WORD_WITH_DOTS", + "ABS_SECTION", "COLON", "MINUS", "PLUS", "DOT", "NEWLINE", + "WS", "NEWLINE_BYTES", "BYTES", "WORD_ABS", "WS_ABS", + "COLON_ABS", "SPACES_FILE", "FILEPATH" ] grammarFileName = "ObjectFileLexer.g4" diff --git a/cocas/object_file/generated/ObjectFileParser.py b/cocas/object_file/generated/ObjectFileParser.py index e64c2078..ba5d2816 100644 --- a/cocas/object_file/generated/ObjectFileParser.py +++ b/cocas/object_file/generated/ObjectFileParser.py @@ -10,84 +10,92 @@ def serializedATN(): return [ - 4,1,26,233,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, + 4,1,28,253,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, 6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2,13,7,13, 2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7,19,2,20, - 7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,1,0,3,0,54, - 8,0,1,0,3,0,57,8,0,1,0,4,0,60,8,0,11,0,12,0,61,1,0,1,0,1,1,3,1,67, - 8,1,1,1,1,1,5,1,71,8,1,10,1,12,1,74,9,1,1,1,4,1,77,8,1,11,1,12,1, - 78,3,1,81,8,1,1,1,5,1,84,8,1,10,1,12,1,87,9,1,1,2,1,2,4,2,91,8,2, - 11,2,12,2,92,1,3,1,3,5,3,97,8,3,10,3,12,3,100,9,3,1,4,1,4,3,4,104, - 8,4,1,4,1,4,5,4,108,8,4,10,4,12,4,111,9,4,1,4,3,4,114,8,4,1,4,5, - 4,117,8,4,10,4,12,4,120,9,4,1,5,1,5,1,5,1,5,1,6,1,6,1,6,1,6,1,6, - 1,7,1,7,1,7,1,7,3,7,135,8,7,1,7,4,7,138,8,7,11,7,12,7,139,1,8,1, - 8,5,8,144,8,8,10,8,12,8,147,9,8,1,8,1,8,1,9,1,9,1,9,1,9,1,9,1,10, - 1,10,1,10,1,10,1,11,1,11,1,11,1,11,1,12,1,12,3,12,166,8,12,1,12, - 4,12,169,8,12,11,12,12,12,170,1,13,1,13,5,13,175,8,13,10,13,12,13, - 178,9,13,1,13,1,13,1,14,1,14,1,14,1,14,1,14,1,14,5,14,188,8,14,10, - 14,12,14,191,9,14,1,14,1,14,1,15,1,15,1,16,1,16,1,17,3,17,200,8, - 17,1,17,1,17,1,17,1,17,3,17,206,8,17,3,17,208,8,17,1,18,1,18,1,18, - 1,18,1,19,1,19,1,19,1,20,1,20,1,20,1,20,1,20,1,20,1,21,1,21,1,22, - 1,22,1,23,1,23,1,24,1,24,1,25,1,25,1,25,0,0,26,0,2,4,6,8,10,12,14, - 16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,0,2,1,0,11, - 12,2,0,11,11,13,13,231,0,53,1,0,0,0,2,66,1,0,0,0,4,90,1,0,0,0,6, - 94,1,0,0,0,8,101,1,0,0,0,10,121,1,0,0,0,12,125,1,0,0,0,14,130,1, - 0,0,0,16,141,1,0,0,0,18,150,1,0,0,0,20,155,1,0,0,0,22,159,1,0,0, - 0,24,163,1,0,0,0,26,172,1,0,0,0,28,181,1,0,0,0,30,194,1,0,0,0,32, - 196,1,0,0,0,34,199,1,0,0,0,36,209,1,0,0,0,38,213,1,0,0,0,40,216, - 1,0,0,0,42,222,1,0,0,0,44,224,1,0,0,0,46,226,1,0,0,0,48,228,1,0, - 0,0,50,230,1,0,0,0,52,54,5,18,0,0,53,52,1,0,0,0,53,54,1,0,0,0,54, - 56,1,0,0,0,55,57,3,10,5,0,56,55,1,0,0,0,56,57,1,0,0,0,57,59,1,0, - 0,0,58,60,3,2,1,0,59,58,1,0,0,0,60,61,1,0,0,0,61,59,1,0,0,0,61,62, - 1,0,0,0,62,63,1,0,0,0,63,64,5,0,0,1,64,1,1,0,0,0,65,67,3,12,6,0, - 66,65,1,0,0,0,66,67,1,0,0,0,67,80,1,0,0,0,68,72,3,4,2,0,69,71,3, - 8,4,0,70,69,1,0,0,0,71,74,1,0,0,0,72,70,1,0,0,0,72,73,1,0,0,0,73, - 81,1,0,0,0,74,72,1,0,0,0,75,77,3,8,4,0,76,75,1,0,0,0,77,78,1,0,0, - 0,78,76,1,0,0,0,78,79,1,0,0,0,79,81,1,0,0,0,80,68,1,0,0,0,80,76, - 1,0,0,0,81,85,1,0,0,0,82,84,3,28,14,0,83,82,1,0,0,0,84,87,1,0,0, - 0,85,83,1,0,0,0,85,86,1,0,0,0,86,3,1,0,0,0,87,85,1,0,0,0,88,91,3, - 6,3,0,89,91,3,18,9,0,90,88,1,0,0,0,90,89,1,0,0,0,91,92,1,0,0,0,92, - 90,1,0,0,0,92,93,1,0,0,0,93,5,1,0,0,0,94,98,3,14,7,0,95,97,3,16, - 8,0,96,95,1,0,0,0,97,100,1,0,0,0,98,96,1,0,0,0,98,99,1,0,0,0,99, - 7,1,0,0,0,100,98,1,0,0,0,101,103,3,20,10,0,102,104,3,22,11,0,103, - 102,1,0,0,0,103,104,1,0,0,0,104,105,1,0,0,0,105,109,3,24,12,0,106, - 108,3,16,8,0,107,106,1,0,0,0,108,111,1,0,0,0,109,107,1,0,0,0,109, - 110,1,0,0,0,110,113,1,0,0,0,111,109,1,0,0,0,112,114,3,26,13,0,113, - 112,1,0,0,0,113,114,1,0,0,0,114,118,1,0,0,0,115,117,3,18,9,0,116, - 115,1,0,0,0,117,120,1,0,0,0,118,116,1,0,0,0,118,119,1,0,0,0,119, - 9,1,0,0,0,120,118,1,0,0,0,121,122,5,1,0,0,122,123,3,46,23,0,123, - 124,5,18,0,0,124,11,1,0,0,0,125,126,5,2,0,0,126,127,5,25,0,0,127, - 128,3,32,16,0,128,129,5,18,0,0,129,13,1,0,0,0,130,131,5,3,0,0,131, - 132,3,42,21,0,132,134,5,24,0,0,133,135,3,30,15,0,134,133,1,0,0,0, - 134,135,1,0,0,0,135,137,1,0,0,0,136,138,5,20,0,0,137,136,1,0,0,0, - 138,139,1,0,0,0,139,137,1,0,0,0,139,140,1,0,0,0,140,15,1,0,0,0,141, - 145,5,4,0,0,142,144,3,40,20,0,143,142,1,0,0,0,144,147,1,0,0,0,145, - 143,1,0,0,0,145,146,1,0,0,0,146,148,1,0,0,0,147,145,1,0,0,0,148, - 149,5,18,0,0,149,17,1,0,0,0,150,151,5,5,0,0,151,152,3,46,23,0,152, - 153,3,44,22,0,153,154,5,18,0,0,154,19,1,0,0,0,155,156,5,6,0,0,156, - 157,3,48,24,0,157,158,5,18,0,0,158,21,1,0,0,0,159,160,5,7,0,0,160, - 161,3,44,22,0,161,162,5,18,0,0,162,23,1,0,0,0,163,165,5,8,0,0,164, - 166,3,30,15,0,165,164,1,0,0,0,165,166,1,0,0,0,166,168,1,0,0,0,167, - 169,5,20,0,0,168,167,1,0,0,0,169,170,1,0,0,0,170,168,1,0,0,0,170, - 171,1,0,0,0,171,25,1,0,0,0,172,176,5,9,0,0,173,175,3,34,17,0,174, - 173,1,0,0,0,175,178,1,0,0,0,176,174,1,0,0,0,176,177,1,0,0,0,177, - 179,1,0,0,0,178,176,1,0,0,0,179,180,5,18,0,0,180,27,1,0,0,0,181, - 182,5,10,0,0,182,183,3,46,23,0,183,189,5,14,0,0,184,185,3,48,24, - 0,185,186,3,34,17,0,186,188,1,0,0,0,187,184,1,0,0,0,188,191,1,0, - 0,0,189,187,1,0,0,0,189,190,1,0,0,0,190,192,1,0,0,0,191,189,1,0, - 0,0,192,193,5,18,0,0,193,29,1,0,0,0,194,195,5,21,0,0,195,31,1,0, - 0,0,196,197,5,26,0,0,197,33,1,0,0,0,198,200,3,50,25,0,199,198,1, - 0,0,0,199,200,1,0,0,0,200,201,1,0,0,0,201,207,3,44,22,0,202,203, - 5,14,0,0,203,205,3,36,18,0,204,206,3,38,19,0,205,204,1,0,0,0,205, - 206,1,0,0,0,206,208,1,0,0,0,207,202,1,0,0,0,207,208,1,0,0,0,208, - 35,1,0,0,0,209,210,3,44,22,0,210,211,5,14,0,0,211,212,3,44,22,0, - 212,37,1,0,0,0,213,214,5,16,0,0,214,215,3,44,22,0,215,39,1,0,0,0, - 216,217,3,44,22,0,217,218,5,14,0,0,218,219,3,44,22,0,219,220,5,14, - 0,0,220,221,3,44,22,0,221,41,1,0,0,0,222,223,5,22,0,0,223,43,1,0, - 0,0,224,225,5,11,0,0,225,45,1,0,0,0,226,227,7,0,0,0,227,47,1,0,0, - 0,228,229,7,1,0,0,229,49,1,0,0,0,230,231,5,15,0,0,231,51,1,0,0,0, - 25,53,56,61,66,72,78,80,85,90,92,98,103,109,113,118,134,139,145, - 165,170,176,189,199,205,207 + 7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,2,26,7,26, + 1,0,3,0,56,8,0,1,0,3,0,59,8,0,1,0,4,0,62,8,0,11,0,12,0,63,1,0,1, + 0,1,1,3,1,69,8,1,1,1,1,1,5,1,73,8,1,10,1,12,1,76,9,1,1,1,4,1,79, + 8,1,11,1,12,1,80,3,1,83,8,1,1,1,5,1,86,8,1,10,1,12,1,89,9,1,1,2, + 1,2,4,2,93,8,2,11,2,12,2,94,1,3,1,3,5,3,99,8,3,10,3,12,3,102,9,3, + 1,4,1,4,3,4,106,8,4,1,4,1,4,5,4,110,8,4,10,4,12,4,113,9,4,1,4,3, + 4,116,8,4,1,4,5,4,119,8,4,10,4,12,4,122,9,4,1,5,1,5,1,5,1,5,1,6, + 1,6,1,6,1,6,1,6,1,7,1,7,1,7,1,7,3,7,137,8,7,1,7,4,7,140,8,7,11,7, + 12,7,141,1,8,1,8,5,8,146,8,8,10,8,12,8,149,9,8,1,8,1,8,1,9,1,9,1, + 9,1,9,5,9,157,8,9,10,9,12,9,160,9,9,1,9,1,9,1,9,1,10,1,10,1,10,1, + 10,1,11,1,11,1,11,1,11,1,12,1,12,3,12,175,8,12,1,12,4,12,178,8,12, + 11,12,12,12,179,1,13,1,13,5,13,184,8,13,10,13,12,13,187,9,13,1,13, + 1,13,1,14,1,14,1,14,1,14,5,14,195,8,14,10,14,12,14,198,9,14,1,14, + 1,14,1,14,1,14,5,14,204,8,14,10,14,12,14,207,9,14,1,14,1,14,1,15, + 1,15,3,15,213,8,15,1,16,1,16,1,17,1,17,1,18,3,18,220,8,18,1,18,1, + 18,1,18,1,18,3,18,226,8,18,3,18,228,8,18,1,19,1,19,1,19,1,19,1,20, + 1,20,1,20,1,21,1,21,1,21,1,21,1,21,1,21,1,22,1,22,1,23,1,23,1,24, + 1,24,1,25,1,25,1,26,1,26,1,26,0,0,27,0,2,4,6,8,10,12,14,16,18,20, + 22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,0,2,1,0,13,14,2, + 0,13,13,15,15,253,0,55,1,0,0,0,2,68,1,0,0,0,4,92,1,0,0,0,6,96,1, + 0,0,0,8,103,1,0,0,0,10,123,1,0,0,0,12,127,1,0,0,0,14,132,1,0,0,0, + 16,143,1,0,0,0,18,152,1,0,0,0,20,164,1,0,0,0,22,168,1,0,0,0,24,172, + 1,0,0,0,26,181,1,0,0,0,28,190,1,0,0,0,30,212,1,0,0,0,32,214,1,0, + 0,0,34,216,1,0,0,0,36,219,1,0,0,0,38,229,1,0,0,0,40,233,1,0,0,0, + 42,236,1,0,0,0,44,242,1,0,0,0,46,244,1,0,0,0,48,246,1,0,0,0,50,248, + 1,0,0,0,52,250,1,0,0,0,54,56,5,20,0,0,55,54,1,0,0,0,55,56,1,0,0, + 0,56,58,1,0,0,0,57,59,3,10,5,0,58,57,1,0,0,0,58,59,1,0,0,0,59,61, + 1,0,0,0,60,62,3,2,1,0,61,60,1,0,0,0,62,63,1,0,0,0,63,61,1,0,0,0, + 63,64,1,0,0,0,64,65,1,0,0,0,65,66,5,0,0,1,66,1,1,0,0,0,67,69,3,12, + 6,0,68,67,1,0,0,0,68,69,1,0,0,0,69,82,1,0,0,0,70,74,3,4,2,0,71,73, + 3,8,4,0,72,71,1,0,0,0,73,76,1,0,0,0,74,72,1,0,0,0,74,75,1,0,0,0, + 75,83,1,0,0,0,76,74,1,0,0,0,77,79,3,8,4,0,78,77,1,0,0,0,79,80,1, + 0,0,0,80,78,1,0,0,0,80,81,1,0,0,0,81,83,1,0,0,0,82,70,1,0,0,0,82, + 78,1,0,0,0,83,87,1,0,0,0,84,86,3,28,14,0,85,84,1,0,0,0,86,89,1,0, + 0,0,87,85,1,0,0,0,87,88,1,0,0,0,88,3,1,0,0,0,89,87,1,0,0,0,90,93, + 3,6,3,0,91,93,3,18,9,0,92,90,1,0,0,0,92,91,1,0,0,0,93,94,1,0,0,0, + 94,92,1,0,0,0,94,95,1,0,0,0,95,5,1,0,0,0,96,100,3,14,7,0,97,99,3, + 16,8,0,98,97,1,0,0,0,99,102,1,0,0,0,100,98,1,0,0,0,100,101,1,0,0, + 0,101,7,1,0,0,0,102,100,1,0,0,0,103,105,3,20,10,0,104,106,3,22,11, + 0,105,104,1,0,0,0,105,106,1,0,0,0,106,107,1,0,0,0,107,111,3,24,12, + 0,108,110,3,16,8,0,109,108,1,0,0,0,110,113,1,0,0,0,111,109,1,0,0, + 0,111,112,1,0,0,0,112,115,1,0,0,0,113,111,1,0,0,0,114,116,3,26,13, + 0,115,114,1,0,0,0,115,116,1,0,0,0,116,120,1,0,0,0,117,119,3,18,9, + 0,118,117,1,0,0,0,119,122,1,0,0,0,120,118,1,0,0,0,120,121,1,0,0, + 0,121,9,1,0,0,0,122,120,1,0,0,0,123,124,5,1,0,0,124,125,3,48,24, + 0,125,126,5,20,0,0,126,11,1,0,0,0,127,128,5,2,0,0,128,129,5,27,0, + 0,129,130,3,34,17,0,130,131,5,20,0,0,131,13,1,0,0,0,132,133,5,3, + 0,0,133,134,3,44,22,0,134,136,5,26,0,0,135,137,3,32,16,0,136,135, + 1,0,0,0,136,137,1,0,0,0,137,139,1,0,0,0,138,140,5,22,0,0,139,138, + 1,0,0,0,140,141,1,0,0,0,141,139,1,0,0,0,141,142,1,0,0,0,142,15,1, + 0,0,0,143,147,5,4,0,0,144,146,3,42,21,0,145,144,1,0,0,0,146,149, + 1,0,0,0,147,145,1,0,0,0,147,148,1,0,0,0,148,150,1,0,0,0,149,147, + 1,0,0,0,150,151,5,20,0,0,151,17,1,0,0,0,152,153,5,5,0,0,153,158, + 3,48,24,0,154,155,5,18,0,0,155,157,3,30,15,0,156,154,1,0,0,0,157, + 160,1,0,0,0,158,156,1,0,0,0,158,159,1,0,0,0,159,161,1,0,0,0,160, + 158,1,0,0,0,161,162,3,46,23,0,162,163,5,20,0,0,163,19,1,0,0,0,164, + 165,5,6,0,0,165,166,3,50,25,0,166,167,5,20,0,0,167,21,1,0,0,0,168, + 169,5,7,0,0,169,170,3,46,23,0,170,171,5,20,0,0,171,23,1,0,0,0,172, + 174,5,8,0,0,173,175,3,32,16,0,174,173,1,0,0,0,174,175,1,0,0,0,175, + 177,1,0,0,0,176,178,5,22,0,0,177,176,1,0,0,0,178,179,1,0,0,0,179, + 177,1,0,0,0,179,180,1,0,0,0,180,25,1,0,0,0,181,185,5,9,0,0,182,184, + 3,36,18,0,183,182,1,0,0,0,184,187,1,0,0,0,185,183,1,0,0,0,185,186, + 1,0,0,0,186,188,1,0,0,0,187,185,1,0,0,0,188,189,5,20,0,0,189,27, + 1,0,0,0,190,191,5,10,0,0,191,196,3,48,24,0,192,193,5,18,0,0,193, + 195,3,30,15,0,194,192,1,0,0,0,195,198,1,0,0,0,196,194,1,0,0,0,196, + 197,1,0,0,0,197,199,1,0,0,0,198,196,1,0,0,0,199,205,5,16,0,0,200, + 201,3,50,25,0,201,202,3,36,18,0,202,204,1,0,0,0,203,200,1,0,0,0, + 204,207,1,0,0,0,205,203,1,0,0,0,205,206,1,0,0,0,206,208,1,0,0,0, + 207,205,1,0,0,0,208,209,5,20,0,0,209,29,1,0,0,0,210,213,5,11,0,0, + 211,213,5,12,0,0,212,210,1,0,0,0,212,211,1,0,0,0,213,31,1,0,0,0, + 214,215,5,23,0,0,215,33,1,0,0,0,216,217,5,28,0,0,217,35,1,0,0,0, + 218,220,3,52,26,0,219,218,1,0,0,0,219,220,1,0,0,0,220,221,1,0,0, + 0,221,227,3,46,23,0,222,223,5,16,0,0,223,225,3,38,19,0,224,226,3, + 40,20,0,225,224,1,0,0,0,225,226,1,0,0,0,226,228,1,0,0,0,227,222, + 1,0,0,0,227,228,1,0,0,0,228,37,1,0,0,0,229,230,3,46,23,0,230,231, + 5,16,0,0,231,232,3,46,23,0,232,39,1,0,0,0,233,234,5,18,0,0,234,235, + 3,46,23,0,235,41,1,0,0,0,236,237,3,46,23,0,237,238,5,16,0,0,238, + 239,3,46,23,0,239,240,5,16,0,0,240,241,3,46,23,0,241,43,1,0,0,0, + 242,243,5,24,0,0,243,45,1,0,0,0,244,245,5,13,0,0,245,47,1,0,0,0, + 246,247,7,0,0,0,247,49,1,0,0,0,248,249,7,1,0,0,249,51,1,0,0,0,250, + 251,5,17,0,0,251,53,1,0,0,0,28,55,58,63,68,74,80,82,87,92,94,100, + 105,111,115,120,136,141,147,158,174,179,185,196,205,212,219,225, + 227 ] class ObjectFileParser ( Parser ): @@ -102,14 +110,15 @@ class ObjectFileParser ( Parser ): literalNames = [ "", "'TARG'", "'FILE'", "'ABS'", "'LOC'", "'NTRY'", "'NAME'", "'ALIG'", "'DATA'", "'REL'", "'XTRN'", - "", "", "'$abs'", "", "'-'", - "'+'", "'.'" ] + "'WEAK'", "'LOCAL'", "", "", "'$abs'", + "", "'-'", "'+'", "'.'" ] symbolicNames = [ "", "TARG", "FILE", "ABS", "LOC", "NTRY", - "NAME", "ALIG", "DATA", "REL", "XTRN", "WORD", "WORD_WITH_DOTS", - "ABS_SECTION", "COLON", "MINUS", "PLUS", "DOT", "NEWLINE", - "WS", "NEWLINE_BYTES", "BYTES", "WORD_ABS", "WS_ABS", - "COLON_ABS", "SPACES_FILE", "FILEPATH" ] + "NAME", "ALIG", "DATA", "REL", "XTRN", "WEAK", "LOCAL", + "WORD", "WORD_WITH_DOTS", "ABS_SECTION", "COLON", + "MINUS", "PLUS", "DOT", "NEWLINE", "WS", "NEWLINE_BYTES", + "BYTES", "WORD_ABS", "WS_ABS", "COLON_ABS", "SPACES_FILE", + "FILEPATH" ] RULE_object_file = 0 RULE_object_block = 1 @@ -126,24 +135,26 @@ class ObjectFileParser ( Parser ): RULE_data_record = 12 RULE_rel_record = 13 RULE_xtrn_record = 14 - RULE_data = 15 - RULE_filepath = 16 - RULE_entry_usage = 17 - RULE_range = 18 - RULE_lower_part = 19 - RULE_location = 20 - RULE_abs_address = 21 - RULE_number = 22 - RULE_label = 23 - RULE_section = 24 - RULE_minus = 25 + RULE_attribute = 15 + RULE_data = 16 + RULE_filepath = 17 + RULE_entry_usage = 18 + RULE_range = 19 + RULE_lower_part = 20 + RULE_location = 21 + RULE_abs_address = 22 + RULE_number = 23 + RULE_label = 24 + RULE_section = 25 + RULE_minus = 26 ruleNames = [ "object_file", "object_block", "asect_block", "abs_block", "rsect_block", "targ_record", "source_record", "abs_record", "loc_record", "ntry_record", "name_record", "alig_record", - "data_record", "rel_record", "xtrn_record", "data", "filepath", - "entry_usage", "range", "lower_part", "location", "abs_address", - "number", "label", "section", "minus" ] + "data_record", "rel_record", "xtrn_record", "attribute", + "data", "filepath", "entry_usage", "range", "lower_part", + "location", "abs_address", "number", "label", "section", + "minus" ] EOF = Token.EOF TARG=1 @@ -156,22 +167,24 @@ class ObjectFileParser ( Parser ): DATA=8 REL=9 XTRN=10 - WORD=11 - WORD_WITH_DOTS=12 - ABS_SECTION=13 - COLON=14 - MINUS=15 - PLUS=16 - DOT=17 - NEWLINE=18 - WS=19 - NEWLINE_BYTES=20 - BYTES=21 - WORD_ABS=22 - WS_ABS=23 - COLON_ABS=24 - SPACES_FILE=25 - FILEPATH=26 + WEAK=11 + LOCAL=12 + WORD=13 + WORD_WITH_DOTS=14 + ABS_SECTION=15 + COLON=16 + MINUS=17 + PLUS=18 + DOT=19 + NEWLINE=20 + WS=21 + NEWLINE_BYTES=22 + BYTES=23 + WORD_ABS=24 + WS_ABS=25 + COLON_ABS=26 + SPACES_FILE=27 + FILEPATH=28 def __init__(self, input:TokenStream, output:TextIO = sys.stdout): super().__init__(input, output) @@ -225,35 +238,35 @@ def object_file(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 53 + self.state = 55 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==18: - self.state = 52 + if _la==20: + self.state = 54 self.match(ObjectFileParser.NEWLINE) - self.state = 56 + self.state = 58 self._errHandler.sync(self) _la = self._input.LA(1) if _la==1: - self.state = 55 + self.state = 57 self.targ_record() - self.state = 59 + self.state = 61 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 58 + self.state = 60 self.object_block() - self.state = 61 + self.state = 63 self._errHandler.sync(self) _la = self._input.LA(1) if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & 108) != 0)): break - self.state = 63 + self.state = 65 self.match(ObjectFileParser.EOF) except RecognitionException as re: localctx.exception = re @@ -312,44 +325,44 @@ def object_block(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 66 + self.state = 68 self._errHandler.sync(self) _la = self._input.LA(1) if _la==2: - self.state = 65 + self.state = 67 self.source_record() - self.state = 80 + self.state = 82 self._errHandler.sync(self) token = self._input.LA(1) if token in [3, 5]: - self.state = 68 + self.state = 70 self.asect_block() - self.state = 72 + self.state = 74 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,4,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 69 + self.state = 71 self.rsect_block() - self.state = 74 + self.state = 76 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,4,self._ctx) pass elif token in [6]: - self.state = 76 + self.state = 78 self._errHandler.sync(self) _alt = 1 while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt == 1: - self.state = 75 + self.state = 77 self.rsect_block() else: raise NoViableAltException(self) - self.state = 78 + self.state = 80 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,5,self._ctx) @@ -357,13 +370,13 @@ def object_block(self): else: raise NoViableAltException(self) - self.state = 85 + self.state = 87 self._errHandler.sync(self) _la = self._input.LA(1) while _la==10: - self.state = 82 + self.state = 84 self.xtrn_record() - self.state = 87 + self.state = 89 self._errHandler.sync(self) _la = self._input.LA(1) @@ -415,20 +428,20 @@ def asect_block(self): self.enterRule(localctx, 4, self.RULE_asect_block) try: self.enterOuterAlt(localctx, 1) - self.state = 90 + self.state = 92 self._errHandler.sync(self) _alt = 1 while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt == 1: - self.state = 90 + self.state = 92 self._errHandler.sync(self) token = self._input.LA(1) if token in [3]: - self.state = 88 + self.state = 90 self.abs_block() pass elif token in [5]: - self.state = 89 + self.state = 91 self.ntry_record() pass else: @@ -437,7 +450,7 @@ def asect_block(self): else: raise NoViableAltException(self) - self.state = 92 + self.state = 94 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,9,self._ctx) @@ -487,15 +500,15 @@ def abs_block(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 94 + self.state = 96 self.abs_record() - self.state = 98 + self.state = 100 self._errHandler.sync(self) _la = self._input.LA(1) while _la==4: - self.state = 95 + self.state = 97 self.loc_record() - self.state = 100 + self.state = 102 self._errHandler.sync(self) _la = self._input.LA(1) @@ -564,44 +577,44 @@ def rsect_block(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 101 - self.name_record() self.state = 103 + self.name_record() + self.state = 105 self._errHandler.sync(self) _la = self._input.LA(1) if _la==7: - self.state = 102 + self.state = 104 self.alig_record() - self.state = 105 + self.state = 107 self.data_record() - self.state = 109 + self.state = 111 self._errHandler.sync(self) _la = self._input.LA(1) while _la==4: - self.state = 106 + self.state = 108 self.loc_record() - self.state = 111 + self.state = 113 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 113 + self.state = 115 self._errHandler.sync(self) _la = self._input.LA(1) if _la==9: - self.state = 112 + self.state = 114 self.rel_record() - self.state = 118 + self.state = 120 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,14,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 115 + self.state = 117 self.ntry_record() - self.state = 120 + self.state = 122 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,14,self._ctx) @@ -649,11 +662,11 @@ def targ_record(self): self.enterRule(localctx, 10, self.RULE_targ_record) try: self.enterOuterAlt(localctx, 1) - self.state = 121 + self.state = 123 self.match(ObjectFileParser.TARG) - self.state = 122 + self.state = 124 self.label() - self.state = 123 + self.state = 125 self.match(ObjectFileParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -702,13 +715,13 @@ def source_record(self): self.enterRule(localctx, 12, self.RULE_source_record) try: self.enterOuterAlt(localctx, 1) - self.state = 125 + self.state = 127 self.match(ObjectFileParser.FILE) - self.state = 126 + self.state = 128 self.match(ObjectFileParser.SPACES_FILE) - self.state = 127 + self.state = 129 self.filepath() - self.state = 128 + self.state = 130 self.match(ObjectFileParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -765,30 +778,30 @@ def abs_record(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 130 + self.state = 132 self.match(ObjectFileParser.ABS) - self.state = 131 + self.state = 133 self.abs_address() - self.state = 132 - self.match(ObjectFileParser.COLON_ABS) self.state = 134 + self.match(ObjectFileParser.COLON_ABS) + self.state = 136 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==21: - self.state = 133 + if _la==23: + self.state = 135 self.data() - self.state = 137 + self.state = 139 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 136 + self.state = 138 self.match(ObjectFileParser.NEWLINE_BYTES) - self.state = 139 + self.state = 141 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==20): + if not (_la==22): break except RecognitionException as re: @@ -839,19 +852,19 @@ def loc_record(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 141 + self.state = 143 self.match(ObjectFileParser.LOC) - self.state = 145 + self.state = 147 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==11: - self.state = 142 + while _la==13: + self.state = 144 self.location() - self.state = 147 + self.state = 149 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 148 + self.state = 150 self.match(ObjectFileParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -883,6 +896,19 @@ def number(self): def NEWLINE(self): return self.getToken(ObjectFileParser.NEWLINE, 0) + def PLUS(self, i:int=None): + if i is None: + return self.getTokens(ObjectFileParser.PLUS) + else: + return self.getToken(ObjectFileParser.PLUS, i) + + def attribute(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(ObjectFileParser.AttributeContext) + else: + return self.getTypedRuleContext(ObjectFileParser.AttributeContext,i) + + def getRuleIndex(self): return ObjectFileParser.RULE_ntry_record @@ -899,15 +925,28 @@ def ntry_record(self): localctx = ObjectFileParser.Ntry_recordContext(self, self._ctx, self.state) self.enterRule(localctx, 18, self.RULE_ntry_record) + self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 150 + self.state = 152 self.match(ObjectFileParser.NTRY) - self.state = 151 + self.state = 153 self.label() - self.state = 152 + self.state = 158 + self._errHandler.sync(self) + _la = self._input.LA(1) + while _la==18: + self.state = 154 + self.match(ObjectFileParser.PLUS) + self.state = 155 + self.attribute() + self.state = 160 + self._errHandler.sync(self) + _la = self._input.LA(1) + + self.state = 161 self.number() - self.state = 153 + self.state = 162 self.match(ObjectFileParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -953,11 +992,11 @@ def name_record(self): self.enterRule(localctx, 20, self.RULE_name_record) try: self.enterOuterAlt(localctx, 1) - self.state = 155 + self.state = 164 self.match(ObjectFileParser.NAME) - self.state = 156 + self.state = 165 self.section() - self.state = 157 + self.state = 166 self.match(ObjectFileParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -1003,11 +1042,11 @@ def alig_record(self): self.enterRule(localctx, 22, self.RULE_alig_record) try: self.enterOuterAlt(localctx, 1) - self.state = 159 + self.state = 168 self.match(ObjectFileParser.ALIG) - self.state = 160 + self.state = 169 self.number() - self.state = 161 + self.state = 170 self.match(ObjectFileParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -1057,26 +1096,26 @@ def data_record(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 163 + self.state = 172 self.match(ObjectFileParser.DATA) - self.state = 165 + self.state = 174 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==21: - self.state = 164 + if _la==23: + self.state = 173 self.data() - self.state = 168 + self.state = 177 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 167 + self.state = 176 self.match(ObjectFileParser.NEWLINE_BYTES) - self.state = 170 + self.state = 179 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==20): + if not (_la==22): break except RecognitionException as re: @@ -1127,19 +1166,19 @@ def rel_record(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 172 + self.state = 181 self.match(ObjectFileParser.REL) - self.state = 176 + self.state = 185 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==11 or _la==15: - self.state = 173 + while _la==13 or _la==17: + self.state = 182 self.entry_usage() - self.state = 178 + self.state = 187 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 179 + self.state = 188 self.match(ObjectFileParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -1170,6 +1209,19 @@ def COLON(self): def NEWLINE(self): return self.getToken(ObjectFileParser.NEWLINE, 0) + def PLUS(self, i:int=None): + if i is None: + return self.getTokens(ObjectFileParser.PLUS) + else: + return self.getToken(ObjectFileParser.PLUS, i) + + def attribute(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(ObjectFileParser.AttributeContext) + else: + return self.getTypedRuleContext(ObjectFileParser.AttributeContext,i) + + def section(self, i:int=None): if i is None: return self.getTypedRuleContexts(ObjectFileParser.SectionContext) @@ -1203,25 +1255,37 @@ def xtrn_record(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 181 + self.state = 190 self.match(ObjectFileParser.XTRN) - self.state = 182 + self.state = 191 self.label() - self.state = 183 + self.state = 196 + self._errHandler.sync(self) + _la = self._input.LA(1) + while _la==18: + self.state = 192 + self.match(ObjectFileParser.PLUS) + self.state = 193 + self.attribute() + self.state = 198 + self._errHandler.sync(self) + _la = self._input.LA(1) + + self.state = 199 self.match(ObjectFileParser.COLON) - self.state = 189 + self.state = 205 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==11 or _la==13: - self.state = 184 + while _la==13 or _la==15: + self.state = 200 self.section() - self.state = 185 + self.state = 201 self.entry_usage() - self.state = 191 + self.state = 207 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 192 + self.state = 208 self.match(ObjectFileParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -1232,6 +1296,88 @@ def xtrn_record(self): return localctx + class AttributeContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + + def getRuleIndex(self): + return ObjectFileParser.RULE_attribute + + + def copyFrom(self, ctx:ParserRuleContext): + super().copyFrom(ctx) + + + + class WeakContext(AttributeContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a ObjectFileParser.AttributeContext + super().__init__(parser) + self.copyFrom(ctx) + + def WEAK(self): + return self.getToken(ObjectFileParser.WEAK, 0) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitWeak" ): + return visitor.visitWeak(self) + else: + return visitor.visitChildren(self) + + + class LocalContext(AttributeContext): + + def __init__(self, parser, ctx:ParserRuleContext): # actually a ObjectFileParser.AttributeContext + super().__init__(parser) + self.copyFrom(ctx) + + def LOCAL(self): + return self.getToken(ObjectFileParser.LOCAL, 0) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitLocal" ): + return visitor.visitLocal(self) + else: + return visitor.visitChildren(self) + + + + def attribute(self): + + localctx = ObjectFileParser.AttributeContext(self, self._ctx, self.state) + self.enterRule(localctx, 30, self.RULE_attribute) + try: + self.state = 212 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [11]: + localctx = ObjectFileParser.WeakContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 210 + self.match(ObjectFileParser.WEAK) + pass + elif token in [12]: + localctx = ObjectFileParser.LocalContext(self, localctx) + self.enterOuterAlt(localctx, 2) + self.state = 211 + self.match(ObjectFileParser.LOCAL) + pass + else: + raise NoViableAltException(self) + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class DataContext(ParserRuleContext): __slots__ = 'parser' @@ -1257,10 +1403,10 @@ def accept(self, visitor:ParseTreeVisitor): def data(self): localctx = ObjectFileParser.DataContext(self, self._ctx, self.state) - self.enterRule(localctx, 30, self.RULE_data) + self.enterRule(localctx, 32, self.RULE_data) try: self.enterOuterAlt(localctx, 1) - self.state = 194 + self.state = 214 self.match(ObjectFileParser.BYTES) except RecognitionException as re: localctx.exception = re @@ -1296,10 +1442,10 @@ def accept(self, visitor:ParseTreeVisitor): def filepath(self): localctx = ObjectFileParser.FilepathContext(self, self._ctx, self.state) - self.enterRule(localctx, 32, self.RULE_filepath) + self.enterRule(localctx, 34, self.RULE_filepath) try: self.enterOuterAlt(localctx, 1) - self.state = 196 + self.state = 216 self.match(ObjectFileParser.FILEPATH) except RecognitionException as re: localctx.exception = re @@ -1351,33 +1497,33 @@ def accept(self, visitor:ParseTreeVisitor): def entry_usage(self): localctx = ObjectFileParser.Entry_usageContext(self, self._ctx, self.state) - self.enterRule(localctx, 34, self.RULE_entry_usage) + self.enterRule(localctx, 36, self.RULE_entry_usage) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 199 + self.state = 219 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==15: - self.state = 198 + if _la==17: + self.state = 218 self.minus() - self.state = 201 + self.state = 221 self.number() - self.state = 207 + self.state = 227 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==14: - self.state = 202 + if _la==16: + self.state = 222 self.match(ObjectFileParser.COLON) - self.state = 203 + self.state = 223 self.range_() - self.state = 205 + self.state = 225 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==16: - self.state = 204 + if _la==18: + self.state = 224 self.lower_part() @@ -1424,14 +1570,14 @@ def accept(self, visitor:ParseTreeVisitor): def range_(self): localctx = ObjectFileParser.RangeContext(self, self._ctx, self.state) - self.enterRule(localctx, 36, self.RULE_range) + self.enterRule(localctx, 38, self.RULE_range) try: self.enterOuterAlt(localctx, 1) - self.state = 209 + self.state = 229 self.number() - self.state = 210 + self.state = 230 self.match(ObjectFileParser.COLON) - self.state = 211 + self.state = 231 self.number() except RecognitionException as re: localctx.exception = re @@ -1471,12 +1617,12 @@ def accept(self, visitor:ParseTreeVisitor): def lower_part(self): localctx = ObjectFileParser.Lower_partContext(self, self._ctx, self.state) - self.enterRule(localctx, 38, self.RULE_lower_part) + self.enterRule(localctx, 40, self.RULE_lower_part) try: self.enterOuterAlt(localctx, 1) - self.state = 213 + self.state = 233 self.match(ObjectFileParser.PLUS) - self.state = 214 + self.state = 234 self.number() except RecognitionException as re: localctx.exception = re @@ -1522,18 +1668,18 @@ def accept(self, visitor:ParseTreeVisitor): def location(self): localctx = ObjectFileParser.LocationContext(self, self._ctx, self.state) - self.enterRule(localctx, 40, self.RULE_location) + self.enterRule(localctx, 42, self.RULE_location) try: self.enterOuterAlt(localctx, 1) - self.state = 216 + self.state = 236 self.number() - self.state = 217 + self.state = 237 self.match(ObjectFileParser.COLON) - self.state = 218 + self.state = 238 self.number() - self.state = 219 + self.state = 239 self.match(ObjectFileParser.COLON) - self.state = 220 + self.state = 240 self.number() except RecognitionException as re: localctx.exception = re @@ -1569,10 +1715,10 @@ def accept(self, visitor:ParseTreeVisitor): def abs_address(self): localctx = ObjectFileParser.Abs_addressContext(self, self._ctx, self.state) - self.enterRule(localctx, 42, self.RULE_abs_address) + self.enterRule(localctx, 44, self.RULE_abs_address) try: self.enterOuterAlt(localctx, 1) - self.state = 222 + self.state = 242 self.match(ObjectFileParser.WORD_ABS) except RecognitionException as re: localctx.exception = re @@ -1608,10 +1754,10 @@ def accept(self, visitor:ParseTreeVisitor): def number(self): localctx = ObjectFileParser.NumberContext(self, self._ctx, self.state) - self.enterRule(localctx, 44, self.RULE_number) + self.enterRule(localctx, 46, self.RULE_number) try: self.enterOuterAlt(localctx, 1) - self.state = 224 + self.state = 244 self.match(ObjectFileParser.WORD) except RecognitionException as re: localctx.exception = re @@ -1650,13 +1796,13 @@ def accept(self, visitor:ParseTreeVisitor): def label(self): localctx = ObjectFileParser.LabelContext(self, self._ctx, self.state) - self.enterRule(localctx, 46, self.RULE_label) + self.enterRule(localctx, 48, self.RULE_label) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 226 + self.state = 246 _la = self._input.LA(1) - if not(_la==11 or _la==12): + if not(_la==13 or _la==14): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) @@ -1698,13 +1844,13 @@ def accept(self, visitor:ParseTreeVisitor): def section(self): localctx = ObjectFileParser.SectionContext(self, self._ctx, self.state) - self.enterRule(localctx, 48, self.RULE_section) + self.enterRule(localctx, 50, self.RULE_section) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 228 + self.state = 248 _la = self._input.LA(1) - if not(_la==11 or _la==13): + if not(_la==13 or _la==15): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) @@ -1743,10 +1889,10 @@ def accept(self, visitor:ParseTreeVisitor): def minus(self): localctx = ObjectFileParser.MinusContext(self, self._ctx, self.state) - self.enterRule(localctx, 50, self.RULE_minus) + self.enterRule(localctx, 52, self.RULE_minus) try: self.enterOuterAlt(localctx, 1) - self.state = 230 + self.state = 250 self.match(ObjectFileParser.MINUS) except RecognitionException as re: localctx.exception = re diff --git a/cocas/object_file/generated/ObjectFileParserVisitor.py b/cocas/object_file/generated/ObjectFileParserVisitor.py index f88dddd7..5d97f60f 100644 --- a/cocas/object_file/generated/ObjectFileParserVisitor.py +++ b/cocas/object_file/generated/ObjectFileParserVisitor.py @@ -84,6 +84,16 @@ def visitXtrn_record(self, ctx:ObjectFileParser.Xtrn_recordContext): return self.visitChildren(ctx) + # Visit a parse tree produced by ObjectFileParser#Weak. + def visitWeak(self, ctx:ObjectFileParser.WeakContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by ObjectFileParser#Local. + def visitLocal(self, ctx:ObjectFileParser.LocalContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ObjectFileParser#data. def visitData(self, ctx:ObjectFileParser.DataContext): return self.visitChildren(ctx) diff --git a/cocas/object_file/grammar/ObjectFileLexer.g4 b/cocas/object_file/grammar/ObjectFileLexer.g4 index 9fd9492c..76c096f4 100644 --- a/cocas/object_file/grammar/ObjectFileLexer.g4 +++ b/cocas/object_file/grammar/ObjectFileLexer.g4 @@ -11,6 +11,9 @@ DATA: 'DATA' -> pushMode(IN_BYTES); REL : 'REL'; XTRN: 'XTRN'; +WEAK: 'WEAK'; +LOCAL: 'LOCAL'; + WORD: [a-zA-Z_0-9]+; WORD_WITH_DOTS : [a-zA-Z_][a-zA-Z_0-9]* DOT [a-zA-Z_0-9.]* [a-zA-Z_0-9]; ABS_SECTION: '$abs'; @@ -37,4 +40,4 @@ mode IN_FILE; SPACES_FILE: ' '+ -> popMode, pushMode(IN_FILEPATH); mode IN_FILEPATH; -FILEPATH: ~[\r\n]+ -> popMode; \ No newline at end of file +FILEPATH: ~[\r\n]+ -> popMode; diff --git a/cocas/object_file/grammar/ObjectFileParser.g4 b/cocas/object_file/grammar/ObjectFileParser.g4 index ae4720c6..dd5041b5 100644 --- a/cocas/object_file/grammar/ObjectFileParser.g4 +++ b/cocas/object_file/grammar/ObjectFileParser.g4 @@ -40,13 +40,17 @@ targ_record: TARG label NEWLINE; source_record: FILE SPACES_FILE filepath NEWLINE; abs_record: ABS abs_address COLON_ABS data? NEWLINE_BYTES+; loc_record: LOC location* NEWLINE; -ntry_record: NTRY label number NEWLINE; +ntry_record: NTRY label (PLUS attribute)* number NEWLINE; name_record: NAME section NEWLINE; alig_record: ALIG number NEWLINE; data_record: DATA data? NEWLINE_BYTES+; rel_record: REL entry_usage* NEWLINE; -xtrn_record: XTRN label COLON (section entry_usage)* NEWLINE; +xtrn_record: XTRN label (PLUS attribute)* COLON (section entry_usage)* NEWLINE; +attribute + : WEAK # Weak + | LOCAL # Local + ; data: BYTES; filepath: FILEPATH; entry_usage: minus? number (COLON range lower_part?)?; From d171257c3434be6f1b28ff048b12e334d5f26212 Mon Sep 17 00:00:00 2001 From: Proletcultist Date: Wed, 28 Jan 2026 10:33:00 +0700 Subject: [PATCH 07/42] [cocas] Added processing of XTRN and NTRY attributes during object import --- cocas/object_file/object_import.py | 36 ++++++++++++++++------- cocas/object_module/__init__.py | 3 +- cocas/object_module/attributes.py | 2 +- cocas/object_module/entry.py | 1 + cocas/object_module/external_entry_key.py | 30 +++++++++++++++++++ cocas/object_module/object_module.py | 1 + 6 files changed, 61 insertions(+), 12 deletions(-) create mode 100644 cocas/object_module/external_entry_key.py diff --git a/cocas/object_file/object_import.py b/cocas/object_file/object_import.py index 26a813a1..38569107 100644 --- a/cocas/object_file/object_import.py +++ b/cocas/object_file/object_import.py @@ -6,7 +6,7 @@ import antlr4 from antlr4 import CommonTokenStream, InputStream -from cocas.object_module import CodeLocation, ExternalEntry, ObjectModule, ObjectSectionRecord +from cocas.object_module import CodeLocation, ExternalEntry, ObjectModule, ObjectSectionRecord, Linkage, Attributes, Entry, ExternalEntryKey from .exceptions import AntlrErrorListener, ObjectFileException from .generated import ObjectFileLexer, ObjectFileParser, ObjectFileParserVisitor @@ -60,7 +60,7 @@ def visitObject_block(self, ctx: ObjectFileParser.Object_blockContext) -> Object xtrn: ObjectFileParser.Xtrn_recordContext for xtrn in ctx.xtrn_record(): - label, entries = self.visitXtrn_record(xtrn) + label, entries, attributes = self.visitXtrn_record(xtrn) for sect, entry in entries: if sect == '$abs': if not asects: @@ -68,9 +68,9 @@ def visitObject_block(self, ctx: ObjectFileParser.Object_blockContext) -> Object 'No absolute sections found, but needed for xtrn entry') # what is this? ind = max(bisect.bisect_right(asect_addr, entry.offset) - 1, 0) - asects[asect_addr[ind]].external[label].append(entry) + asects[asect_addr[ind]].external[ExternalEntryKey(label, attributes)].append(entry) elif sect in rsects: - rsects[sect].external[label].append(entry) + rsects[sect].external[ExternalEntryKey(label, attributes)].append(entry) else: raise ObjectFileException(self.file, xtrn.start.line, f'Section not found: {sect}') if filename: @@ -92,9 +92,9 @@ def visitAsect_block(self, ctx: ObjectFileParser.Asect_blockContext): if not asects and ctx.ntry_record(): asects[0] = ObjectSectionRecord('$abs', 0, bytearray(), {}, [], {}, 1) asect_addr = sorted(asects.keys()) - for label, addr in map(self.visitNtry_record, ctx.ntry_record()): + for label, addr, attributes in map(self.visitNtry_record, ctx.ntry_record()): ind = max(bisect.bisect_right(asect_addr, addr) - 1, 0) - asects[asect_addr[ind]].entries[label] = addr + asects[asect_addr[ind]].entries[label] = Entry(addr, attributes) return asects, asect_addr def visitAbs_block(self, ctx: ObjectFileParser.Abs_blockContext): @@ -116,8 +116,8 @@ def visitRsect_block(self, ctx: ObjectFileParser.Rsect_blockContext): else: rel = [] entries = {} - for label, address in map(self.visitNtry_record, ctx.ntry_record()): - entries[label] = address + for label, address, attributes in map(self.visitNtry_record, ctx.ntry_record()): + entries[label] = Entry(address, attributes) code_locations = {} for cl in map(self.visitLoc_record, ctx.loc_record()): code_locations |= cl @@ -140,10 +140,25 @@ def visitLoc_record(self, ctx: ObjectFileParser.Loc_recordContext): res[byte] = CodeLocation(None, line, col) return res + def visitWeak(self, ctx: ObjectFileParser.WeakContext): + return Attributes.WEAK + + def visitLocal(self, ctx: ObjectFileParser.LocalContext): + return Attributes.LOCAL + + def visitAttributes(self, attributes: list[ObjectFileParser.AttributeContext]): + parsed = list(map(self.visit, attributes)) + + if Attributes.WEAK in parsed and Attributes.LOCAL in parsed: + raise ObjectFileException(self.file, attributes[0].start.line, 'Symbol cannot have WEAK and LOCAL attributes at the same time') + + return parsed + def visitNtry_record(self, ctx: ObjectFileParser.Ntry_recordContext): label = self.visitLabel(ctx.label()) address = self.visitNumber(ctx.number()) - return label, address + attributes = self.visitAttributes(ctx.attribute()) + return label, address, attributes def visitName_record(self, ctx: ObjectFileParser.Name_recordContext): return self.visitSection(ctx.section()) @@ -164,7 +179,8 @@ def visitXtrn_record(self, ctx: ObjectFileParser.Xtrn_recordContext): label = self.visitLabel(ctx.label()) entries = [(self.visitSection(n), self.visitEntry_usage(e)) for (n, e) in zip(ctx.section(), ctx.entry_usage())] - return label, entries + attributes = self.visitAttributes(ctx.attribute()) + return label, entries, attributes def parse_byte(self, byte: str, ctx: ObjectFileParser.DataContext): try: diff --git a/cocas/object_module/__init__.py b/cocas/object_module/__init__.py index faac2cda..6fabe249 100644 --- a/cocas/object_module/__init__.py +++ b/cocas/object_module/__init__.py @@ -5,5 +5,6 @@ from .location import CodeLocation from .object_module import ObjectModule, ObjectSectionRecord from .linkage import Linkage -from .attributes import Attributes from .entry import Entry +from .attributes import Attributes +from .external_entry_key import ExternalEntryKey diff --git a/cocas/object_module/attributes.py b/cocas/object_module/attributes.py index 95823fa5..8cb666f2 100644 --- a/cocas/object_module/attributes.py +++ b/cocas/object_module/attributes.py @@ -15,4 +15,4 @@ def __str__(self): return "" case _: pass # do something - \ No newline at end of file + diff --git a/cocas/object_module/entry.py b/cocas/object_module/entry.py index 1ad4f425..bd5287dd 100644 --- a/cocas/object_module/entry.py +++ b/cocas/object_module/entry.py @@ -27,3 +27,4 @@ def __str__(self): def __repr__(self): return str(self) + diff --git a/cocas/object_module/external_entry_key.py b/cocas/object_module/external_entry_key.py new file mode 100644 index 00000000..7e708d16 --- /dev/null +++ b/cocas/object_module/external_entry_key.py @@ -0,0 +1,30 @@ +from .attributes import Attributes + +class ExternalEntryKey: + """Describes the key for adding ExternalEntry objects to a dictionary. + Contains the label name, attributes, sorted in non-descending order, anb + their string representation.""" + def __init__(self, label: str, attrs: list(Attributes)): + self.label: str = label + self.attrs: attrs = sorted(attrs) + self.key = label + + if len(self.attrs) > 0: + # ATTR1 +ATTR2 ... +ATTRn + string = " +".join(map(str, self.attrs)) + # label +ATTR1 +ATTR2 ... +ATTRn + self.key += f"+{string}" + + def __hash__(self): + return hash(self.key) + + def __eq__(self, other): + if not isinstance(other, type(self)): + return False + return self.key == self.key + + def __str__(self): + return self.key + + def __repr__(self): + return str(self) diff --git a/cocas/object_module/object_module.py b/cocas/object_module/object_module.py index 8cba8fef..fbacec02 100644 --- a/cocas/object_module/object_module.py +++ b/cocas/object_module/object_module.py @@ -4,6 +4,7 @@ from typing import Union from .external_entry import ExternalEntry +from .external_entry_key import ExternalEntryKey from .location import CodeLocation from .entry import Entry From 7554ae6ef8a9b15bbdd4966dd658adf4e48b91ab Mon Sep 17 00:00:00 2001 From: Proletcultist Date: Wed, 28 Jan 2026 10:37:17 +0700 Subject: [PATCH 08/42] [cocas] Changed linker functions to hold new/modified classes --- cocas/linker/linker.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cocas/linker/linker.py b/cocas/linker/linker.py index c32074c5..a9847b05 100644 --- a/cocas/linker/linker.py +++ b/cocas/linker/linker.py @@ -68,7 +68,7 @@ def find_exts_by_sect(sects: list[ObjectSectionRecord]): exts_by_sect = dict() for sect in sects: exts = exts_by_sect.setdefault(sect.name, set()) - exts |= set(sect.external.keys()) + exts |= set(map(lambda k: k.label, sect.external.keys())) return exts_by_sect @@ -161,7 +161,7 @@ def link(objects: list[tuple[Any, ObjectModule]], image_size: Optional[int] = No lower_limit = 1 << 8 * entry.entry_bytes.start val = int.from_bytes(image[pos:pos + len(entry.entry_bytes)], 'little', signed=False) * lower_limit val += entry.lower_part + lower_parts.get(entry.offset, 0) - val += ents[ext_name] * entry.sign + val += ents[ext_name.label] * entry.sign val %= (1 << 8 * entry.entry_bytes.stop) image[pos:pos + len(entry.entry_bytes)] = \ (val // lower_limit).to_bytes(len(entry.entry_bytes), 'little', signed=False) From c7376e8bd77897bbfa2ef92ce7b926b052ddc1b7 Mon Sep 17 00:00:00 2001 From: Proletcultist Date: Thu, 29 Jan 2026 11:41:47 +0700 Subject: [PATCH 09/42] [cocas] Commented check for labels collision in concat_rsects --- cocas/object_module/concat_rsects.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/cocas/object_module/concat_rsects.py b/cocas/object_module/concat_rsects.py index 1405e6ce..db48a142 100644 --- a/cocas/object_module/concat_rsects.py +++ b/cocas/object_module/concat_rsects.py @@ -2,6 +2,8 @@ from math import lcm from typing import TYPE_CHECKING, Iterable +from .entry import Entry + if TYPE_CHECKING: from cocas.object_module import ObjectSectionRecord @@ -32,10 +34,10 @@ def concat_rsects(rsects: Iterable["ObjectSectionRecord"]) -> list["ObjectSectio prev_size = (prev_size + rsect.alignment - 1) // rsect.alignment * rsect.alignment new.data.extend(bytearray(prev_size - len(new.data))) new.data += rsect.data - same_entries = new.entries.keys() & rsect.entries.keys() - if same_entries: - raise ValueError(f"Two sections with same name {name} declare label {next(iter(same_entries))}") - new.entries.update({entry_name: entry.address + prev_size for entry_name, entry in rsect.entries.items()}) + # same_entries = new.entries.keys() & rsect.entries.keys() + # if same_entries: + # raise ValueError(f"Two sections with same name {name} declare label {next(iter(same_entries))}") + new.entries.update({name: Entry(entry.address + prev_size, entry.attrs) for name, entry in rsect.entries.items()}) for pos, loc in rsect.code_locations.items(): new.code_locations[pos + prev_size] = loc for label, exts in rsect.external.items(): From 02f416aeb188e50d3a5dd139d0c5e2e6291e2eca Mon Sep 17 00:00:00 2001 From: Proletcultist Date: Thu, 29 Jan 2026 11:42:18 +0700 Subject: [PATCH 10/42] [cocas] Added holding of weak and file-local symbols during linkage --- cocas/linker/linker.py | 127 +++++++++++++++++++++++++---------------- 1 file changed, 77 insertions(+), 50 deletions(-) diff --git a/cocas/linker/linker.py b/cocas/linker/linker.py index a9847b05..7c0cba0a 100644 --- a/cocas/linker/linker.py +++ b/cocas/linker/linker.py @@ -1,8 +1,8 @@ import itertools from math import inf -from typing import Any, Optional +from typing import Any, Optional, Iterable -from cocas.object_module import CodeLocation, ObjectModule, ObjectSectionRecord, concat_rsects +from cocas.object_module import CodeLocation, ObjectModule, ObjectSectionRecord, concat_rsects, Attributes from .exceptions import LinkerException from .targets import TargetParams, import_target @@ -34,7 +34,6 @@ def init_bins(asects: list[ObjectSectionRecord], image_size: Optional[int]): return rsect_bins - def place_sects(rsects: list[ObjectSectionRecord], rsect_bins: list, image_size) -> dict[str, int]: sect_addresses = {'$abs': 0} for rsect in rsects: @@ -54,49 +53,67 @@ def place_sects(rsects: list[ObjectSectionRecord], rsect_bins: list, image_size) return sect_addresses -def gather_ents(sects: list[ObjectSectionRecord], sect_addresses: dict[str, int]): - ents = dict() - for sect in sects: - for ent_name in sect.entries: - if ent_name in ents: - raise LinkerException(f'Duplicate entries "{ent_name}"') - ents[ent_name] = sect.entries[ent_name].address + sect_addresses[sect.name] - return ents - - -def find_exts_by_sect(sects: list[ObjectSectionRecord]): - exts_by_sect = dict() - for sect in sects: - exts = exts_by_sect.setdefault(sect.name, set()) - exts |= set(map(lambda k: k.label, sect.external.keys())) - return exts_by_sect - - -def find_sect_by_ent(sects: list[ObjectSectionRecord]): - sect_by_ent = dict() - for sect in sects: - for ent_name in sect.entries: - if ent_name in sect_by_ent: - raise LinkerException(f"Entry {ent_name} is declared in multiple sections") - sect_by_ent[ent_name] = sect.name - return sect_by_ent - - -def find_referenced_sects(exts_by_sect: dict[str, set[str]], sect_by_ent: dict[str, str]): - used_sects_queue = ['$abs'] - used_sects = {'$abs'} +def find_referenced_sects(asects: list[ObjectSectionRecord], entry_by_ext: dict[int, (ObjectSectionRecord, Entry)]): + used_sects_queue = asects.copy() + used_sects = [] i = 0 while i < len(used_sects_queue): - if used_sects_queue[i] in exts_by_sect: - for ext_name in exts_by_sect[used_sects_queue[i]]: - if ext_name not in sect_by_ent: - raise LinkerException(f'Unresolved ext "{ext_name}"') - new_sect = sect_by_ent[ext_name] - if new_sect not in used_sects: - used_sects_queue.append(new_sect) - used_sects.add(new_sect) + sect = used_sects_queue[i] + used_sects.append(sect) + + for ext in sect.external: + if not entry_by_ext[id(ext)] is None and not entry_by_ext[id(ext)][0] in used_sects_queue: + used_sects_queue.append(entry_by_ext[id(ext)][0]) i += 1 return used_sects + + +def find_entries_for_exts(modules: list[ObjectModule]): + # ret: id(ExternalEntryKey) -> (section, entry) + ret: dict[int, (ObjectSectionRecord, Entry)] = {} + + # modules_scope: id(ObjectModule) -> (label -> (section, entry)) + modules_scope: dict[int, dict[str, (ObjectSectionRecord, Entry)]] = {} + global_scope: dict[str, (ObjectSectionRecord, Entry)] = {} + weak_global_scope: dict[str, list[(ObjectSectionRecord, Entry)]] = {} + + for module in modules: + for sect in (module.rsects + module.asects): + for name, entry in sect.entries.items(): + if Attributes.LOCAL in entry.attrs: + if id(module) in modules_scope and name in modules_scope[id(module)]: + raise LinkerException(f"File-local entry {name} is declared in multiple sections of the same object module") + modules_scope.setdefault(id(module), {})[name] = (sect, entry) + elif Attributes.WEAK in entry.attrs: + weak_global_scope.setdefault(name, []).append((sect, entry)) + else: + if name in global_scope: + raise LinkerException(f"Global entry {name} is declared in multiple sections") + global_scope[name] = (sect, entry) + + for module in modules: + for sect in (module.rsects + module.asects): + for ext in sect.external: + if Attributes.LOCAL in ext.attrs: + if (not id(module) in modules_scope) or (not ext.label in modules_scope[id(module)]): + raise LinkerException(f'Unresolved file-local ext "{ext.label}"') + ret[id(ext)] = modules_scope[id(module)][ext.label] + elif Attributes.WEAK in ext.attrs: + if ext.label in global_scope: + ret[id(ext)] = global_scope[ext.label] + elif ext.label in weak_global_scope: + ret[id(ext)] = weak_global_scope[ext.label][0] + else: + ret[id(ext)] = None + else: + if ext.label in global_scope: + ret[id(ext)] = global_scope[ext.label] + elif ext.label in weak_global_scope: + ret[id(ext)] = weak_global_scope[ext.label][0] + else: + raise LinkerException(f'Unresolved global ext "{ext.label}"') + + return ret def link(objects: list[tuple[Any, ObjectModule]], image_size: Optional[int] = None) -> \ @@ -108,26 +125,26 @@ def link(objects: list[tuple[Any, ObjectModule]], image_size: Optional[int] = No :param image_size: maximum size of image for current target or None if no limit :return: pair [bytearray of image data, mapping from image addresses to locations in source files] """ + entry_by_exts = find_entries_for_exts([obj for _, obj in objects]) + asects: list[ObjectSectionRecord] = list(itertools.chain.from_iterable([obj.asects for _, obj in objects])) + used_sects = find_referenced_sects(asects, entry_by_exts) try: - rsects = concat_rsects(itertools.chain.from_iterable([obj.rsects for _, obj in objects])) + rsects = concat_rsects(filter(lambda rsect: rsect in used_sects, itertools.chain.from_iterable([obj.rsects for _, obj in objects]))) except ValueError as e: raise LinkerException(str(e)) - exts_by_sect = find_exts_by_sect(asects + rsects) - sect_by_ent = find_sect_by_ent(asects + rsects) - used_sects = find_referenced_sects(exts_by_sect, sect_by_ent) - - rsects = [s for s in rsects if s.name in used_sects] rsects.sort(key=lambda s: -len(s.data)) asects.sort(key=lambda s: s.address) rsect_bins = init_bins(asects, image_size) sect_addresses = place_sects(rsects, rsect_bins, image_size) - ents = gather_ents(asects + rsects, sect_addresses) + image = bytearray(2 ** 16) code_locations: dict[int, CodeLocation] = {} + # Writing asects data to image + # Gathering code_locations from asects for asect in asects: image_begin = asect.address image_end = image_begin + len(asect.data) @@ -135,6 +152,9 @@ def link(objects: list[tuple[Any, ObjectModule]], image_size: Optional[int] = No for loc_offset, location in asect.code_locations.items(): code_locations[loc_offset + image_begin] = location + # Writing rsects data to image + # Rellocation + # Gathering code_locations from rsects lower_parts: dict[int, int] = {} # Won't be empty if two entries added together, currently targets don't do that for rsect in rsects: image_begin = sect_addresses[rsect.name] @@ -154,14 +174,21 @@ def link(objects: list[tuple[Any, ObjectModule]], image_size: Optional[int] = No for loc_offset, location in rsect.code_locations.items(): code_locations[loc_offset + image_begin] = location + # Linking XTRNs with NTRYs for sect in asects + rsects: for ext_name in sect.external: + if entry_by_exts[id(ext_name)] is None: + symbol_value = 0 + else: + symbol_sect, symbol = entry_by_exts[id(ext_name)] + symbol_value = sect_addresses[symbol_sect.name] + symbol.address + for entry in sect.external[ext_name]: pos = sect_addresses[sect.name] + entry.offset lower_limit = 1 << 8 * entry.entry_bytes.start val = int.from_bytes(image[pos:pos + len(entry.entry_bytes)], 'little', signed=False) * lower_limit val += entry.lower_part + lower_parts.get(entry.offset, 0) - val += ents[ext_name.label] * entry.sign + val += symbol_value * entry.sign val %= (1 << 8 * entry.entry_bytes.stop) image[pos:pos + len(entry.entry_bytes)] = \ (val // lower_limit).to_bytes(len(entry.entry_bytes), 'little', signed=False) From 86ce0d0e04be294c4099155d7e61ac19a622f1b0 Mon Sep 17 00:00:00 2001 From: Proletcultist Date: Thu, 29 Jan 2026 13:50:17 +0700 Subject: [PATCH 11/42] [cocas] Removed unneeded import, added comment --- cocas/linker/linker.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cocas/linker/linker.py b/cocas/linker/linker.py index 7c0cba0a..c62b2f76 100644 --- a/cocas/linker/linker.py +++ b/cocas/linker/linker.py @@ -1,6 +1,6 @@ import itertools from math import inf -from typing import Any, Optional, Iterable +from typing import Any, Optional from cocas.object_module import CodeLocation, ObjectModule, ObjectSectionRecord, concat_rsects, Attributes @@ -34,6 +34,7 @@ def init_bins(asects: list[ObjectSectionRecord], image_size: Optional[int]): return rsect_bins + def place_sects(rsects: list[ObjectSectionRecord], rsect_bins: list, image_size) -> dict[str, int]: sect_addresses = {'$abs': 0} for rsect in rsects: @@ -125,6 +126,7 @@ def link(objects: list[tuple[Any, ObjectModule]], image_size: Optional[int] = No :param image_size: maximum size of image for current target or None if no limit :return: pair [bytearray of image data, mapping from image addresses to locations in source files] """ + # For all XTRN find corresponding NTRY entry_by_exts = find_entries_for_exts([obj for _, obj in objects]) asects: list[ObjectSectionRecord] = list(itertools.chain.from_iterable([obj.asects for _, obj in objects])) From 425371a695934859bd2f333c809b198bd532cc34 Mon Sep 17 00:00:00 2001 From: Proletcultist Date: Thu, 29 Jan 2026 14:33:20 +0700 Subject: [PATCH 12/42] [cocas] Replaced ExternalEntryKey with ExternalLabelKey --- cocas/linker/linker.py | 2 +- cocas/object_file/object_import.py | 7 +++--- cocas/object_module/__init__.py | 1 - cocas/object_module/external_entry_key.py | 30 ----------------------- cocas/object_module/object_module.py | 1 - 5 files changed, 5 insertions(+), 36 deletions(-) delete mode 100644 cocas/object_module/external_entry_key.py diff --git a/cocas/linker/linker.py b/cocas/linker/linker.py index c62b2f76..fcedeb4e 100644 --- a/cocas/linker/linker.py +++ b/cocas/linker/linker.py @@ -70,7 +70,7 @@ def find_referenced_sects(asects: list[ObjectSectionRecord], entry_by_ext: dict[ def find_entries_for_exts(modules: list[ObjectModule]): - # ret: id(ExternalEntryKey) -> (section, entry) + # ret: id(ExternalLabelKey) -> (section, entry) ret: dict[int, (ObjectSectionRecord, Entry)] = {} # modules_scope: id(ObjectModule) -> (label -> (section, entry)) diff --git a/cocas/object_file/object_import.py b/cocas/object_file/object_import.py index 38569107..2aa7250f 100644 --- a/cocas/object_file/object_import.py +++ b/cocas/object_file/object_import.py @@ -6,7 +6,8 @@ import antlr4 from antlr4 import CommonTokenStream, InputStream -from cocas.object_module import CodeLocation, ExternalEntry, ObjectModule, ObjectSectionRecord, Linkage, Attributes, Entry, ExternalEntryKey +from cocas.object_module import CodeLocation, ExternalEntry, ObjectModule, ObjectSectionRecord, Linkage, Attributes, Entry +from cocas.assembler import ExternalLabelKey from .exceptions import AntlrErrorListener, ObjectFileException from .generated import ObjectFileLexer, ObjectFileParser, ObjectFileParserVisitor @@ -68,9 +69,9 @@ def visitObject_block(self, ctx: ObjectFileParser.Object_blockContext) -> Object 'No absolute sections found, but needed for xtrn entry') # what is this? ind = max(bisect.bisect_right(asect_addr, entry.offset) - 1, 0) - asects[asect_addr[ind]].external[ExternalEntryKey(label, attributes)].append(entry) + asects[asect_addr[ind]].external[ExternalLabelKey(label, attributes=attributes)].append(entry) elif sect in rsects: - rsects[sect].external[ExternalEntryKey(label, attributes)].append(entry) + rsects[sect].external[ExternalLabelKey(label, attributes=attributes)].append(entry) else: raise ObjectFileException(self.file, xtrn.start.line, f'Section not found: {sect}') if filename: diff --git a/cocas/object_module/__init__.py b/cocas/object_module/__init__.py index 6fabe249..662b72ef 100644 --- a/cocas/object_module/__init__.py +++ b/cocas/object_module/__init__.py @@ -7,4 +7,3 @@ from .linkage import Linkage from .entry import Entry from .attributes import Attributes -from .external_entry_key import ExternalEntryKey diff --git a/cocas/object_module/external_entry_key.py b/cocas/object_module/external_entry_key.py deleted file mode 100644 index 7e708d16..00000000 --- a/cocas/object_module/external_entry_key.py +++ /dev/null @@ -1,30 +0,0 @@ -from .attributes import Attributes - -class ExternalEntryKey: - """Describes the key for adding ExternalEntry objects to a dictionary. - Contains the label name, attributes, sorted in non-descending order, anb - their string representation.""" - def __init__(self, label: str, attrs: list(Attributes)): - self.label: str = label - self.attrs: attrs = sorted(attrs) - self.key = label - - if len(self.attrs) > 0: - # ATTR1 +ATTR2 ... +ATTRn - string = " +".join(map(str, self.attrs)) - # label +ATTR1 +ATTR2 ... +ATTRn - self.key += f"+{string}" - - def __hash__(self): - return hash(self.key) - - def __eq__(self, other): - if not isinstance(other, type(self)): - return False - return self.key == self.key - - def __str__(self): - return self.key - - def __repr__(self): - return str(self) diff --git a/cocas/object_module/object_module.py b/cocas/object_module/object_module.py index fbacec02..8cba8fef 100644 --- a/cocas/object_module/object_module.py +++ b/cocas/object_module/object_module.py @@ -4,7 +4,6 @@ from typing import Union from .external_entry import ExternalEntry -from .external_entry_key import ExternalEntryKey from .location import CodeLocation from .entry import Entry From 4abe916614d7781d0e313a3e4ceb8898ed4ee23d Mon Sep 17 00:00:00 2001 From: Proletcultist Date: Thu, 29 Jan 2026 14:44:22 +0700 Subject: [PATCH 13/42] [cocas] Removed symbol names collision check in concat_rsects --- cocas/object_module/concat_rsects.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/cocas/object_module/concat_rsects.py b/cocas/object_module/concat_rsects.py index db48a142..48811373 100644 --- a/cocas/object_module/concat_rsects.py +++ b/cocas/object_module/concat_rsects.py @@ -34,9 +34,6 @@ def concat_rsects(rsects: Iterable["ObjectSectionRecord"]) -> list["ObjectSectio prev_size = (prev_size + rsect.alignment - 1) // rsect.alignment * rsect.alignment new.data.extend(bytearray(prev_size - len(new.data))) new.data += rsect.data - # same_entries = new.entries.keys() & rsect.entries.keys() - # if same_entries: - # raise ValueError(f"Two sections with same name {name} declare label {next(iter(same_entries))}") new.entries.update({name: Entry(entry.address + prev_size, entry.attrs) for name, entry in rsect.entries.items()}) for pos, loc in rsect.code_locations.items(): new.code_locations[pos + prev_size] = loc From d43b1cae4f48b9aea7baac9281be41fbf0305666 Mon Sep 17 00:00:00 2001 From: Proletcultist Date: Thu, 29 Jan 2026 14:44:35 +0700 Subject: [PATCH 14/42] [cocas] Added import of Entry to linker.py --- cocas/linker/linker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocas/linker/linker.py b/cocas/linker/linker.py index fcedeb4e..8b1937be 100644 --- a/cocas/linker/linker.py +++ b/cocas/linker/linker.py @@ -2,7 +2,7 @@ from math import inf from typing import Any, Optional -from cocas.object_module import CodeLocation, ObjectModule, ObjectSectionRecord, concat_rsects, Attributes +from cocas.object_module import CodeLocation, ObjectModule, ObjectSectionRecord, concat_rsects, Attributes, Entry from .exceptions import LinkerException from .targets import TargetParams, import_target From 62e554eec9aeb08bfc722a517d76125065528952 Mon Sep 17 00:00:00 2001 From: Timofey X Date: Fri, 30 Jan 2026 12:47:08 +0700 Subject: [PATCH 15/42] [cocas] Fix typing in the commit that was not reviewed --- cocas/assembler/ast_builder.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/cocas/assembler/ast_builder.py b/cocas/assembler/ast_builder.py index e1b10cb9..c514fb98 100644 --- a/cocas/assembler/ast_builder.py +++ b/cocas/assembler/ast_builder.py @@ -2,6 +2,7 @@ import warnings from base64 import b64decode from pathlib import Path +from typing import Optional from antlr4 import CommonTokenStream, InputStream @@ -249,25 +250,25 @@ def visitAddr_expr(self, ctx: AsmParser.Addr_exprContext): add_terms.append(term) return RelocatableExpressionNode(None, add_terms, sub_terms, const_term) - def visitLocalLabelSuffix(self, ctx) -> Linkage: + def visitLocalLabelSuffix(self, ctx) -> Optional[Linkage]: return None - def visitGlobalLabelSuffix(self, ctx) -> Linkage: + def visitGlobalLabelSuffix(self, ctx) -> Optional[Linkage]: return Linkage.GLOBAL - def visitFileLabelSuffix(self, ctx) -> Linkage: + def visitFileLabelSuffix(self, ctx) -> Optional[Linkage]: return Linkage.FILE_LOCAL - def visitWeakLabelSuffix(self, ctx) -> Linkage: + def visitWeakLabelSuffix(self, ctx) -> Optional[Linkage]: return Linkage.WEAK_GLOBAL - def visitGlobalExtType(self, ctx) -> Linkage: + def visitGlobalExtType(self, ctx) -> Optional[Linkage]: return Linkage.GLOBAL - def visitFileExtType(self, ctx) -> Linkage: + def visitFileExtType(self, ctx) -> Optional[Linkage]: return Linkage.FILE_LOCAL - def visitWeakExtType(self, ctx) -> Linkage: + def visitWeakExtType(self, ctx) -> Optional[Linkage]: return Linkage.WEAK_GLOBAL def visitStandaloneLabels(self, ctx: AsmParser.StandaloneLabelsContext) -> list[LabelDeclarationNode]: From e2d6a673b98e98e89e632a1b211735451322855f Mon Sep 17 00:00:00 2001 From: Proletcultist Date: Fri, 30 Jan 2026 13:47:09 +0700 Subject: [PATCH 16/42] [cocas] Corrected type find_entries_for_exts returns --- cocas/linker/linker.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cocas/linker/linker.py b/cocas/linker/linker.py index 8b1937be..debdc9d8 100644 --- a/cocas/linker/linker.py +++ b/cocas/linker/linker.py @@ -69,9 +69,9 @@ def find_referenced_sects(asects: list[ObjectSectionRecord], entry_by_ext: dict[ return used_sects -def find_entries_for_exts(modules: list[ObjectModule]): +def find_entries_for_exts(modules: list[ObjectModule]) -> dict[int, Optional[(ObjectSectionRecord, Entry)]]: # ret: id(ExternalLabelKey) -> (section, entry) - ret: dict[int, (ObjectSectionRecord, Entry)] = {} + ret: dict[int, Optional[(ObjectSectionRecord, Entry)]] = {} # modules_scope: id(ObjectModule) -> (label -> (section, entry)) modules_scope: dict[int, dict[str, (ObjectSectionRecord, Entry)]] = {} From 3fcf364345e38159111e5cdf60450455c87ed01b Mon Sep 17 00:00:00 2001 From: reVInotip Date: Fri, 30 Jan 2026 14:34:35 +0700 Subject: [PATCH 17/42] [cocas] Fix class ExternalLabelKey and types in parse_expression --- cocas/assembler/external_label_key.py | 5 +++++ cocas/assembler/targets/cdm16/code_segments.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/cocas/assembler/external_label_key.py b/cocas/assembler/external_label_key.py index 9bdbf6f3..11695807 100644 --- a/cocas/assembler/external_label_key.py +++ b/cocas/assembler/external_label_key.py @@ -6,6 +6,11 @@ class ExternalLabelKey: """Describes the key for adding ExternalEntry objects to a dictionary. Contains the label name, attributes, sorted in non-descending order, anb their string representation.""" + + label: str + attrs: list(Attributes) = [] + key: str + def __init__(self, label: str, linkage_attr: Optional[Linkage] = None, attributes: Optional[list[Attributes]] = None): diff --git a/cocas/assembler/targets/cdm16/code_segments.py b/cocas/assembler/targets/cdm16/code_segments.py index eb0873f1..8b76fa4f 100644 --- a/cocas/assembler/targets/cdm16/code_segments.py +++ b/cocas/assembler/targets/cdm16/code_segments.py @@ -308,7 +308,7 @@ def parse_expression(expr: RelocatableExpressionNode, section: "Section", labels if isinstance(term, LabelNode): if term.name in section.exts: result.ext_labels[ExternalLabelKey(term.name, section.exts[term.name])] = \ - result.ext_labels.get(term.name, 0) + sign + result.ext_labels.get(ExternalLabelKey(term.name, section.exts[term.name]), 0) + sign elif term.name in section.labels and section.name != '$abs': result.rel_labels[term.name] = result.rel_labels.get(term.name, 0) + sign elif term.name in section.labels: From 5d0c034d10fca9baed21ac82d32a63e532cb399e Mon Sep 17 00:00:00 2001 From: Proletcultist Date: Fri, 30 Jan 2026 14:42:52 +0700 Subject: [PATCH 18/42] [cocas] Fixed wrong type hints --- cocas/linker/linker.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cocas/linker/linker.py b/cocas/linker/linker.py index debdc9d8..1913e3ea 100644 --- a/cocas/linker/linker.py +++ b/cocas/linker/linker.py @@ -54,7 +54,7 @@ def place_sects(rsects: list[ObjectSectionRecord], rsect_bins: list, image_size) return sect_addresses -def find_referenced_sects(asects: list[ObjectSectionRecord], entry_by_ext: dict[int, (ObjectSectionRecord, Entry)]): +def find_referenced_sects(asects: list[ObjectSectionRecord], entry_by_ext: dict[int, tuple[ObjectSectionRecord, Entry]]): used_sects_queue = asects.copy() used_sects = [] i = 0 @@ -71,12 +71,12 @@ def find_referenced_sects(asects: list[ObjectSectionRecord], entry_by_ext: dict[ def find_entries_for_exts(modules: list[ObjectModule]) -> dict[int, Optional[(ObjectSectionRecord, Entry)]]: # ret: id(ExternalLabelKey) -> (section, entry) - ret: dict[int, Optional[(ObjectSectionRecord, Entry)]] = {} + ret: dict[int, Optional[tuple[ObjectSectionRecord, Entry]]] = {} # modules_scope: id(ObjectModule) -> (label -> (section, entry)) - modules_scope: dict[int, dict[str, (ObjectSectionRecord, Entry)]] = {} - global_scope: dict[str, (ObjectSectionRecord, Entry)] = {} - weak_global_scope: dict[str, list[(ObjectSectionRecord, Entry)]] = {} + modules_scope: dict[int, dict[str, tuple[ObjectSectionRecord, Entry]]] = {} + global_scope: dict[str, tuple[ObjectSectionRecord, Entry]] = {} + weak_global_scope: dict[str, list[tuple[ObjectSectionRecord, Entry]]] = {} for module in modules: for sect in (module.rsects + module.asects): From 9c4614cedf1235e841e864b7b00e6c809abf59b6 Mon Sep 17 00:00:00 2001 From: Proletcultist Date: Fri, 30 Jan 2026 14:50:52 +0700 Subject: [PATCH 19/42] [cocas] Fixed wrong type hint (again) --- cocas/linker/linker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocas/linker/linker.py b/cocas/linker/linker.py index 1913e3ea..d376002f 100644 --- a/cocas/linker/linker.py +++ b/cocas/linker/linker.py @@ -69,7 +69,7 @@ def find_referenced_sects(asects: list[ObjectSectionRecord], entry_by_ext: dict[ return used_sects -def find_entries_for_exts(modules: list[ObjectModule]) -> dict[int, Optional[(ObjectSectionRecord, Entry)]]: +def find_entries_for_exts(modules: list[ObjectModule]) -> dict[int, Optional[tuple[ObjectSectionRecord, Entry]]]: # ret: id(ExternalLabelKey) -> (section, entry) ret: dict[int, Optional[tuple[ObjectSectionRecord, Entry]]] = {} From 0e39a81eee947c254deff69bed659831633bfe2b Mon Sep 17 00:00:00 2001 From: reVInotip Date: Fri, 30 Jan 2026 14:51:57 +0700 Subject: [PATCH 20/42] [cocas] Refactor code and fix imports --- cocas/assembler/__init__.py | 1 - cocas/assembler/targets/cdm16/code_segments.py | 2 +- cocas/object_file/object_import.py | 2 +- cocas/{assembler => object_module}/external_label_key.py | 4 ++-- cocas/object_module/object_module.py | 3 +-- 5 files changed, 5 insertions(+), 7 deletions(-) rename cocas/{assembler => object_module}/external_label_key.py (97%) diff --git a/cocas/assembler/__init__.py b/cocas/assembler/__init__.py index d042f1db..d8af4dce 100644 --- a/cocas/assembler/__init__.py +++ b/cocas/assembler/__init__.py @@ -4,4 +4,3 @@ from .exceptions import AssemblerException, AssemblerExceptionTag from .macro_processor import read_mlb from .targets import list_assembler_targets -from .external_label_key import ExternalLabelKey diff --git a/cocas/assembler/targets/cdm16/code_segments.py b/cocas/assembler/targets/cdm16/code_segments.py index 8b76fa4f..9862b4ed 100644 --- a/cocas/assembler/targets/cdm16/code_segments.py +++ b/cocas/assembler/targets/cdm16/code_segments.py @@ -9,7 +9,7 @@ from ...ast_nodes import LabelNode, LabelDeclarationNode, RegisterNode, RelocatableExpressionNode, TemplateFieldNode from ...exceptions import AssemblerException, AssemblerExceptionTag from .. import IAlignedSegment, IAlignmentPaddingSegment, ICodeSegment, IVaryingLengthSegment -from ...external_label_key import ExternalLabelKey +from ....object_module.external_label_key import ExternalLabelKey from ....object_module.linkage import Linkage if TYPE_CHECKING: diff --git a/cocas/object_file/object_import.py b/cocas/object_file/object_import.py index 2aa7250f..aeb2056a 100644 --- a/cocas/object_file/object_import.py +++ b/cocas/object_file/object_import.py @@ -7,7 +7,7 @@ from antlr4 import CommonTokenStream, InputStream from cocas.object_module import CodeLocation, ExternalEntry, ObjectModule, ObjectSectionRecord, Linkage, Attributes, Entry -from cocas.assembler import ExternalLabelKey +from cocas.object_module.external_label_key import ExternalLabelKey from .exceptions import AntlrErrorListener, ObjectFileException from .generated import ObjectFileLexer, ObjectFileParser, ObjectFileParserVisitor diff --git a/cocas/assembler/external_label_key.py b/cocas/object_module/external_label_key.py similarity index 97% rename from cocas/assembler/external_label_key.py rename to cocas/object_module/external_label_key.py index 11695807..f5af97cc 100644 --- a/cocas/assembler/external_label_key.py +++ b/cocas/object_module/external_label_key.py @@ -8,9 +8,9 @@ class ExternalLabelKey: their string representation.""" label: str - attrs: list(Attributes) = [] + attrs: list[Attributes] = [] key: str - + def __init__(self, label: str, linkage_attr: Optional[Linkage] = None, attributes: Optional[list[Attributes]] = None): diff --git a/cocas/object_module/object_module.py b/cocas/object_module/object_module.py index 8cba8fef..3e633c2a 100644 --- a/cocas/object_module/object_module.py +++ b/cocas/object_module/object_module.py @@ -6,8 +6,7 @@ from .external_entry import ExternalEntry from .location import CodeLocation from .entry import Entry - -from ..assembler.external_label_key import ExternalLabelKey +from .external_label_key import ExternalLabelKey @dataclass From 137d6f15f3cde82e74dda512e6f62e66f9a04765 Mon Sep 17 00:00:00 2001 From: reVInotip Date: Fri, 30 Jan 2026 15:19:21 +0700 Subject: [PATCH 21/42] [cocas] Added support for cdm8 and cdm8e architectures --- cocas/assembler/targets/cdm8/code_segments.py | 6 ++++-- cocas/assembler/targets/cdm8e/code_segments.py | 11 ++++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/cocas/assembler/targets/cdm8/code_segments.py b/cocas/assembler/targets/cdm8/code_segments.py index d8b2db1c..ad42bd26 100644 --- a/cocas/assembler/targets/cdm8/code_segments.py +++ b/cocas/assembler/targets/cdm8/code_segments.py @@ -7,6 +7,7 @@ from ...ast_nodes import LabelNode, RelocatableExpressionNode, TemplateFieldNode from ...exceptions import AssemblerException, AssemblerExceptionTag from .. import IAlignmentPaddingSegment, ICodeSegment +from ....object_module.external_label_key import ExternalLabelKey if TYPE_CHECKING: from ...code_block import Section @@ -78,7 +79,7 @@ class ParsedExpression: relocate_additions: int = field(default=0) asect: dict[str, int] = field(default_factory=dict) rel_labels: dict[str, int] = field(default_factory=dict) - ext_labels: dict[str, int] = field(default_factory=dict) + ext_labels: dict[ExternalLabelKey, int] = field(default_factory=dict) def parse_expression(expr: RelocatableExpressionNode, section: "Section", labels: dict[str, int], @@ -89,7 +90,8 @@ def parse_expression(expr: RelocatableExpressionNode, section: "Section", labels for term, sign in [(t, 1) for t in expr.add_terms] + [(t, -1) for t in expr.sub_terms]: if isinstance(term, LabelNode): if term.name in section.exts: - result.ext_labels[term.name] = result.ext_labels.get(term.name, 0) + sign + result.ext_labels[ExternalLabelKey(term.name, section.exts[term.name])] = \ + result.ext_labels.get(ExternalLabelKey(term.name, section.exts[term.name]), 0) + sign elif term.name in section.labels and section.name != '$abs': result.rel_labels[term.name] = result.rel_labels.get(term.name, 0) + sign elif term.name in section.labels: diff --git a/cocas/assembler/targets/cdm8e/code_segments.py b/cocas/assembler/targets/cdm8e/code_segments.py index a6f9b642..ad51751a 100644 --- a/cocas/assembler/targets/cdm8e/code_segments.py +++ b/cocas/assembler/targets/cdm8e/code_segments.py @@ -9,6 +9,7 @@ from .. import ICodeSegment, IVaryingLengthSegment from .branches import check_inverse_branch from .instruction_codes import simple_instructions +from ....object_module.external_label_key import ExternalLabelKey TAG = AssemblerExceptionTag.ASM @@ -262,12 +263,16 @@ def add_ext_record(obj_rec: "ObjectSectionRecord", ext: str, s: "Section", val: val_lo, _ = val.to_bytes(2, 'little', signed=False) offset = s.address + len(obj_rec.data) if seg.expr.byte_specifier == 'low': - obj_rec.external.setdefault(ext, []).append(ExternalEntry(offset, range(0, 1), full_bytes=False)) + obj_rec.external \ + .setdefault(ExternalLabelKey(ext, s.exts[ext]), []) \ + .append(ExternalEntry(offset, range(0, 1), full_bytes=False)) elif seg.expr.byte_specifier == 'high': entry = ExternalEntry(offset, range(1, 2), full_bytes=False, lower_part=val_lo) - obj_rec.external.setdefault(ext, []).append(entry) + obj_rec.external.setdefault(ExternalLabelKey(ext, s.exts[ext]), []).append(entry) else: - obj_rec.external.setdefault(ext, []).append(ExternalEntry(offset, range(0, 2), full_bytes=True)) + obj_rec.external \ + .setdefault(ExternalLabelKey(ext, s.exts[ext]), []) \ + .append(ExternalEntry(offset, range(0, 2), full_bytes=True)) def add_rel_record(obj_rec: "ObjectSectionRecord", s: "Section", val: int, From fe4679ebe69cfe5c5c5c703592ef0ebf7a24ad6e Mon Sep 17 00:00:00 2001 From: reVInotip Date: Fri, 30 Jan 2026 15:59:05 +0700 Subject: [PATCH 22/42] [cocas] Fix duplicate labels declaration checking --- cocas/assembler/code_block.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cocas/assembler/code_block.py b/cocas/assembler/code_block.py index 1673ff1a..b6d67cf4 100644 --- a/cocas/assembler/code_block.py +++ b/cocas/assembler/code_block.py @@ -70,10 +70,9 @@ def assemble_lines(self, lines: list, temp_storage): def assemble_label_declaration(self, line: LabelDeclarationNode, __): label_name = line.label.name - label_linkage = line.linkage if (label_name in self.labels or - (label_name in self.ents and label_linkage == self.ents[label_name]) or - (label_name in self.exts and label_linkage == self.exts[label_name])): + label_name in self.ents or + label_name in self.exts): raise AssemblerException(AssemblerExceptionTag.ASM, line.location.file, line.location.line, f'Duplicate label "{label_name}" declaration') From b5be8382770ec04f09e3d645140e22516390d441 Mon Sep 17 00:00:00 2001 From: reVInotip Date: Fri, 30 Jan 2026 16:30:53 +0700 Subject: [PATCH 23/42] [cocas] Fix imports from object_module --- cocas/assembler/object_generator.py | 2 +- cocas/assembler/targets/cdm16/code_segments.py | 6 ++---- cocas/assembler/targets/cdm8/code_segments.py | 3 +-- cocas/assembler/targets/cdm8e/code_segments.py | 3 +-- cocas/object_module/__init__.py | 1 + cocas/object_module/external_label_key.py | 4 ++-- 6 files changed, 8 insertions(+), 11 deletions(-) diff --git a/cocas/assembler/object_generator.py b/cocas/assembler/object_generator.py index abb494e0..74e417f9 100644 --- a/cocas/assembler/object_generator.py +++ b/cocas/assembler/object_generator.py @@ -3,7 +3,7 @@ from typing import Any, Union from cocas.object_module import CodeLocation, ObjectModule, concat_rsects -from ..object_module.linkage import Linkage +from cocas.object_module.linkage import Linkage from .ast_nodes import ( InstructionNode, diff --git a/cocas/assembler/targets/cdm16/code_segments.py b/cocas/assembler/targets/cdm16/code_segments.py index 9862b4ed..5438da8c 100644 --- a/cocas/assembler/targets/cdm16/code_segments.py +++ b/cocas/assembler/targets/cdm16/code_segments.py @@ -4,13 +4,11 @@ import bitstruct -from cocas.object_module import CodeLocation, ExternalEntry, ObjectSectionRecord +from cocas.object_module import CodeLocation, ExternalEntry, ObjectSectionRecord, ExternalLabelKey -from ...ast_nodes import LabelNode, LabelDeclarationNode, RegisterNode, RelocatableExpressionNode, TemplateFieldNode +from ...ast_nodes import LabelNode, RegisterNode, RelocatableExpressionNode, TemplateFieldNode from ...exceptions import AssemblerException, AssemblerExceptionTag from .. import IAlignedSegment, IAlignmentPaddingSegment, ICodeSegment, IVaryingLengthSegment -from ....object_module.external_label_key import ExternalLabelKey -from ....object_module.linkage import Linkage if TYPE_CHECKING: from ...code_block import Section diff --git a/cocas/assembler/targets/cdm8/code_segments.py b/cocas/assembler/targets/cdm8/code_segments.py index ad42bd26..02360350 100644 --- a/cocas/assembler/targets/cdm8/code_segments.py +++ b/cocas/assembler/targets/cdm8/code_segments.py @@ -2,12 +2,11 @@ from dataclasses import dataclass, field from typing import TYPE_CHECKING -from cocas.object_module import CodeLocation, ExternalEntry, ObjectSectionRecord +from cocas.object_module import CodeLocation, ExternalEntry, ObjectSectionRecord, ExternalLabelKey from ...ast_nodes import LabelNode, RelocatableExpressionNode, TemplateFieldNode from ...exceptions import AssemblerException, AssemblerExceptionTag from .. import IAlignmentPaddingSegment, ICodeSegment -from ....object_module.external_label_key import ExternalLabelKey if TYPE_CHECKING: from ...code_block import Section diff --git a/cocas/assembler/targets/cdm8e/code_segments.py b/cocas/assembler/targets/cdm8e/code_segments.py index ad51751a..505e190f 100644 --- a/cocas/assembler/targets/cdm8e/code_segments.py +++ b/cocas/assembler/targets/cdm8e/code_segments.py @@ -2,14 +2,13 @@ from dataclasses import dataclass, field from typing import TYPE_CHECKING -from cocas.object_module import CodeLocation, ExternalEntry, ObjectSectionRecord +from cocas.object_module import CodeLocation, ExternalEntry, ObjectSectionRecord, ExternalLabelKey from ...ast_nodes import LabelNode, RelocatableExpressionNode, TemplateFieldNode from ...exceptions import AssemblerException, AssemblerExceptionTag from .. import ICodeSegment, IVaryingLengthSegment from .branches import check_inverse_branch from .instruction_codes import simple_instructions -from ....object_module.external_label_key import ExternalLabelKey TAG = AssemblerExceptionTag.ASM diff --git a/cocas/object_module/__init__.py b/cocas/object_module/__init__.py index 662b72ef..cf59d271 100644 --- a/cocas/object_module/__init__.py +++ b/cocas/object_module/__init__.py @@ -5,5 +5,6 @@ from .location import CodeLocation from .object_module import ObjectModule, ObjectSectionRecord from .linkage import Linkage +from .external_label_key import ExternalLabelKey from .entry import Entry from .attributes import Attributes diff --git a/cocas/object_module/external_label_key.py b/cocas/object_module/external_label_key.py index f5af97cc..79bd7868 100644 --- a/cocas/object_module/external_label_key.py +++ b/cocas/object_module/external_label_key.py @@ -1,5 +1,5 @@ -from ..object_module.linkage import Linkage -from ..object_module.attributes import Attributes +from cocas.object_module.linkage import Linkage +from cocas.object_module.attributes import Attributes from typing import Optional class ExternalLabelKey: From ba64bcac7761ede30f639beeff340875e1ed9bb4 Mon Sep 17 00:00:00 2001 From: reVInotip Date: Fri, 30 Jan 2026 16:34:01 +0700 Subject: [PATCH 24/42] [cocas] Also fix imports from object_module --- cocas/assembler/code_block.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocas/assembler/code_block.py b/cocas/assembler/code_block.py index b6d67cf4..e16c031d 100644 --- a/cocas/assembler/code_block.py +++ b/cocas/assembler/code_block.py @@ -19,7 +19,7 @@ ) from .exceptions import AssemblerException, AssemblerExceptionTag, CdmTempException from .targets import ICodeSegment, TargetInstructions -from ..object_module.entry import Entry +from cocas.object_module.entry import Entry @dataclass From 9e6a27b8d3b636ebef4bb7bfcc3570b064109c7d Mon Sep 17 00:00:00 2001 From: reVInotip Date: Fri, 30 Jan 2026 17:19:57 +0700 Subject: [PATCH 25/42] [cocas] Refactor code and fix sorting --- cocas/object_module/attributes.py | 5 ++--- cocas/object_module/external_label_key.py | 16 ++++++++-------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/cocas/object_module/attributes.py b/cocas/object_module/attributes.py index 8cb666f2..34090dfb 100644 --- a/cocas/object_module/attributes.py +++ b/cocas/object_module/attributes.py @@ -1,6 +1,6 @@ -from enum import Enum +from enum import IntEnum -class Attributes(Enum): +class Attributes(IntEnum): NONE = 0, LOCAL = 1, WEAK = 2 @@ -15,4 +15,3 @@ def __str__(self): return "" case _: pass # do something - diff --git a/cocas/object_module/external_label_key.py b/cocas/object_module/external_label_key.py index 79bd7868..da8c9db3 100644 --- a/cocas/object_module/external_label_key.py +++ b/cocas/object_module/external_label_key.py @@ -8,29 +8,29 @@ class ExternalLabelKey: their string representation.""" label: str - attrs: list[Attributes] = [] + attributes: set[Attributes] = set() key: str def __init__(self, label: str, linkage_attr: Optional[Linkage] = None, attributes: Optional[list[Attributes]] = None): self.label: str = label - self.attrs: list(Attributes) = [] + self.attributes: set(Attributes) = set() self.key: str = label if linkage_attr: attr: Attributes = linkage_attr.to_attribute() if attr != Attributes.NONE: - self.attrs.append(linkage_attr.to_attribute()) + self.attributes.add(linkage_attr.to_attribute()) if attributes: - self.attrs.extend(attributes) + self.attributes.update(attributes) - self.attrs = sorted(self.attrs) + self.attributes = sorted(self.attributes) - if len(self.attrs) > 0: + if len(self.attributes) > 0: # ATTR1 +ATTR2 ... +ATTRn - string = " +".join(map(str, self.attrs)) + string = " +".join(map(str, self.attributes)) # label +ATTR1 +ATTR2 ... +ATTRn self.key += f" +{string}" @@ -49,4 +49,4 @@ def __repr__(self): return str(self) def is_file_local(self): - return Attributes.LOCAL in self.attrs \ No newline at end of file + return Attributes.LOCAL in self.attributes \ No newline at end of file From 6a08ced4a81b88ca987600ff50b808d796a2ae91 Mon Sep 17 00:00:00 2001 From: Proletcultist Date: Fri, 30 Jan 2026 21:44:11 +0700 Subject: [PATCH 26/42] [cocas] Changed access to ExternalLabelKey field after renaming --- cocas/linker/linker.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cocas/linker/linker.py b/cocas/linker/linker.py index d376002f..247551fa 100644 --- a/cocas/linker/linker.py +++ b/cocas/linker/linker.py @@ -95,11 +95,11 @@ def find_entries_for_exts(modules: list[ObjectModule]) -> dict[int, Optional[tup for module in modules: for sect in (module.rsects + module.asects): for ext in sect.external: - if Attributes.LOCAL in ext.attrs: + if Attributes.LOCAL in ext.attributes: if (not id(module) in modules_scope) or (not ext.label in modules_scope[id(module)]): raise LinkerException(f'Unresolved file-local ext "{ext.label}"') ret[id(ext)] = modules_scope[id(module)][ext.label] - elif Attributes.WEAK in ext.attrs: + elif Attributes.WEAK in ext.attributes: if ext.label in global_scope: ret[id(ext)] = global_scope[ext.label] elif ext.label in weak_global_scope: From 087d548c762d58a8a9c189026803bdf05f1069e6 Mon Sep 17 00:00:00 2001 From: Andrey Eliseev Date: Sat, 7 Mar 2026 23:41:59 +0700 Subject: [PATCH 27/42] [cocas] Fix typing in external_label_key --- cocas/object_module/external_label_key.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/cocas/object_module/external_label_key.py b/cocas/object_module/external_label_key.py index da8c9db3..6eacc235 100644 --- a/cocas/object_module/external_label_key.py +++ b/cocas/object_module/external_label_key.py @@ -8,15 +8,15 @@ class ExternalLabelKey: their string representation.""" label: str - attributes: set[Attributes] = set() + attributes: set[Attributes] key: str def __init__(self, label: str, linkage_attr: Optional[Linkage] = None, attributes: Optional[list[Attributes]] = None): - self.label: str = label - self.attributes: set(Attributes) = set() - self.key: str = label + self.label = label + self.attributes = set() + self.key = label if linkage_attr: attr: Attributes = linkage_attr.to_attribute() @@ -26,11 +26,9 @@ def __init__(self, label: str, if attributes: self.attributes.update(attributes) - self.attributes = sorted(self.attributes) - if len(self.attributes) > 0: # ATTR1 +ATTR2 ... +ATTRn - string = " +".join(map(str, self.attributes)) + string = " +".join(map(str, sorted(self.attributes))) # label +ATTR1 +ATTR2 ... +ATTRn self.key += f" +{string}" @@ -49,4 +47,4 @@ def __repr__(self): return str(self) def is_file_local(self): - return Attributes.LOCAL in self.attributes \ No newline at end of file + return Attributes.LOCAL in self.attributes From a75660df1aaa5f5f0a7ed14d1c19d90b5926cf83 Mon Sep 17 00:00:00 2001 From: Andrey Eliseev Date: Sat, 7 Mar 2026 23:43:49 +0700 Subject: [PATCH 28/42] [cocas] Fix ext label parsing in top lines --- cocas/assembler/ast_builder.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cocas/assembler/ast_builder.py b/cocas/assembler/ast_builder.py index c514fb98..67353a65 100644 --- a/cocas/assembler/ast_builder.py +++ b/cocas/assembler/ast_builder.py @@ -68,8 +68,8 @@ def visitProgram(self, ctx: AsmParser.ProgramContext) -> ProgramNode: return ret def visitTop_line(self, ctx: AsmParser.Top_lineContext) -> tuple[list[LabelDeclarationNode], list[InstructionNode]]: - shared_externals = [] - top_instructions = [] + shared_externals: list[LabelDeclarationNode] = [] + top_instructions: list[InstructionNode] = [] for child in ctx.children: if isinstance(child, AsmParser.InstructionLineContext): nodes = self.visitInstructionLine(child) @@ -83,7 +83,7 @@ def visitTop_line(self, ctx: AsmParser.Top_lineContext) -> tuple[list[LabelDecla top_instructions.append(i) elif isinstance(i, LabelDeclarationNode): self.check_label_is_ext(i) - shared_externals.append(i.label) + shared_externals.append(i) else: raise Exception(f"Unexpected node from top line: {i}") elif isinstance(child, AsmParser.StandaloneLabelsContext): From ad8414a642b76e07782f1c06147062a63c4e9c9f Mon Sep 17 00:00:00 2001 From: Andrey Eliseev Date: Sun, 8 Mar 2026 00:13:28 +0700 Subject: [PATCH 29/42] [cocas] Rename Attributes to SymbolAttribute --- cocas/linker/linker.py | 10 +++++----- cocas/object_file/object_import.py | 8 ++++---- cocas/object_module/__init__.py | 2 +- cocas/object_module/attributes.py | 17 ----------------- cocas/object_module/entry.py | 10 +++++----- cocas/object_module/external_label_key.py | 14 +++++++------- cocas/object_module/linkage.py | 11 ++++++----- cocas/object_module/symbol_attribute.py | 14 ++++++++++++++ 8 files changed, 42 insertions(+), 44 deletions(-) delete mode 100644 cocas/object_module/attributes.py create mode 100644 cocas/object_module/symbol_attribute.py diff --git a/cocas/linker/linker.py b/cocas/linker/linker.py index 247551fa..345c549b 100644 --- a/cocas/linker/linker.py +++ b/cocas/linker/linker.py @@ -2,7 +2,7 @@ from math import inf from typing import Any, Optional -from cocas.object_module import CodeLocation, ObjectModule, ObjectSectionRecord, concat_rsects, Attributes, Entry +from cocas.object_module import CodeLocation, ObjectModule, ObjectSectionRecord, concat_rsects, SymbolAttribute, Entry from .exceptions import LinkerException from .targets import TargetParams, import_target @@ -81,11 +81,11 @@ def find_entries_for_exts(modules: list[ObjectModule]) -> dict[int, Optional[tup for module in modules: for sect in (module.rsects + module.asects): for name, entry in sect.entries.items(): - if Attributes.LOCAL in entry.attrs: + if SymbolAttribute.LOCAL in entry.attrs: if id(module) in modules_scope and name in modules_scope[id(module)]: raise LinkerException(f"File-local entry {name} is declared in multiple sections of the same object module") modules_scope.setdefault(id(module), {})[name] = (sect, entry) - elif Attributes.WEAK in entry.attrs: + elif SymbolAttribute.WEAK in entry.attrs: weak_global_scope.setdefault(name, []).append((sect, entry)) else: if name in global_scope: @@ -95,11 +95,11 @@ def find_entries_for_exts(modules: list[ObjectModule]) -> dict[int, Optional[tup for module in modules: for sect in (module.rsects + module.asects): for ext in sect.external: - if Attributes.LOCAL in ext.attributes: + if SymbolAttribute.LOCAL in ext.attributes: if (not id(module) in modules_scope) or (not ext.label in modules_scope[id(module)]): raise LinkerException(f'Unresolved file-local ext "{ext.label}"') ret[id(ext)] = modules_scope[id(module)][ext.label] - elif Attributes.WEAK in ext.attributes: + elif SymbolAttribute.WEAK in ext.attributes: if ext.label in global_scope: ret[id(ext)] = global_scope[ext.label] elif ext.label in weak_global_scope: diff --git a/cocas/object_file/object_import.py b/cocas/object_file/object_import.py index aeb2056a..8552bb61 100644 --- a/cocas/object_file/object_import.py +++ b/cocas/object_file/object_import.py @@ -6,7 +6,7 @@ import antlr4 from antlr4 import CommonTokenStream, InputStream -from cocas.object_module import CodeLocation, ExternalEntry, ObjectModule, ObjectSectionRecord, Linkage, Attributes, Entry +from cocas.object_module import CodeLocation, ExternalEntry, ObjectModule, ObjectSectionRecord, Linkage, SymbolAttribute, Entry from cocas.object_module.external_label_key import ExternalLabelKey from .exceptions import AntlrErrorListener, ObjectFileException @@ -142,15 +142,15 @@ def visitLoc_record(self, ctx: ObjectFileParser.Loc_recordContext): return res def visitWeak(self, ctx: ObjectFileParser.WeakContext): - return Attributes.WEAK + return SymbolAttribute.WEAK def visitLocal(self, ctx: ObjectFileParser.LocalContext): - return Attributes.LOCAL + return SymbolAttribute.LOCAL def visitAttributes(self, attributes: list[ObjectFileParser.AttributeContext]): parsed = list(map(self.visit, attributes)) - if Attributes.WEAK in parsed and Attributes.LOCAL in parsed: + if SymbolAttribute.WEAK in parsed and SymbolAttribute.LOCAL in parsed: raise ObjectFileException(self.file, attributes[0].start.line, 'Symbol cannot have WEAK and LOCAL attributes at the same time') return parsed diff --git a/cocas/object_module/__init__.py b/cocas/object_module/__init__.py index cf59d271..ca8dc542 100644 --- a/cocas/object_module/__init__.py +++ b/cocas/object_module/__init__.py @@ -7,4 +7,4 @@ from .linkage import Linkage from .external_label_key import ExternalLabelKey from .entry import Entry -from .attributes import Attributes +from .symbol_attribute import SymbolAttribute diff --git a/cocas/object_module/attributes.py b/cocas/object_module/attributes.py deleted file mode 100644 index 34090dfb..00000000 --- a/cocas/object_module/attributes.py +++ /dev/null @@ -1,17 +0,0 @@ -from enum import IntEnum - -class Attributes(IntEnum): - NONE = 0, - LOCAL = 1, - WEAK = 2 - - def __str__(self): - match self: - case Attributes.LOCAL: - return "LOCAL" - case Attributes.WEAK: - return "WEAK" - case Attributes.NONE: - return "" - case _: - pass # do something diff --git a/cocas/object_module/entry.py b/cocas/object_module/entry.py index bd5287dd..cbad89f2 100644 --- a/cocas/object_module/entry.py +++ b/cocas/object_module/entry.py @@ -1,19 +1,19 @@ from dataclasses import dataclass, field from typing import Optional -from .attributes import Attributes +from .symbol_attribute import SymbolAttribute from .linkage import Linkage @dataclass class Entry: address: int - attrs: list[Attributes] = field(default_factory=list) + attrs: list[SymbolAttribute] = field(default_factory=list) def add_linkage_attribute(self, linkage: Optional[Linkage]): if linkage: - attr: Attributes = linkage.to_attribute() - if attr != Attributes.NONE: - self.attrs.append(linkage.to_attribute()) + attr: Optional[SymbolAttribute] = linkage.to_attribute() + if attr: + self.attrs.append(attr) def __str__(self): string = "" diff --git a/cocas/object_module/external_label_key.py b/cocas/object_module/external_label_key.py index 6eacc235..8ee565c0 100644 --- a/cocas/object_module/external_label_key.py +++ b/cocas/object_module/external_label_key.py @@ -1,5 +1,5 @@ from cocas.object_module.linkage import Linkage -from cocas.object_module.attributes import Attributes +from cocas.object_module.symbol_attribute import SymbolAttribute from typing import Optional class ExternalLabelKey: @@ -8,20 +8,20 @@ class ExternalLabelKey: their string representation.""" label: str - attributes: set[Attributes] + attributes: set[SymbolAttribute] key: str def __init__(self, label: str, linkage_attr: Optional[Linkage] = None, - attributes: Optional[list[Attributes]] = None): + attributes: Optional[list[SymbolAttribute]] = None): self.label = label self.attributes = set() self.key = label if linkage_attr: - attr: Attributes = linkage_attr.to_attribute() - if attr != Attributes.NONE: - self.attributes.add(linkage_attr.to_attribute()) + attr: Optional[SymbolAttribute] = linkage_attr.to_attribute() + if attr: + self.attributes.add(attr) if attributes: self.attributes.update(attributes) @@ -47,4 +47,4 @@ def __repr__(self): return str(self) def is_file_local(self): - return Attributes.LOCAL in self.attributes + return SymbolAttribute.LOCAL in self.attributes diff --git a/cocas/object_module/linkage.py b/cocas/object_module/linkage.py index cf16b0d2..7f52eff1 100644 --- a/cocas/object_module/linkage.py +++ b/cocas/object_module/linkage.py @@ -1,16 +1,17 @@ from enum import Enum -from .attributes import Attributes +from typing import Optional +from .symbol_attribute import SymbolAttribute class Linkage(Enum): FILE_LOCAL = 1 GLOBAL = 2 WEAK_GLOBAL = 3 - def to_attribute(self): + def to_attribute(self) -> Optional[SymbolAttribute]: match self: case Linkage.FILE_LOCAL: - return Attributes.LOCAL + return SymbolAttribute.LOCAL case Linkage.WEAK_GLOBAL: - return Attributes.WEAK + return SymbolAttribute.WEAK case _: - return Attributes.NONE + return None diff --git a/cocas/object_module/symbol_attribute.py b/cocas/object_module/symbol_attribute.py new file mode 100644 index 00000000..19556b89 --- /dev/null +++ b/cocas/object_module/symbol_attribute.py @@ -0,0 +1,14 @@ +from enum import IntEnum + +class SymbolAttribute(IntEnum): + LOCAL = 1 + WEAK = 2 + + def __str__(self): + match self: + case SymbolAttribute.LOCAL: + return "LOCAL" + case SymbolAttribute.WEAK: + return "WEAK" + case _: + raise ValueError("Unknown symbol attribute") From 3a6a649996457bbc021380990c93443bdbdc65e7 Mon Sep 17 00:00:00 2001 From: Andrey Eliseev Date: Sun, 8 Mar 2026 18:48:47 +0700 Subject: [PATCH 30/42] [cocas] Refactor entry linkage It doesn't make sense to include all attributes into the unique key of an entry. An attribute may, for example, specify the type of the entry, like variable or function, and this shouldn't matter to the linker. This is why this commit replaces ExternalLabelKey with a simpler EntryKey that only consists of the name of the entry and its linkage. This EntryKey is now used everywhere accros the assembler and linker. Entry linkage is no longer an attribute, but its own separate thing. This commit removes attributes, but leaves the Entry class in object_module as an extension point to possibly bring attributes back later. --- cocas/assembler/code_block.py | 11 +- cocas/assembler/object_generator.py | 42 +- .../assembler/targets/cdm16/code_segments.py | 8 +- cocas/assembler/targets/cdm8/code_segments.py | 8 +- .../assembler/targets/cdm8e/code_segments.py | 8 +- cocas/linker/linker.py | 55 +- .../object_file/generated/ObjectFileLexer.py | 212 +++--- .../object_file/generated/ObjectFileParser.py | 693 +++++++++--------- .../generated/ObjectFileParserVisitor.py | 10 + cocas/object_file/grammar/ObjectFileLexer.g4 | 1 + cocas/object_file/grammar/ObjectFileParser.g4 | 11 +- cocas/object_file/object_export.py | 27 +- cocas/object_file/object_import.py | 45 +- cocas/object_module/__init__.py | 5 +- cocas/object_module/concat_rsects.py | 2 +- cocas/object_module/entry.py | 61 +- cocas/object_module/external_label_key.py | 50 -- cocas/object_module/linkage.py | 17 - cocas/object_module/object_module.py | 7 +- cocas/object_module/symbol_attribute.py | 14 - 20 files changed, 636 insertions(+), 651 deletions(-) delete mode 100644 cocas/object_module/external_label_key.py delete mode 100644 cocas/object_module/linkage.py delete mode 100644 cocas/object_module/symbol_attribute.py diff --git a/cocas/assembler/code_block.py b/cocas/assembler/code_block.py index e16c031d..7601f5d2 100644 --- a/cocas/assembler/code_block.py +++ b/cocas/assembler/code_block.py @@ -1,7 +1,7 @@ from dataclasses import dataclass from typing import Any, Callable, Type -from cocas.object_module import CodeLocation, ObjectSectionRecord, Linkage +from cocas.object_module import CodeLocation, ObjectSectionRecord, EntryKey, Entry, Linkage from .ast_nodes import ( AbsoluteSectionNode, @@ -19,7 +19,6 @@ ) from .exceptions import AssemblerException, AssemblerExceptionTag, CdmTempException from .targets import ICodeSegment, TargetInstructions -from cocas.object_module.entry import Entry @dataclass @@ -181,11 +180,9 @@ def __init__(self, sn: SectionNode, target_instructions: TargetInstructions): def to_object_section_record(self, labels: dict[str, int], templates: dict[str, dict[str, int]]): entries = { - key: (lambda: (entry := Entry(label), - entry.add_linkage_attribute(self.ents[key]), - entry)[2])() - for key, label in self.labels.items() - if key in self.ents + EntryKey(name, self.ents[name]): Entry(offset) + for name, offset in self.labels.items() + if name in self.ents } out = ObjectSectionRecord(self.name, self.address, bytearray(), entries, [], self.code_locations) for seg in self.segments: diff --git a/cocas/assembler/object_generator.py b/cocas/assembler/object_generator.py index 74e417f9..b900ce60 100644 --- a/cocas/assembler/object_generator.py +++ b/cocas/assembler/object_generator.py @@ -2,8 +2,7 @@ from dataclasses import dataclass from typing import Any, Union -from cocas.object_module import CodeLocation, ObjectModule, concat_rsects -from cocas.object_module.linkage import Linkage +from cocas.object_module import CodeLocation, ObjectModule, Linkage, concat_rsects from .ast_nodes import ( InstructionNode, @@ -106,7 +105,7 @@ def label_or_template(label: Union[LabelNode, Any], template_fields: dict[str, d def generate_object_module(pn: ProgramNode, target_instructions: TargetInstructions) -> ObjectModule: templates = [Template(t, target_instructions) for t in pn.template_sections] template_fields = dict([(t.name, t.labels) for t in templates]) - file_local_labels: dict[str, tuple[str, int]] = dict() + undefined_file_locals: dict[str, CodeLocation] = dict() # LabelDeclarationNode # InstructionNode @@ -123,20 +122,25 @@ def generate_object_module(pn: ProgramNode, target_instructions: TargetInstructi if prefix in template_fields: raise AssemblerException(AssemblerExceptionTag.ASM, line.location.file, line.location.line, f"Label {line.label.name} conflicts with template {prefix}") - if line.linkage == Linkage.FILE_LOCAL: - file_local_labels[line.label.name] = (line.location.file, line.location.line) + if line.external and line.linkage == Linkage.FILE_LOCAL: + undefined_file_locals[line.label.name] = line.location elif isinstance(line, InstructionNode): for arg in line.arguments: if isinstance(arg, RelocatableExpressionNode): arg.add_terms = list( map(lambda x: label_or_template(x, template_fields), arg.add_terms)) - asects = [Section(asect, target_instructions) for asect in pn.absolute_sections] + asects = sorted((Section(asect, target_instructions) for asect in pn.absolute_sections), key=lambda s: s.address) rsects = [Section(rsect, target_instructions) for rsect in pn.relocatable_sections] + shared_externals = dict(map(lambda x: (x.label.name, x.linkage), pn.shared_externals)) for i in itertools.chain(asects, rsects): i.exts |= shared_externals - asects.sort(key=lambda s: s.address) + undefined_file_locals |= { + decl.label.name: decl.location + for decl in pn.shared_externals + if decl.linkage == Linkage.FILE_LOCAL + } for _ in pn.top_instructions: pass # do something @@ -146,17 +150,17 @@ def generate_object_module(pn: ProgramNode, target_instructions: TargetInstructi for rsect in rsects: update_varying_length([rsect], all_labels, template_fields) - asect_objects = [asect.to_object_section_record(all_labels, template_fields) for asect in asects] - rsect_objects = concat_rsects(map(lambda x: x.to_object_section_record(all_labels, template_fields), rsects)) - - for obj in itertools.chain(asect_objects, rsect_objects): - for label in obj.entries.keys(): - if label in file_local_labels: - file_local_labels.pop(label) + asect_records = [asect.to_object_section_record(all_labels, template_fields) for asect in asects] + rsect_records = concat_rsects(map(lambda x: x.to_object_section_record(all_labels, template_fields), rsects)) + + for section in itertools.chain(asect_records, rsect_records): + for label in section.entries.keys(): + if label.name in undefined_file_locals: + undefined_file_locals.pop(label.name) - if not len(file_local_labels) == 0: - label, (file, line) = next(iter(file_local_labels.items())) - raise AssemblerException(AssemblerExceptionTag.ASM, file, line, - f'Not found file local label(s) implementation: "{label}"') + if undefined_file_locals: + label, location = next(iter(undefined_file_locals.items())) + raise AssemblerException(AssemblerExceptionTag.ASM, location.file, location.line, + f'Undefined file-local label: {label}') - return ObjectModule(asect_objects, rsect_objects) + return ObjectModule(asect_records, rsect_records) diff --git a/cocas/assembler/targets/cdm16/code_segments.py b/cocas/assembler/targets/cdm16/code_segments.py index 5438da8c..bef98219 100644 --- a/cocas/assembler/targets/cdm16/code_segments.py +++ b/cocas/assembler/targets/cdm16/code_segments.py @@ -4,7 +4,7 @@ import bitstruct -from cocas.object_module import CodeLocation, ExternalEntry, ObjectSectionRecord, ExternalLabelKey +from cocas.object_module import CodeLocation, ExternalEntry, ObjectSectionRecord, EntryKey from ...ast_nodes import LabelNode, RegisterNode, RelocatableExpressionNode, TemplateFieldNode from ...exceptions import AssemblerException, AssemblerExceptionTag @@ -294,7 +294,7 @@ class ParsedExpression: relocate_additions: int = field(default=0) asect: dict[str, int] = field(default_factory=dict) rel_labels: dict[str, int] = field(default_factory=dict) - ext_labels: dict[ExternalLabelKey, int] = field(default_factory=dict) + ext_labels: dict[EntryKey, int] = field(default_factory=dict) def parse_expression(expr: RelocatableExpressionNode, section: "Section", labels: dict[str, int], @@ -305,8 +305,8 @@ def parse_expression(expr: RelocatableExpressionNode, section: "Section", labels for term, sign in [(t, 1) for t in expr.add_terms] + [(t, -1) for t in expr.sub_terms]: if isinstance(term, LabelNode): if term.name in section.exts: - result.ext_labels[ExternalLabelKey(term.name, section.exts[term.name])] = \ - result.ext_labels.get(ExternalLabelKey(term.name, section.exts[term.name]), 0) + sign + entry_key = EntryKey(term.name, section.exts[term.name]) + result.ext_labels[entry_key] = result.ext_labels.get(entry_key, 0) + sign elif term.name in section.labels and section.name != '$abs': result.rel_labels[term.name] = result.rel_labels.get(term.name, 0) + sign elif term.name in section.labels: diff --git a/cocas/assembler/targets/cdm8/code_segments.py b/cocas/assembler/targets/cdm8/code_segments.py index 02360350..4b424c67 100644 --- a/cocas/assembler/targets/cdm8/code_segments.py +++ b/cocas/assembler/targets/cdm8/code_segments.py @@ -2,7 +2,7 @@ from dataclasses import dataclass, field from typing import TYPE_CHECKING -from cocas.object_module import CodeLocation, ExternalEntry, ObjectSectionRecord, ExternalLabelKey +from cocas.object_module import CodeLocation, ExternalEntry, ObjectSectionRecord, EntryKey from ...ast_nodes import LabelNode, RelocatableExpressionNode, TemplateFieldNode from ...exceptions import AssemblerException, AssemblerExceptionTag @@ -78,7 +78,7 @@ class ParsedExpression: relocate_additions: int = field(default=0) asect: dict[str, int] = field(default_factory=dict) rel_labels: dict[str, int] = field(default_factory=dict) - ext_labels: dict[ExternalLabelKey, int] = field(default_factory=dict) + ext_labels: dict[EntryKey, int] = field(default_factory=dict) def parse_expression(expr: RelocatableExpressionNode, section: "Section", labels: dict[str, int], @@ -89,8 +89,8 @@ def parse_expression(expr: RelocatableExpressionNode, section: "Section", labels for term, sign in [(t, 1) for t in expr.add_terms] + [(t, -1) for t in expr.sub_terms]: if isinstance(term, LabelNode): if term.name in section.exts: - result.ext_labels[ExternalLabelKey(term.name, section.exts[term.name])] = \ - result.ext_labels.get(ExternalLabelKey(term.name, section.exts[term.name]), 0) + sign + entry_key = EntryKey(term.name, section.exts[term.name]) + result.ext_labels[entry_key] = result.ext_labels.get(entry_key, 0) + sign elif term.name in section.labels and section.name != '$abs': result.rel_labels[term.name] = result.rel_labels.get(term.name, 0) + sign elif term.name in section.labels: diff --git a/cocas/assembler/targets/cdm8e/code_segments.py b/cocas/assembler/targets/cdm8e/code_segments.py index 505e190f..6fcaffea 100644 --- a/cocas/assembler/targets/cdm8e/code_segments.py +++ b/cocas/assembler/targets/cdm8e/code_segments.py @@ -2,7 +2,7 @@ from dataclasses import dataclass, field from typing import TYPE_CHECKING -from cocas.object_module import CodeLocation, ExternalEntry, ObjectSectionRecord, ExternalLabelKey +from cocas.object_module import CodeLocation, ExternalEntry, ObjectSectionRecord, EntryKey from ...ast_nodes import LabelNode, RelocatableExpressionNode, TemplateFieldNode from ...exceptions import AssemblerException, AssemblerExceptionTag @@ -263,14 +263,14 @@ def add_ext_record(obj_rec: "ObjectSectionRecord", ext: str, s: "Section", val: offset = s.address + len(obj_rec.data) if seg.expr.byte_specifier == 'low': obj_rec.external \ - .setdefault(ExternalLabelKey(ext, s.exts[ext]), []) \ + .setdefault(EntryKey(ext, s.exts[ext]), []) \ .append(ExternalEntry(offset, range(0, 1), full_bytes=False)) elif seg.expr.byte_specifier == 'high': entry = ExternalEntry(offset, range(1, 2), full_bytes=False, lower_part=val_lo) - obj_rec.external.setdefault(ExternalLabelKey(ext, s.exts[ext]), []).append(entry) + obj_rec.external.setdefault(EntryKey(ext, s.exts[ext]), []).append(entry) else: obj_rec.external \ - .setdefault(ExternalLabelKey(ext, s.exts[ext]), []) \ + .setdefault(EntryKey(ext, s.exts[ext]), []) \ .append(ExternalEntry(offset, range(0, 2), full_bytes=True)) diff --git a/cocas/linker/linker.py b/cocas/linker/linker.py index 345c549b..bbec7ef5 100644 --- a/cocas/linker/linker.py +++ b/cocas/linker/linker.py @@ -2,7 +2,7 @@ from math import inf from typing import Any, Optional -from cocas.object_module import CodeLocation, ObjectModule, ObjectSectionRecord, concat_rsects, SymbolAttribute, Entry +from cocas.object_module import CodeLocation, ObjectModule, ObjectSectionRecord, concat_rsects, Entry, EntryKey, Linkage from .exceptions import LinkerException from .targets import TargetParams, import_target @@ -70,7 +70,6 @@ def find_referenced_sects(asects: list[ObjectSectionRecord], entry_by_ext: dict[ def find_entries_for_exts(modules: list[ObjectModule]) -> dict[int, Optional[tuple[ObjectSectionRecord, Entry]]]: - # ret: id(ExternalLabelKey) -> (section, entry) ret: dict[int, Optional[tuple[ObjectSectionRecord, Entry]]] = {} # modules_scope: id(ObjectModule) -> (label -> (section, entry)) @@ -80,39 +79,39 @@ def find_entries_for_exts(modules: list[ObjectModule]) -> dict[int, Optional[tup for module in modules: for sect in (module.rsects + module.asects): - for name, entry in sect.entries.items(): - if SymbolAttribute.LOCAL in entry.attrs: - if id(module) in modules_scope and name in modules_scope[id(module)]: - raise LinkerException(f"File-local entry {name} is declared in multiple sections of the same object module") - modules_scope.setdefault(id(module), {})[name] = (sect, entry) - elif SymbolAttribute.WEAK in entry.attrs: - weak_global_scope.setdefault(name, []).append((sect, entry)) + for key, entry in sect.entries.items(): + if key.linkage == Linkage.FILE_LOCAL: + if id(module) in modules_scope and key.name in modules_scope[id(module)]: + raise LinkerException(f"File-local entry {key.name} is declared in multiple sections of the same object module") + modules_scope.setdefault(id(module), {})[key.name] = (sect, entry) + elif key.linkage == Linkage.WEAK_GLOBAL: + weak_global_scope.setdefault(key.name, []).append((sect, entry)) else: - if name in global_scope: - raise LinkerException(f"Global entry {name} is declared in multiple sections") - global_scope[name] = (sect, entry) + if key.name in global_scope: + raise LinkerException(f"Global entry {key.name} is declared in multiple sections") + global_scope[key.name] = (sect, entry) for module in modules: for sect in (module.rsects + module.asects): - for ext in sect.external: - if SymbolAttribute.LOCAL in ext.attributes: - if (not id(module) in modules_scope) or (not ext.label in modules_scope[id(module)]): - raise LinkerException(f'Unresolved file-local ext "{ext.label}"') - ret[id(ext)] = modules_scope[id(module)][ext.label] - elif SymbolAttribute.WEAK in ext.attributes: - if ext.label in global_scope: - ret[id(ext)] = global_scope[ext.label] - elif ext.label in weak_global_scope: - ret[id(ext)] = weak_global_scope[ext.label][0] + for key in sect.external: + if key.linkage == Linkage.FILE_LOCAL: + if (not id(module) in modules_scope) or (not key.name in modules_scope[id(module)]): + raise LinkerException(f'Unresolved file-local ext "{key.name}"') + ret[id(key)] = modules_scope[id(module)][key.name] + elif key.linkage == Linkage.WEAK_GLOBAL: + if key.name in global_scope: + ret[id(key)] = global_scope[key.name] + elif key.name in weak_global_scope: + ret[id(key)] = weak_global_scope[key.name][0] else: - ret[id(ext)] = None + ret[id(key)] = None else: - if ext.label in global_scope: - ret[id(ext)] = global_scope[ext.label] - elif ext.label in weak_global_scope: - ret[id(ext)] = weak_global_scope[ext.label][0] + if key.name in global_scope: + ret[id(key)] = global_scope[key.name] + elif key.name in weak_global_scope: + ret[id(key)] = weak_global_scope[key.name][0] else: - raise LinkerException(f'Unresolved global ext "{ext.label}"') + raise LinkerException(f'Unresolved global ext "{key.name}"') return ret diff --git a/cocas/object_file/generated/ObjectFileLexer.py b/cocas/object_file/generated/ObjectFileLexer.py index b18bb032..89edcbbc 100644 --- a/cocas/object_file/generated/ObjectFileLexer.py +++ b/cocas/object_file/generated/ObjectFileLexer.py @@ -10,85 +10,89 @@ def serializedATN(): return [ - 4,0,28,221,6,-1,6,-1,6,-1,6,-1,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3, + 4,0,29,230,6,-1,6,-1,6,-1,6,-1,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3, 7,3,2,4,7,4,2,5,7,5,2,6,7,6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2, 11,7,11,2,12,7,12,2,13,7,13,2,14,7,14,2,15,7,15,2,16,7,16,2,17,7, 17,2,18,7,18,2,19,7,19,2,20,7,20,2,21,7,21,2,22,7,22,2,23,7,23,2, - 24,7,24,2,25,7,25,2,26,7,26,2,27,7,27,1,0,1,0,1,0,1,0,1,0,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,2,1,2,1,2,1,2,1,2,1,2,1,3,1,3,1,3,1,3,1, - 4,1,4,1,4,1,4,1,4,1,5,1,5,1,5,1,5,1,5,1,6,1,6,1,6,1,6,1,6,1,7,1, - 7,1,7,1,7,1,7,1,7,1,7,1,8,1,8,1,8,1,8,1,9,1,9,1,9,1,9,1,9,1,10,1, - 10,1,10,1,10,1,10,1,11,1,11,1,11,1,11,1,11,1,11,1,12,4,12,127,8, - 12,11,12,12,12,128,1,13,1,13,5,13,133,8,13,10,13,12,13,136,9,13, - 1,13,1,13,5,13,140,8,13,10,13,12,13,143,9,13,1,13,1,13,1,14,1,14, - 1,14,1,14,1,14,1,15,1,15,1,16,1,16,1,17,1,17,1,18,1,18,1,19,3,19, - 161,8,19,1,19,4,19,164,8,19,11,19,12,19,165,1,20,4,20,169,8,20,11, - 20,12,20,170,1,20,1,20,1,21,3,21,176,8,21,1,21,4,21,179,8,21,11, - 21,12,21,180,1,21,1,21,1,22,4,22,186,8,22,11,22,12,22,187,1,23,4, - 23,191,8,23,11,23,12,23,192,1,24,4,24,196,8,24,11,24,12,24,197,1, - 24,1,24,1,25,1,25,1,25,1,25,1,25,1,26,4,26,208,8,26,11,26,12,26, - 209,1,26,1,26,1,26,1,27,4,27,216,8,27,11,27,12,27,217,1,27,1,27, - 0,0,28,5,1,7,2,9,3,11,4,13,5,15,6,17,7,19,8,21,9,23,10,25,11,27, - 12,29,13,31,14,33,15,35,16,37,17,39,18,41,19,43,20,45,21,47,22,49, - 23,51,24,53,25,55,26,57,27,59,28,5,0,1,2,3,4,6,4,0,48,57,65,90,95, - 95,97,122,3,0,65,90,95,95,97,122,5,0,46,46,48,57,65,90,95,95,97, - 122,2,0,9,9,32,32,6,0,9,9,32,32,48,57,65,90,95,95,97,122,2,0,10, - 10,13,13,229,0,5,1,0,0,0,0,7,1,0,0,0,0,9,1,0,0,0,0,11,1,0,0,0,0, - 13,1,0,0,0,0,15,1,0,0,0,0,17,1,0,0,0,0,19,1,0,0,0,0,21,1,0,0,0,0, - 23,1,0,0,0,0,25,1,0,0,0,0,27,1,0,0,0,0,29,1,0,0,0,0,31,1,0,0,0,0, - 33,1,0,0,0,0,35,1,0,0,0,0,37,1,0,0,0,0,39,1,0,0,0,0,41,1,0,0,0,0, - 43,1,0,0,0,0,45,1,0,0,0,1,47,1,0,0,0,1,49,1,0,0,0,2,51,1,0,0,0,2, - 53,1,0,0,0,2,55,1,0,0,0,3,57,1,0,0,0,4,59,1,0,0,0,5,61,1,0,0,0,7, - 66,1,0,0,0,9,73,1,0,0,0,11,79,1,0,0,0,13,83,1,0,0,0,15,88,1,0,0, - 0,17,93,1,0,0,0,19,98,1,0,0,0,21,105,1,0,0,0,23,109,1,0,0,0,25,114, - 1,0,0,0,27,119,1,0,0,0,29,126,1,0,0,0,31,130,1,0,0,0,33,146,1,0, - 0,0,35,151,1,0,0,0,37,153,1,0,0,0,39,155,1,0,0,0,41,157,1,0,0,0, - 43,163,1,0,0,0,45,168,1,0,0,0,47,178,1,0,0,0,49,185,1,0,0,0,51,190, - 1,0,0,0,53,195,1,0,0,0,55,201,1,0,0,0,57,207,1,0,0,0,59,215,1,0, - 0,0,61,62,5,84,0,0,62,63,5,65,0,0,63,64,5,82,0,0,64,65,5,71,0,0, - 65,6,1,0,0,0,66,67,5,70,0,0,67,68,5,73,0,0,68,69,5,76,0,0,69,70, - 5,69,0,0,70,71,1,0,0,0,71,72,6,1,0,0,72,8,1,0,0,0,73,74,5,65,0,0, - 74,75,5,66,0,0,75,76,5,83,0,0,76,77,1,0,0,0,77,78,6,2,1,0,78,10, - 1,0,0,0,79,80,5,76,0,0,80,81,5,79,0,0,81,82,5,67,0,0,82,12,1,0,0, - 0,83,84,5,78,0,0,84,85,5,84,0,0,85,86,5,82,0,0,86,87,5,89,0,0,87, - 14,1,0,0,0,88,89,5,78,0,0,89,90,5,65,0,0,90,91,5,77,0,0,91,92,5, - 69,0,0,92,16,1,0,0,0,93,94,5,65,0,0,94,95,5,76,0,0,95,96,5,73,0, - 0,96,97,5,71,0,0,97,18,1,0,0,0,98,99,5,68,0,0,99,100,5,65,0,0,100, - 101,5,84,0,0,101,102,5,65,0,0,102,103,1,0,0,0,103,104,6,7,2,0,104, - 20,1,0,0,0,105,106,5,82,0,0,106,107,5,69,0,0,107,108,5,76,0,0,108, - 22,1,0,0,0,109,110,5,88,0,0,110,111,5,84,0,0,111,112,5,82,0,0,112, - 113,5,78,0,0,113,24,1,0,0,0,114,115,5,87,0,0,115,116,5,69,0,0,116, - 117,5,65,0,0,117,118,5,75,0,0,118,26,1,0,0,0,119,120,5,76,0,0,120, - 121,5,79,0,0,121,122,5,67,0,0,122,123,5,65,0,0,123,124,5,76,0,0, - 124,28,1,0,0,0,125,127,7,0,0,0,126,125,1,0,0,0,127,128,1,0,0,0,128, - 126,1,0,0,0,128,129,1,0,0,0,129,30,1,0,0,0,130,134,7,1,0,0,131,133, - 7,0,0,0,132,131,1,0,0,0,133,136,1,0,0,0,134,132,1,0,0,0,134,135, - 1,0,0,0,135,137,1,0,0,0,136,134,1,0,0,0,137,141,3,41,18,0,138,140, - 7,2,0,0,139,138,1,0,0,0,140,143,1,0,0,0,141,139,1,0,0,0,141,142, - 1,0,0,0,142,144,1,0,0,0,143,141,1,0,0,0,144,145,7,0,0,0,145,32,1, - 0,0,0,146,147,5,36,0,0,147,148,5,97,0,0,148,149,5,98,0,0,149,150, - 5,115,0,0,150,34,1,0,0,0,151,152,5,58,0,0,152,36,1,0,0,0,153,154, - 5,45,0,0,154,38,1,0,0,0,155,156,5,43,0,0,156,40,1,0,0,0,157,158, - 5,46,0,0,158,42,1,0,0,0,159,161,5,13,0,0,160,159,1,0,0,0,160,161, - 1,0,0,0,161,162,1,0,0,0,162,164,5,10,0,0,163,160,1,0,0,0,164,165, - 1,0,0,0,165,163,1,0,0,0,165,166,1,0,0,0,166,44,1,0,0,0,167,169,7, - 3,0,0,168,167,1,0,0,0,169,170,1,0,0,0,170,168,1,0,0,0,170,171,1, - 0,0,0,171,172,1,0,0,0,172,173,6,20,3,0,173,46,1,0,0,0,174,176,5, - 13,0,0,175,174,1,0,0,0,175,176,1,0,0,0,176,177,1,0,0,0,177,179,5, - 10,0,0,178,175,1,0,0,0,179,180,1,0,0,0,180,178,1,0,0,0,180,181,1, - 0,0,0,181,182,1,0,0,0,182,183,6,21,4,0,183,48,1,0,0,0,184,186,7, - 4,0,0,185,184,1,0,0,0,186,187,1,0,0,0,187,185,1,0,0,0,187,188,1, - 0,0,0,188,50,1,0,0,0,189,191,7,0,0,0,190,189,1,0,0,0,191,192,1,0, - 0,0,192,190,1,0,0,0,192,193,1,0,0,0,193,52,1,0,0,0,194,196,7,3,0, - 0,195,194,1,0,0,0,196,197,1,0,0,0,197,195,1,0,0,0,197,198,1,0,0, - 0,198,199,1,0,0,0,199,200,6,24,3,0,200,54,1,0,0,0,201,202,5,58,0, - 0,202,203,1,0,0,0,203,204,6,25,4,0,204,205,6,25,2,0,205,56,1,0,0, - 0,206,208,5,32,0,0,207,206,1,0,0,0,208,209,1,0,0,0,209,207,1,0,0, - 0,209,210,1,0,0,0,210,211,1,0,0,0,211,212,6,26,4,0,212,213,6,26, - 5,0,213,58,1,0,0,0,214,216,8,5,0,0,215,214,1,0,0,0,216,217,1,0,0, - 0,217,215,1,0,0,0,217,218,1,0,0,0,218,219,1,0,0,0,219,220,6,27,4, - 0,220,60,1,0,0,0,18,0,1,2,3,4,128,134,141,160,165,170,175,180,187, - 192,197,209,217,6,5,3,0,5,2,0,5,1,0,6,0,0,4,0,0,5,4,0 + 24,7,24,2,25,7,25,2,26,7,26,2,27,7,27,2,28,7,28,1,0,1,0,1,0,1,0, + 1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,2,1,2,1,2,1,2,1,2,1,3,1,3, + 1,3,1,3,1,4,1,4,1,4,1,4,1,4,1,5,1,5,1,5,1,5,1,5,1,6,1,6,1,6,1,6, + 1,6,1,7,1,7,1,7,1,7,1,7,1,7,1,7,1,8,1,8,1,8,1,8,1,9,1,9,1,9,1,9, + 1,9,1,10,1,10,1,10,1,10,1,10,1,10,1,10,1,11,1,11,1,11,1,11,1,11, + 1,12,1,12,1,12,1,12,1,12,1,12,1,13,4,13,136,8,13,11,13,12,13,137, + 1,14,1,14,5,14,142,8,14,10,14,12,14,145,9,14,1,14,1,14,5,14,149, + 8,14,10,14,12,14,152,9,14,1,14,1,14,1,15,1,15,1,15,1,15,1,15,1,16, + 1,16,1,17,1,17,1,18,1,18,1,19,1,19,1,20,3,20,170,8,20,1,20,4,20, + 173,8,20,11,20,12,20,174,1,21,4,21,178,8,21,11,21,12,21,179,1,21, + 1,21,1,22,3,22,185,8,22,1,22,4,22,188,8,22,11,22,12,22,189,1,22, + 1,22,1,23,4,23,195,8,23,11,23,12,23,196,1,24,4,24,200,8,24,11,24, + 12,24,201,1,25,4,25,205,8,25,11,25,12,25,206,1,25,1,25,1,26,1,26, + 1,26,1,26,1,26,1,27,4,27,217,8,27,11,27,12,27,218,1,27,1,27,1,27, + 1,28,4,28,225,8,28,11,28,12,28,226,1,28,1,28,0,0,29,5,1,7,2,9,3, + 11,4,13,5,15,6,17,7,19,8,21,9,23,10,25,11,27,12,29,13,31,14,33,15, + 35,16,37,17,39,18,41,19,43,20,45,21,47,22,49,23,51,24,53,25,55,26, + 57,27,59,28,61,29,5,0,1,2,3,4,6,4,0,48,57,65,90,95,95,97,122,3,0, + 65,90,95,95,97,122,5,0,46,46,48,57,65,90,95,95,97,122,2,0,9,9,32, + 32,6,0,9,9,32,32,48,57,65,90,95,95,97,122,2,0,10,10,13,13,238,0, + 5,1,0,0,0,0,7,1,0,0,0,0,9,1,0,0,0,0,11,1,0,0,0,0,13,1,0,0,0,0,15, + 1,0,0,0,0,17,1,0,0,0,0,19,1,0,0,0,0,21,1,0,0,0,0,23,1,0,0,0,0,25, + 1,0,0,0,0,27,1,0,0,0,0,29,1,0,0,0,0,31,1,0,0,0,0,33,1,0,0,0,0,35, + 1,0,0,0,0,37,1,0,0,0,0,39,1,0,0,0,0,41,1,0,0,0,0,43,1,0,0,0,0,45, + 1,0,0,0,0,47,1,0,0,0,1,49,1,0,0,0,1,51,1,0,0,0,2,53,1,0,0,0,2,55, + 1,0,0,0,2,57,1,0,0,0,3,59,1,0,0,0,4,61,1,0,0,0,5,63,1,0,0,0,7,68, + 1,0,0,0,9,75,1,0,0,0,11,81,1,0,0,0,13,85,1,0,0,0,15,90,1,0,0,0,17, + 95,1,0,0,0,19,100,1,0,0,0,21,107,1,0,0,0,23,111,1,0,0,0,25,116,1, + 0,0,0,27,123,1,0,0,0,29,128,1,0,0,0,31,135,1,0,0,0,33,139,1,0,0, + 0,35,155,1,0,0,0,37,160,1,0,0,0,39,162,1,0,0,0,41,164,1,0,0,0,43, + 166,1,0,0,0,45,172,1,0,0,0,47,177,1,0,0,0,49,187,1,0,0,0,51,194, + 1,0,0,0,53,199,1,0,0,0,55,204,1,0,0,0,57,210,1,0,0,0,59,216,1,0, + 0,0,61,224,1,0,0,0,63,64,5,84,0,0,64,65,5,65,0,0,65,66,5,82,0,0, + 66,67,5,71,0,0,67,6,1,0,0,0,68,69,5,70,0,0,69,70,5,73,0,0,70,71, + 5,76,0,0,71,72,5,69,0,0,72,73,1,0,0,0,73,74,6,1,0,0,74,8,1,0,0,0, + 75,76,5,65,0,0,76,77,5,66,0,0,77,78,5,83,0,0,78,79,1,0,0,0,79,80, + 6,2,1,0,80,10,1,0,0,0,81,82,5,76,0,0,82,83,5,79,0,0,83,84,5,67,0, + 0,84,12,1,0,0,0,85,86,5,78,0,0,86,87,5,84,0,0,87,88,5,82,0,0,88, + 89,5,89,0,0,89,14,1,0,0,0,90,91,5,78,0,0,91,92,5,65,0,0,92,93,5, + 77,0,0,93,94,5,69,0,0,94,16,1,0,0,0,95,96,5,65,0,0,96,97,5,76,0, + 0,97,98,5,73,0,0,98,99,5,71,0,0,99,18,1,0,0,0,100,101,5,68,0,0,101, + 102,5,65,0,0,102,103,5,84,0,0,103,104,5,65,0,0,104,105,1,0,0,0,105, + 106,6,7,2,0,106,20,1,0,0,0,107,108,5,82,0,0,108,109,5,69,0,0,109, + 110,5,76,0,0,110,22,1,0,0,0,111,112,5,88,0,0,112,113,5,84,0,0,113, + 114,5,82,0,0,114,115,5,78,0,0,115,24,1,0,0,0,116,117,5,71,0,0,117, + 118,5,76,0,0,118,119,5,79,0,0,119,120,5,66,0,0,120,121,5,65,0,0, + 121,122,5,76,0,0,122,26,1,0,0,0,123,124,5,87,0,0,124,125,5,69,0, + 0,125,126,5,65,0,0,126,127,5,75,0,0,127,28,1,0,0,0,128,129,5,76, + 0,0,129,130,5,79,0,0,130,131,5,67,0,0,131,132,5,65,0,0,132,133,5, + 76,0,0,133,30,1,0,0,0,134,136,7,0,0,0,135,134,1,0,0,0,136,137,1, + 0,0,0,137,135,1,0,0,0,137,138,1,0,0,0,138,32,1,0,0,0,139,143,7,1, + 0,0,140,142,7,0,0,0,141,140,1,0,0,0,142,145,1,0,0,0,143,141,1,0, + 0,0,143,144,1,0,0,0,144,146,1,0,0,0,145,143,1,0,0,0,146,150,3,43, + 19,0,147,149,7,2,0,0,148,147,1,0,0,0,149,152,1,0,0,0,150,148,1,0, + 0,0,150,151,1,0,0,0,151,153,1,0,0,0,152,150,1,0,0,0,153,154,7,0, + 0,0,154,34,1,0,0,0,155,156,5,36,0,0,156,157,5,97,0,0,157,158,5,98, + 0,0,158,159,5,115,0,0,159,36,1,0,0,0,160,161,5,58,0,0,161,38,1,0, + 0,0,162,163,5,45,0,0,163,40,1,0,0,0,164,165,5,43,0,0,165,42,1,0, + 0,0,166,167,5,46,0,0,167,44,1,0,0,0,168,170,5,13,0,0,169,168,1,0, + 0,0,169,170,1,0,0,0,170,171,1,0,0,0,171,173,5,10,0,0,172,169,1,0, + 0,0,173,174,1,0,0,0,174,172,1,0,0,0,174,175,1,0,0,0,175,46,1,0,0, + 0,176,178,7,3,0,0,177,176,1,0,0,0,178,179,1,0,0,0,179,177,1,0,0, + 0,179,180,1,0,0,0,180,181,1,0,0,0,181,182,6,21,3,0,182,48,1,0,0, + 0,183,185,5,13,0,0,184,183,1,0,0,0,184,185,1,0,0,0,185,186,1,0,0, + 0,186,188,5,10,0,0,187,184,1,0,0,0,188,189,1,0,0,0,189,187,1,0,0, + 0,189,190,1,0,0,0,190,191,1,0,0,0,191,192,6,22,4,0,192,50,1,0,0, + 0,193,195,7,4,0,0,194,193,1,0,0,0,195,196,1,0,0,0,196,194,1,0,0, + 0,196,197,1,0,0,0,197,52,1,0,0,0,198,200,7,0,0,0,199,198,1,0,0,0, + 200,201,1,0,0,0,201,199,1,0,0,0,201,202,1,0,0,0,202,54,1,0,0,0,203, + 205,7,3,0,0,204,203,1,0,0,0,205,206,1,0,0,0,206,204,1,0,0,0,206, + 207,1,0,0,0,207,208,1,0,0,0,208,209,6,25,3,0,209,56,1,0,0,0,210, + 211,5,58,0,0,211,212,1,0,0,0,212,213,6,26,4,0,213,214,6,26,2,0,214, + 58,1,0,0,0,215,217,5,32,0,0,216,215,1,0,0,0,217,218,1,0,0,0,218, + 216,1,0,0,0,218,219,1,0,0,0,219,220,1,0,0,0,220,221,6,27,4,0,221, + 222,6,27,5,0,222,60,1,0,0,0,223,225,8,5,0,0,224,223,1,0,0,0,225, + 226,1,0,0,0,226,224,1,0,0,0,226,227,1,0,0,0,227,228,1,0,0,0,228, + 229,6,28,4,0,229,62,1,0,0,0,18,0,1,2,3,4,137,143,150,169,174,179, + 184,189,196,201,206,218,226,6,5,3,0,5,2,0,5,1,0,6,0,0,4,0,0,5,4, + 0 ] class ObjectFileLexer(Lexer): @@ -112,24 +116,25 @@ class ObjectFileLexer(Lexer): DATA = 8 REL = 9 XTRN = 10 - WEAK = 11 - LOCAL = 12 - WORD = 13 - WORD_WITH_DOTS = 14 - ABS_SECTION = 15 - COLON = 16 - MINUS = 17 - PLUS = 18 - DOT = 19 - NEWLINE = 20 - WS = 21 - NEWLINE_BYTES = 22 - BYTES = 23 - WORD_ABS = 24 - WS_ABS = 25 - COLON_ABS = 26 - SPACES_FILE = 27 - FILEPATH = 28 + GLOBAL = 11 + WEAK = 12 + LOCAL = 13 + WORD = 14 + WORD_WITH_DOTS = 15 + ABS_SECTION = 16 + COLON = 17 + MINUS = 18 + PLUS = 19 + DOT = 20 + NEWLINE = 21 + WS = 22 + NEWLINE_BYTES = 23 + BYTES = 24 + WORD_ABS = 25 + WS_ABS = 26 + COLON_ABS = 27 + SPACES_FILE = 28 + FILEPATH = 29 channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ] @@ -137,20 +142,21 @@ class ObjectFileLexer(Lexer): literalNames = [ "", "'TARG'", "'FILE'", "'ABS'", "'LOC'", "'NTRY'", "'NAME'", "'ALIG'", - "'DATA'", "'REL'", "'XTRN'", "'WEAK'", "'LOCAL'", "'$abs'", - "'-'", "'+'", "'.'" ] + "'DATA'", "'REL'", "'XTRN'", "'GLOBAL'", "'WEAK'", "'LOCAL'", + "'$abs'", "'-'", "'+'", "'.'" ] symbolicNames = [ "", "TARG", "FILE", "ABS", "LOC", "NTRY", "NAME", "ALIG", "DATA", - "REL", "XTRN", "WEAK", "LOCAL", "WORD", "WORD_WITH_DOTS", "ABS_SECTION", - "COLON", "MINUS", "PLUS", "DOT", "NEWLINE", "WS", "NEWLINE_BYTES", - "BYTES", "WORD_ABS", "WS_ABS", "COLON_ABS", "SPACES_FILE", "FILEPATH" ] + "REL", "XTRN", "GLOBAL", "WEAK", "LOCAL", "WORD", "WORD_WITH_DOTS", + "ABS_SECTION", "COLON", "MINUS", "PLUS", "DOT", "NEWLINE", "WS", + "NEWLINE_BYTES", "BYTES", "WORD_ABS", "WS_ABS", "COLON_ABS", + "SPACES_FILE", "FILEPATH" ] ruleNames = [ "TARG", "FILE", "ABS", "LOC", "NTRY", "NAME", "ALIG", - "DATA", "REL", "XTRN", "WEAK", "LOCAL", "WORD", "WORD_WITH_DOTS", - "ABS_SECTION", "COLON", "MINUS", "PLUS", "DOT", "NEWLINE", - "WS", "NEWLINE_BYTES", "BYTES", "WORD_ABS", "WS_ABS", - "COLON_ABS", "SPACES_FILE", "FILEPATH" ] + "DATA", "REL", "XTRN", "GLOBAL", "WEAK", "LOCAL", "WORD", + "WORD_WITH_DOTS", "ABS_SECTION", "COLON", "MINUS", "PLUS", + "DOT", "NEWLINE", "WS", "NEWLINE_BYTES", "BYTES", "WORD_ABS", + "WS_ABS", "COLON_ABS", "SPACES_FILE", "FILEPATH" ] grammarFileName = "ObjectFileLexer.g4" diff --git a/cocas/object_file/generated/ObjectFileParser.py b/cocas/object_file/generated/ObjectFileParser.py index ba5d2816..bf41667b 100644 --- a/cocas/object_file/generated/ObjectFileParser.py +++ b/cocas/object_file/generated/ObjectFileParser.py @@ -10,92 +10,90 @@ def serializedATN(): return [ - 4,1,28,253,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, + 4,1,29,248,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, 6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2,13,7,13, 2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7,19,2,20, 7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,2,26,7,26, - 1,0,3,0,56,8,0,1,0,3,0,59,8,0,1,0,4,0,62,8,0,11,0,12,0,63,1,0,1, - 0,1,1,3,1,69,8,1,1,1,1,1,5,1,73,8,1,10,1,12,1,76,9,1,1,1,4,1,79, - 8,1,11,1,12,1,80,3,1,83,8,1,1,1,5,1,86,8,1,10,1,12,1,89,9,1,1,2, - 1,2,4,2,93,8,2,11,2,12,2,94,1,3,1,3,5,3,99,8,3,10,3,12,3,102,9,3, - 1,4,1,4,3,4,106,8,4,1,4,1,4,5,4,110,8,4,10,4,12,4,113,9,4,1,4,3, - 4,116,8,4,1,4,5,4,119,8,4,10,4,12,4,122,9,4,1,5,1,5,1,5,1,5,1,6, - 1,6,1,6,1,6,1,6,1,7,1,7,1,7,1,7,3,7,137,8,7,1,7,4,7,140,8,7,11,7, - 12,7,141,1,8,1,8,5,8,146,8,8,10,8,12,8,149,9,8,1,8,1,8,1,9,1,9,1, - 9,1,9,5,9,157,8,9,10,9,12,9,160,9,9,1,9,1,9,1,9,1,10,1,10,1,10,1, - 10,1,11,1,11,1,11,1,11,1,12,1,12,3,12,175,8,12,1,12,4,12,178,8,12, - 11,12,12,12,179,1,13,1,13,5,13,184,8,13,10,13,12,13,187,9,13,1,13, - 1,13,1,14,1,14,1,14,1,14,5,14,195,8,14,10,14,12,14,198,9,14,1,14, - 1,14,1,14,1,14,5,14,204,8,14,10,14,12,14,207,9,14,1,14,1,14,1,15, - 1,15,3,15,213,8,15,1,16,1,16,1,17,1,17,1,18,3,18,220,8,18,1,18,1, - 18,1,18,1,18,3,18,226,8,18,3,18,228,8,18,1,19,1,19,1,19,1,19,1,20, - 1,20,1,20,1,21,1,21,1,21,1,21,1,21,1,21,1,22,1,22,1,23,1,23,1,24, - 1,24,1,25,1,25,1,26,1,26,1,26,0,0,27,0,2,4,6,8,10,12,14,16,18,20, - 22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,0,2,1,0,13,14,2, - 0,13,13,15,15,253,0,55,1,0,0,0,2,68,1,0,0,0,4,92,1,0,0,0,6,96,1, - 0,0,0,8,103,1,0,0,0,10,123,1,0,0,0,12,127,1,0,0,0,14,132,1,0,0,0, - 16,143,1,0,0,0,18,152,1,0,0,0,20,164,1,0,0,0,22,168,1,0,0,0,24,172, - 1,0,0,0,26,181,1,0,0,0,28,190,1,0,0,0,30,212,1,0,0,0,32,214,1,0, - 0,0,34,216,1,0,0,0,36,219,1,0,0,0,38,229,1,0,0,0,40,233,1,0,0,0, - 42,236,1,0,0,0,44,242,1,0,0,0,46,244,1,0,0,0,48,246,1,0,0,0,50,248, - 1,0,0,0,52,250,1,0,0,0,54,56,5,20,0,0,55,54,1,0,0,0,55,56,1,0,0, - 0,56,58,1,0,0,0,57,59,3,10,5,0,58,57,1,0,0,0,58,59,1,0,0,0,59,61, - 1,0,0,0,60,62,3,2,1,0,61,60,1,0,0,0,62,63,1,0,0,0,63,61,1,0,0,0, - 63,64,1,0,0,0,64,65,1,0,0,0,65,66,5,0,0,1,66,1,1,0,0,0,67,69,3,12, - 6,0,68,67,1,0,0,0,68,69,1,0,0,0,69,82,1,0,0,0,70,74,3,4,2,0,71,73, - 3,8,4,0,72,71,1,0,0,0,73,76,1,0,0,0,74,72,1,0,0,0,74,75,1,0,0,0, - 75,83,1,0,0,0,76,74,1,0,0,0,77,79,3,8,4,0,78,77,1,0,0,0,79,80,1, - 0,0,0,80,78,1,0,0,0,80,81,1,0,0,0,81,83,1,0,0,0,82,70,1,0,0,0,82, - 78,1,0,0,0,83,87,1,0,0,0,84,86,3,28,14,0,85,84,1,0,0,0,86,89,1,0, - 0,0,87,85,1,0,0,0,87,88,1,0,0,0,88,3,1,0,0,0,89,87,1,0,0,0,90,93, - 3,6,3,0,91,93,3,18,9,0,92,90,1,0,0,0,92,91,1,0,0,0,93,94,1,0,0,0, - 94,92,1,0,0,0,94,95,1,0,0,0,95,5,1,0,0,0,96,100,3,14,7,0,97,99,3, - 16,8,0,98,97,1,0,0,0,99,102,1,0,0,0,100,98,1,0,0,0,100,101,1,0,0, - 0,101,7,1,0,0,0,102,100,1,0,0,0,103,105,3,20,10,0,104,106,3,22,11, - 0,105,104,1,0,0,0,105,106,1,0,0,0,106,107,1,0,0,0,107,111,3,24,12, - 0,108,110,3,16,8,0,109,108,1,0,0,0,110,113,1,0,0,0,111,109,1,0,0, - 0,111,112,1,0,0,0,112,115,1,0,0,0,113,111,1,0,0,0,114,116,3,26,13, - 0,115,114,1,0,0,0,115,116,1,0,0,0,116,120,1,0,0,0,117,119,3,18,9, - 0,118,117,1,0,0,0,119,122,1,0,0,0,120,118,1,0,0,0,120,121,1,0,0, - 0,121,9,1,0,0,0,122,120,1,0,0,0,123,124,5,1,0,0,124,125,3,48,24, - 0,125,126,5,20,0,0,126,11,1,0,0,0,127,128,5,2,0,0,128,129,5,27,0, - 0,129,130,3,34,17,0,130,131,5,20,0,0,131,13,1,0,0,0,132,133,5,3, - 0,0,133,134,3,44,22,0,134,136,5,26,0,0,135,137,3,32,16,0,136,135, - 1,0,0,0,136,137,1,0,0,0,137,139,1,0,0,0,138,140,5,22,0,0,139,138, - 1,0,0,0,140,141,1,0,0,0,141,139,1,0,0,0,141,142,1,0,0,0,142,15,1, - 0,0,0,143,147,5,4,0,0,144,146,3,42,21,0,145,144,1,0,0,0,146,149, - 1,0,0,0,147,145,1,0,0,0,147,148,1,0,0,0,148,150,1,0,0,0,149,147, - 1,0,0,0,150,151,5,20,0,0,151,17,1,0,0,0,152,153,5,5,0,0,153,158, - 3,48,24,0,154,155,5,18,0,0,155,157,3,30,15,0,156,154,1,0,0,0,157, - 160,1,0,0,0,158,156,1,0,0,0,158,159,1,0,0,0,159,161,1,0,0,0,160, - 158,1,0,0,0,161,162,3,46,23,0,162,163,5,20,0,0,163,19,1,0,0,0,164, - 165,5,6,0,0,165,166,3,50,25,0,166,167,5,20,0,0,167,21,1,0,0,0,168, - 169,5,7,0,0,169,170,3,46,23,0,170,171,5,20,0,0,171,23,1,0,0,0,172, - 174,5,8,0,0,173,175,3,32,16,0,174,173,1,0,0,0,174,175,1,0,0,0,175, - 177,1,0,0,0,176,178,5,22,0,0,177,176,1,0,0,0,178,179,1,0,0,0,179, - 177,1,0,0,0,179,180,1,0,0,0,180,25,1,0,0,0,181,185,5,9,0,0,182,184, - 3,36,18,0,183,182,1,0,0,0,184,187,1,0,0,0,185,183,1,0,0,0,185,186, - 1,0,0,0,186,188,1,0,0,0,187,185,1,0,0,0,188,189,5,20,0,0,189,27, - 1,0,0,0,190,191,5,10,0,0,191,196,3,48,24,0,192,193,5,18,0,0,193, - 195,3,30,15,0,194,192,1,0,0,0,195,198,1,0,0,0,196,194,1,0,0,0,196, - 197,1,0,0,0,197,199,1,0,0,0,198,196,1,0,0,0,199,205,5,16,0,0,200, - 201,3,50,25,0,201,202,3,36,18,0,202,204,1,0,0,0,203,200,1,0,0,0, - 204,207,1,0,0,0,205,203,1,0,0,0,205,206,1,0,0,0,206,208,1,0,0,0, - 207,205,1,0,0,0,208,209,5,20,0,0,209,29,1,0,0,0,210,213,5,11,0,0, - 211,213,5,12,0,0,212,210,1,0,0,0,212,211,1,0,0,0,213,31,1,0,0,0, - 214,215,5,23,0,0,215,33,1,0,0,0,216,217,5,28,0,0,217,35,1,0,0,0, - 218,220,3,52,26,0,219,218,1,0,0,0,219,220,1,0,0,0,220,221,1,0,0, - 0,221,227,3,46,23,0,222,223,5,16,0,0,223,225,3,38,19,0,224,226,3, - 40,20,0,225,224,1,0,0,0,225,226,1,0,0,0,226,228,1,0,0,0,227,222, - 1,0,0,0,227,228,1,0,0,0,228,37,1,0,0,0,229,230,3,46,23,0,230,231, - 5,16,0,0,231,232,3,46,23,0,232,39,1,0,0,0,233,234,5,18,0,0,234,235, - 3,46,23,0,235,41,1,0,0,0,236,237,3,46,23,0,237,238,5,16,0,0,238, - 239,3,46,23,0,239,240,5,16,0,0,240,241,3,46,23,0,241,43,1,0,0,0, - 242,243,5,24,0,0,243,45,1,0,0,0,244,245,5,13,0,0,245,47,1,0,0,0, - 246,247,7,0,0,0,247,49,1,0,0,0,248,249,7,1,0,0,249,51,1,0,0,0,250, - 251,5,17,0,0,251,53,1,0,0,0,28,55,58,63,68,74,80,82,87,92,94,100, - 105,111,115,120,136,141,147,158,174,179,185,196,205,212,219,225, - 227 + 2,27,7,27,1,0,3,0,58,8,0,1,0,3,0,61,8,0,1,0,4,0,64,8,0,11,0,12,0, + 65,1,0,1,0,1,1,3,1,71,8,1,1,1,1,1,5,1,75,8,1,10,1,12,1,78,9,1,1, + 1,4,1,81,8,1,11,1,12,1,82,3,1,85,8,1,1,1,5,1,88,8,1,10,1,12,1,91, + 9,1,1,2,1,2,4,2,95,8,2,11,2,12,2,96,1,3,1,3,5,3,101,8,3,10,3,12, + 3,104,9,3,1,4,1,4,3,4,108,8,4,1,4,1,4,5,4,112,8,4,10,4,12,4,115, + 9,4,1,4,3,4,118,8,4,1,4,5,4,121,8,4,10,4,12,4,124,9,4,1,5,1,5,1, + 5,1,5,1,6,1,6,1,6,1,6,1,6,1,7,1,7,1,7,1,7,3,7,139,8,7,1,7,4,7,142, + 8,7,11,7,12,7,143,1,8,1,8,5,8,148,8,8,10,8,12,8,151,9,8,1,8,1,8, + 1,9,1,9,1,9,1,9,1,9,1,9,1,10,1,10,1,10,1,10,1,11,1,11,1,11,1,11, + 1,12,1,12,3,12,171,8,12,1,12,4,12,174,8,12,11,12,12,12,175,1,13, + 1,13,5,13,180,8,13,10,13,12,13,183,9,13,1,13,1,13,1,14,1,14,1,14, + 1,14,1,14,1,14,1,14,5,14,194,8,14,10,14,12,14,197,9,14,1,14,1,14, + 1,15,1,15,3,15,203,8,15,1,16,1,16,1,16,3,16,208,8,16,1,17,1,17,1, + 18,1,18,1,19,3,19,215,8,19,1,19,1,19,1,19,1,19,3,19,221,8,19,3,19, + 223,8,19,1,20,1,20,1,20,1,20,1,21,1,21,1,21,1,22,1,22,1,22,1,22, + 1,22,1,22,1,23,1,23,1,24,1,24,1,25,1,25,1,26,1,26,1,27,1,27,1,27, + 0,0,28,0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40, + 42,44,46,48,50,52,54,0,2,1,0,14,15,2,0,14,14,16,16,247,0,57,1,0, + 0,0,2,70,1,0,0,0,4,94,1,0,0,0,6,98,1,0,0,0,8,105,1,0,0,0,10,125, + 1,0,0,0,12,129,1,0,0,0,14,134,1,0,0,0,16,145,1,0,0,0,18,154,1,0, + 0,0,20,160,1,0,0,0,22,164,1,0,0,0,24,168,1,0,0,0,26,177,1,0,0,0, + 28,186,1,0,0,0,30,202,1,0,0,0,32,207,1,0,0,0,34,209,1,0,0,0,36,211, + 1,0,0,0,38,214,1,0,0,0,40,224,1,0,0,0,42,228,1,0,0,0,44,231,1,0, + 0,0,46,237,1,0,0,0,48,239,1,0,0,0,50,241,1,0,0,0,52,243,1,0,0,0, + 54,245,1,0,0,0,56,58,5,21,0,0,57,56,1,0,0,0,57,58,1,0,0,0,58,60, + 1,0,0,0,59,61,3,10,5,0,60,59,1,0,0,0,60,61,1,0,0,0,61,63,1,0,0,0, + 62,64,3,2,1,0,63,62,1,0,0,0,64,65,1,0,0,0,65,63,1,0,0,0,65,66,1, + 0,0,0,66,67,1,0,0,0,67,68,5,0,0,1,68,1,1,0,0,0,69,71,3,12,6,0,70, + 69,1,0,0,0,70,71,1,0,0,0,71,84,1,0,0,0,72,76,3,4,2,0,73,75,3,8,4, + 0,74,73,1,0,0,0,75,78,1,0,0,0,76,74,1,0,0,0,76,77,1,0,0,0,77,85, + 1,0,0,0,78,76,1,0,0,0,79,81,3,8,4,0,80,79,1,0,0,0,81,82,1,0,0,0, + 82,80,1,0,0,0,82,83,1,0,0,0,83,85,1,0,0,0,84,72,1,0,0,0,84,80,1, + 0,0,0,85,89,1,0,0,0,86,88,3,28,14,0,87,86,1,0,0,0,88,91,1,0,0,0, + 89,87,1,0,0,0,89,90,1,0,0,0,90,3,1,0,0,0,91,89,1,0,0,0,92,95,3,6, + 3,0,93,95,3,18,9,0,94,92,1,0,0,0,94,93,1,0,0,0,95,96,1,0,0,0,96, + 94,1,0,0,0,96,97,1,0,0,0,97,5,1,0,0,0,98,102,3,14,7,0,99,101,3,16, + 8,0,100,99,1,0,0,0,101,104,1,0,0,0,102,100,1,0,0,0,102,103,1,0,0, + 0,103,7,1,0,0,0,104,102,1,0,0,0,105,107,3,20,10,0,106,108,3,22,11, + 0,107,106,1,0,0,0,107,108,1,0,0,0,108,109,1,0,0,0,109,113,3,24,12, + 0,110,112,3,16,8,0,111,110,1,0,0,0,112,115,1,0,0,0,113,111,1,0,0, + 0,113,114,1,0,0,0,114,117,1,0,0,0,115,113,1,0,0,0,116,118,3,26,13, + 0,117,116,1,0,0,0,117,118,1,0,0,0,118,122,1,0,0,0,119,121,3,18,9, + 0,120,119,1,0,0,0,121,124,1,0,0,0,122,120,1,0,0,0,122,123,1,0,0, + 0,123,9,1,0,0,0,124,122,1,0,0,0,125,126,5,1,0,0,126,127,3,50,25, + 0,127,128,5,21,0,0,128,11,1,0,0,0,129,130,5,2,0,0,130,131,5,28,0, + 0,131,132,3,36,18,0,132,133,5,21,0,0,133,13,1,0,0,0,134,135,5,3, + 0,0,135,136,3,46,23,0,136,138,5,27,0,0,137,139,3,34,17,0,138,137, + 1,0,0,0,138,139,1,0,0,0,139,141,1,0,0,0,140,142,5,23,0,0,141,140, + 1,0,0,0,142,143,1,0,0,0,143,141,1,0,0,0,143,144,1,0,0,0,144,15,1, + 0,0,0,145,149,5,4,0,0,146,148,3,44,22,0,147,146,1,0,0,0,148,151, + 1,0,0,0,149,147,1,0,0,0,149,150,1,0,0,0,150,152,1,0,0,0,151,149, + 1,0,0,0,152,153,5,21,0,0,153,17,1,0,0,0,154,155,5,5,0,0,155,156, + 3,50,25,0,156,157,3,30,15,0,157,158,3,48,24,0,158,159,5,21,0,0,159, + 19,1,0,0,0,160,161,5,6,0,0,161,162,3,52,26,0,162,163,5,21,0,0,163, + 21,1,0,0,0,164,165,5,7,0,0,165,166,3,48,24,0,166,167,5,21,0,0,167, + 23,1,0,0,0,168,170,5,8,0,0,169,171,3,34,17,0,170,169,1,0,0,0,170, + 171,1,0,0,0,171,173,1,0,0,0,172,174,5,23,0,0,173,172,1,0,0,0,174, + 175,1,0,0,0,175,173,1,0,0,0,175,176,1,0,0,0,176,25,1,0,0,0,177,181, + 5,9,0,0,178,180,3,38,19,0,179,178,1,0,0,0,180,183,1,0,0,0,181,179, + 1,0,0,0,181,182,1,0,0,0,182,184,1,0,0,0,183,181,1,0,0,0,184,185, + 5,21,0,0,185,27,1,0,0,0,186,187,5,10,0,0,187,188,3,50,25,0,188,189, + 3,30,15,0,189,195,5,17,0,0,190,191,3,52,26,0,191,192,3,38,19,0,192, + 194,1,0,0,0,193,190,1,0,0,0,194,197,1,0,0,0,195,193,1,0,0,0,195, + 196,1,0,0,0,196,198,1,0,0,0,197,195,1,0,0,0,198,199,5,21,0,0,199, + 29,1,0,0,0,200,201,5,19,0,0,201,203,3,32,16,0,202,200,1,0,0,0,202, + 203,1,0,0,0,203,31,1,0,0,0,204,208,5,11,0,0,205,208,5,12,0,0,206, + 208,5,13,0,0,207,204,1,0,0,0,207,205,1,0,0,0,207,206,1,0,0,0,208, + 33,1,0,0,0,209,210,5,24,0,0,210,35,1,0,0,0,211,212,5,29,0,0,212, + 37,1,0,0,0,213,215,3,54,27,0,214,213,1,0,0,0,214,215,1,0,0,0,215, + 216,1,0,0,0,216,222,3,48,24,0,217,218,5,17,0,0,218,220,3,40,20,0, + 219,221,3,42,21,0,220,219,1,0,0,0,220,221,1,0,0,0,221,223,1,0,0, + 0,222,217,1,0,0,0,222,223,1,0,0,0,223,39,1,0,0,0,224,225,3,48,24, + 0,225,226,5,17,0,0,226,227,3,48,24,0,227,41,1,0,0,0,228,229,5,19, + 0,0,229,230,3,48,24,0,230,43,1,0,0,0,231,232,3,48,24,0,232,233,5, + 17,0,0,233,234,3,48,24,0,234,235,5,17,0,0,235,236,3,48,24,0,236, + 45,1,0,0,0,237,238,5,25,0,0,238,47,1,0,0,0,239,240,5,14,0,0,240, + 49,1,0,0,0,241,242,7,0,0,0,242,51,1,0,0,0,243,244,7,1,0,0,244,53, + 1,0,0,0,245,246,5,18,0,0,246,55,1,0,0,0,27,57,60,65,70,76,82,84, + 89,94,96,102,107,113,117,122,138,143,149,170,175,181,195,202,207, + 214,220,222 ] class ObjectFileParser ( Parser ): @@ -110,15 +108,15 @@ class ObjectFileParser ( Parser ): literalNames = [ "", "'TARG'", "'FILE'", "'ABS'", "'LOC'", "'NTRY'", "'NAME'", "'ALIG'", "'DATA'", "'REL'", "'XTRN'", - "'WEAK'", "'LOCAL'", "", "", "'$abs'", - "", "'-'", "'+'", "'.'" ] + "'GLOBAL'", "'WEAK'", "'LOCAL'", "", "", + "'$abs'", "", "'-'", "'+'", "'.'" ] symbolicNames = [ "", "TARG", "FILE", "ABS", "LOC", "NTRY", - "NAME", "ALIG", "DATA", "REL", "XTRN", "WEAK", "LOCAL", - "WORD", "WORD_WITH_DOTS", "ABS_SECTION", "COLON", - "MINUS", "PLUS", "DOT", "NEWLINE", "WS", "NEWLINE_BYTES", - "BYTES", "WORD_ABS", "WS_ABS", "COLON_ABS", "SPACES_FILE", - "FILEPATH" ] + "NAME", "ALIG", "DATA", "REL", "XTRN", "GLOBAL", "WEAK", + "LOCAL", "WORD", "WORD_WITH_DOTS", "ABS_SECTION", + "COLON", "MINUS", "PLUS", "DOT", "NEWLINE", "WS", + "NEWLINE_BYTES", "BYTES", "WORD_ABS", "WS_ABS", "COLON_ABS", + "SPACES_FILE", "FILEPATH" ] RULE_object_file = 0 RULE_object_block = 1 @@ -135,26 +133,27 @@ class ObjectFileParser ( Parser ): RULE_data_record = 12 RULE_rel_record = 13 RULE_xtrn_record = 14 - RULE_attribute = 15 - RULE_data = 16 - RULE_filepath = 17 - RULE_entry_usage = 18 - RULE_range = 19 - RULE_lower_part = 20 - RULE_location = 21 - RULE_abs_address = 22 - RULE_number = 23 - RULE_label = 24 - RULE_section = 25 - RULE_minus = 26 + RULE_linkage_spec = 15 + RULE_linkage = 16 + RULE_data = 17 + RULE_filepath = 18 + RULE_entry_usage = 19 + RULE_range = 20 + RULE_lower_part = 21 + RULE_location = 22 + RULE_abs_address = 23 + RULE_number = 24 + RULE_label = 25 + RULE_section = 26 + RULE_minus = 27 ruleNames = [ "object_file", "object_block", "asect_block", "abs_block", "rsect_block", "targ_record", "source_record", "abs_record", "loc_record", "ntry_record", "name_record", "alig_record", - "data_record", "rel_record", "xtrn_record", "attribute", - "data", "filepath", "entry_usage", "range", "lower_part", - "location", "abs_address", "number", "label", "section", - "minus" ] + "data_record", "rel_record", "xtrn_record", "linkage_spec", + "linkage", "data", "filepath", "entry_usage", "range", + "lower_part", "location", "abs_address", "number", "label", + "section", "minus" ] EOF = Token.EOF TARG=1 @@ -167,24 +166,25 @@ class ObjectFileParser ( Parser ): DATA=8 REL=9 XTRN=10 - WEAK=11 - LOCAL=12 - WORD=13 - WORD_WITH_DOTS=14 - ABS_SECTION=15 - COLON=16 - MINUS=17 - PLUS=18 - DOT=19 - NEWLINE=20 - WS=21 - NEWLINE_BYTES=22 - BYTES=23 - WORD_ABS=24 - WS_ABS=25 - COLON_ABS=26 - SPACES_FILE=27 - FILEPATH=28 + GLOBAL=11 + WEAK=12 + LOCAL=13 + WORD=14 + WORD_WITH_DOTS=15 + ABS_SECTION=16 + COLON=17 + MINUS=18 + PLUS=19 + DOT=20 + NEWLINE=21 + WS=22 + NEWLINE_BYTES=23 + BYTES=24 + WORD_ABS=25 + WS_ABS=26 + COLON_ABS=27 + SPACES_FILE=28 + FILEPATH=29 def __init__(self, input:TokenStream, output:TextIO = sys.stdout): super().__init__(input, output) @@ -238,35 +238,35 @@ def object_file(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 55 + self.state = 57 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==20: - self.state = 54 + if _la==21: + self.state = 56 self.match(ObjectFileParser.NEWLINE) - self.state = 58 + self.state = 60 self._errHandler.sync(self) _la = self._input.LA(1) if _la==1: - self.state = 57 + self.state = 59 self.targ_record() - self.state = 61 + self.state = 63 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 60 + self.state = 62 self.object_block() - self.state = 63 + self.state = 65 self._errHandler.sync(self) _la = self._input.LA(1) if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & 108) != 0)): break - self.state = 65 + self.state = 67 self.match(ObjectFileParser.EOF) except RecognitionException as re: localctx.exception = re @@ -325,44 +325,44 @@ def object_block(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 68 + self.state = 70 self._errHandler.sync(self) _la = self._input.LA(1) if _la==2: - self.state = 67 + self.state = 69 self.source_record() - self.state = 82 + self.state = 84 self._errHandler.sync(self) token = self._input.LA(1) if token in [3, 5]: - self.state = 70 + self.state = 72 self.asect_block() - self.state = 74 + self.state = 76 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,4,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 71 + self.state = 73 self.rsect_block() - self.state = 76 + self.state = 78 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,4,self._ctx) pass elif token in [6]: - self.state = 78 + self.state = 80 self._errHandler.sync(self) _alt = 1 while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt == 1: - self.state = 77 + self.state = 79 self.rsect_block() else: raise NoViableAltException(self) - self.state = 80 + self.state = 82 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,5,self._ctx) @@ -370,13 +370,13 @@ def object_block(self): else: raise NoViableAltException(self) - self.state = 87 + self.state = 89 self._errHandler.sync(self) _la = self._input.LA(1) while _la==10: - self.state = 84 + self.state = 86 self.xtrn_record() - self.state = 89 + self.state = 91 self._errHandler.sync(self) _la = self._input.LA(1) @@ -428,20 +428,20 @@ def asect_block(self): self.enterRule(localctx, 4, self.RULE_asect_block) try: self.enterOuterAlt(localctx, 1) - self.state = 92 + self.state = 94 self._errHandler.sync(self) _alt = 1 while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt == 1: - self.state = 92 + self.state = 94 self._errHandler.sync(self) token = self._input.LA(1) if token in [3]: - self.state = 90 + self.state = 92 self.abs_block() pass elif token in [5]: - self.state = 91 + self.state = 93 self.ntry_record() pass else: @@ -450,7 +450,7 @@ def asect_block(self): else: raise NoViableAltException(self) - self.state = 94 + self.state = 96 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,9,self._ctx) @@ -500,15 +500,15 @@ def abs_block(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 96 + self.state = 98 self.abs_record() - self.state = 100 + self.state = 102 self._errHandler.sync(self) _la = self._input.LA(1) while _la==4: - self.state = 97 + self.state = 99 self.loc_record() - self.state = 102 + self.state = 104 self._errHandler.sync(self) _la = self._input.LA(1) @@ -577,44 +577,44 @@ def rsect_block(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 103 - self.name_record() self.state = 105 + self.name_record() + self.state = 107 self._errHandler.sync(self) _la = self._input.LA(1) if _la==7: - self.state = 104 + self.state = 106 self.alig_record() - self.state = 107 + self.state = 109 self.data_record() - self.state = 111 + self.state = 113 self._errHandler.sync(self) _la = self._input.LA(1) while _la==4: - self.state = 108 + self.state = 110 self.loc_record() - self.state = 113 + self.state = 115 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 115 + self.state = 117 self._errHandler.sync(self) _la = self._input.LA(1) if _la==9: - self.state = 114 + self.state = 116 self.rel_record() - self.state = 120 + self.state = 122 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,14,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 117 + self.state = 119 self.ntry_record() - self.state = 122 + self.state = 124 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,14,self._ctx) @@ -662,11 +662,11 @@ def targ_record(self): self.enterRule(localctx, 10, self.RULE_targ_record) try: self.enterOuterAlt(localctx, 1) - self.state = 123 + self.state = 125 self.match(ObjectFileParser.TARG) - self.state = 124 + self.state = 126 self.label() - self.state = 125 + self.state = 127 self.match(ObjectFileParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -715,13 +715,13 @@ def source_record(self): self.enterRule(localctx, 12, self.RULE_source_record) try: self.enterOuterAlt(localctx, 1) - self.state = 127 + self.state = 129 self.match(ObjectFileParser.FILE) - self.state = 128 + self.state = 130 self.match(ObjectFileParser.SPACES_FILE) - self.state = 129 + self.state = 131 self.filepath() - self.state = 130 + self.state = 132 self.match(ObjectFileParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -778,30 +778,30 @@ def abs_record(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 132 + self.state = 134 self.match(ObjectFileParser.ABS) - self.state = 133 + self.state = 135 self.abs_address() - self.state = 134 - self.match(ObjectFileParser.COLON_ABS) self.state = 136 + self.match(ObjectFileParser.COLON_ABS) + self.state = 138 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==23: - self.state = 135 + if _la==24: + self.state = 137 self.data() - self.state = 139 + self.state = 141 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 138 + self.state = 140 self.match(ObjectFileParser.NEWLINE_BYTES) - self.state = 141 + self.state = 143 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==22): + if not (_la==23): break except RecognitionException as re: @@ -852,19 +852,19 @@ def loc_record(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 143 + self.state = 145 self.match(ObjectFileParser.LOC) - self.state = 147 + self.state = 149 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==13: - self.state = 144 + while _la==14: + self.state = 146 self.location() - self.state = 149 + self.state = 151 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 150 + self.state = 152 self.match(ObjectFileParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -889,6 +889,10 @@ def label(self): return self.getTypedRuleContext(ObjectFileParser.LabelContext,0) + def linkage_spec(self): + return self.getTypedRuleContext(ObjectFileParser.Linkage_specContext,0) + + def number(self): return self.getTypedRuleContext(ObjectFileParser.NumberContext,0) @@ -896,19 +900,6 @@ def number(self): def NEWLINE(self): return self.getToken(ObjectFileParser.NEWLINE, 0) - def PLUS(self, i:int=None): - if i is None: - return self.getTokens(ObjectFileParser.PLUS) - else: - return self.getToken(ObjectFileParser.PLUS, i) - - def attribute(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(ObjectFileParser.AttributeContext) - else: - return self.getTypedRuleContext(ObjectFileParser.AttributeContext,i) - - def getRuleIndex(self): return ObjectFileParser.RULE_ntry_record @@ -925,28 +916,17 @@ def ntry_record(self): localctx = ObjectFileParser.Ntry_recordContext(self, self._ctx, self.state) self.enterRule(localctx, 18, self.RULE_ntry_record) - self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 152 + self.state = 154 self.match(ObjectFileParser.NTRY) - self.state = 153 + self.state = 155 self.label() - self.state = 158 - self._errHandler.sync(self) - _la = self._input.LA(1) - while _la==18: - self.state = 154 - self.match(ObjectFileParser.PLUS) - self.state = 155 - self.attribute() - self.state = 160 - self._errHandler.sync(self) - _la = self._input.LA(1) - - self.state = 161 + self.state = 156 + self.linkage_spec() + self.state = 157 self.number() - self.state = 162 + self.state = 158 self.match(ObjectFileParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -992,11 +972,11 @@ def name_record(self): self.enterRule(localctx, 20, self.RULE_name_record) try: self.enterOuterAlt(localctx, 1) - self.state = 164 + self.state = 160 self.match(ObjectFileParser.NAME) - self.state = 165 + self.state = 161 self.section() - self.state = 166 + self.state = 162 self.match(ObjectFileParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -1042,11 +1022,11 @@ def alig_record(self): self.enterRule(localctx, 22, self.RULE_alig_record) try: self.enterOuterAlt(localctx, 1) - self.state = 168 + self.state = 164 self.match(ObjectFileParser.ALIG) - self.state = 169 + self.state = 165 self.number() - self.state = 170 + self.state = 166 self.match(ObjectFileParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -1096,26 +1076,26 @@ def data_record(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 172 + self.state = 168 self.match(ObjectFileParser.DATA) - self.state = 174 + self.state = 170 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==23: - self.state = 173 + if _la==24: + self.state = 169 self.data() - self.state = 177 + self.state = 173 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 176 + self.state = 172 self.match(ObjectFileParser.NEWLINE_BYTES) - self.state = 179 + self.state = 175 self._errHandler.sync(self) _la = self._input.LA(1) - if not (_la==22): + if not (_la==23): break except RecognitionException as re: @@ -1166,19 +1146,19 @@ def rel_record(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 181 + self.state = 177 self.match(ObjectFileParser.REL) - self.state = 185 + self.state = 181 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==13 or _la==17: - self.state = 182 + while _la==14 or _la==18: + self.state = 178 self.entry_usage() - self.state = 187 + self.state = 183 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 188 + self.state = 184 self.match(ObjectFileParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -1203,25 +1183,16 @@ def label(self): return self.getTypedRuleContext(ObjectFileParser.LabelContext,0) + def linkage_spec(self): + return self.getTypedRuleContext(ObjectFileParser.Linkage_specContext,0) + + def COLON(self): return self.getToken(ObjectFileParser.COLON, 0) def NEWLINE(self): return self.getToken(ObjectFileParser.NEWLINE, 0) - def PLUS(self, i:int=None): - if i is None: - return self.getTokens(ObjectFileParser.PLUS) - else: - return self.getToken(ObjectFileParser.PLUS, i) - - def attribute(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(ObjectFileParser.AttributeContext) - else: - return self.getTypedRuleContext(ObjectFileParser.AttributeContext,i) - - def section(self, i:int=None): if i is None: return self.getTypedRuleContexts(ObjectFileParser.SectionContext) @@ -1255,38 +1226,80 @@ def xtrn_record(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 190 + self.state = 186 self.match(ObjectFileParser.XTRN) - self.state = 191 + self.state = 187 self.label() - self.state = 196 + self.state = 188 + self.linkage_spec() + self.state = 189 + self.match(ObjectFileParser.COLON) + self.state = 195 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==18: - self.state = 192 - self.match(ObjectFileParser.PLUS) - self.state = 193 - self.attribute() - self.state = 198 + while _la==14 or _la==16: + self.state = 190 + self.section() + self.state = 191 + self.entry_usage() + self.state = 197 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 199 - self.match(ObjectFileParser.COLON) - self.state = 205 + self.state = 198 + self.match(ObjectFileParser.NEWLINE) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + + class Linkage_specContext(ParserRuleContext): + __slots__ = 'parser' + + def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): + super().__init__(parent, invokingState) + self.parser = parser + + def PLUS(self): + return self.getToken(ObjectFileParser.PLUS, 0) + + def linkage(self): + return self.getTypedRuleContext(ObjectFileParser.LinkageContext,0) + + + def getRuleIndex(self): + return ObjectFileParser.RULE_linkage_spec + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitLinkage_spec" ): + return visitor.visitLinkage_spec(self) + else: + return visitor.visitChildren(self) + + + + + def linkage_spec(self): + + localctx = ObjectFileParser.Linkage_specContext(self, self._ctx, self.state) + self.enterRule(localctx, 30, self.RULE_linkage_spec) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 202 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==13 or _la==15: + if _la==19: self.state = 200 - self.section() + self.match(ObjectFileParser.PLUS) self.state = 201 - self.entry_usage() - self.state = 207 - self._errHandler.sync(self) - _la = self._input.LA(1) + self.linkage() + - self.state = 208 - self.match(ObjectFileParser.NEWLINE) except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -1296,7 +1309,7 @@ def xtrn_record(self): return localctx - class AttributeContext(ParserRuleContext): + class LinkageContext(ParserRuleContext): __slots__ = 'parser' def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): @@ -1305,7 +1318,7 @@ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): def getRuleIndex(self): - return ObjectFileParser.RULE_attribute + return ObjectFileParser.RULE_linkage def copyFrom(self, ctx:ParserRuleContext): @@ -1313,9 +1326,9 @@ def copyFrom(self, ctx:ParserRuleContext): - class WeakContext(AttributeContext): + class WeakContext(LinkageContext): - def __init__(self, parser, ctx:ParserRuleContext): # actually a ObjectFileParser.AttributeContext + def __init__(self, parser, ctx:ParserRuleContext): # actually a ObjectFileParser.LinkageContext super().__init__(parser) self.copyFrom(ctx) @@ -1329,9 +1342,9 @@ def accept(self, visitor:ParseTreeVisitor): return visitor.visitChildren(self) - class LocalContext(AttributeContext): + class LocalContext(LinkageContext): - def __init__(self, parser, ctx:ParserRuleContext): # actually a ObjectFileParser.AttributeContext + def __init__(self, parser, ctx:ParserRuleContext): # actually a ObjectFileParser.LinkageContext super().__init__(parser) self.copyFrom(ctx) @@ -1345,25 +1358,47 @@ def accept(self, visitor:ParseTreeVisitor): return visitor.visitChildren(self) + class GlobalContext(LinkageContext): - def attribute(self): + def __init__(self, parser, ctx:ParserRuleContext): # actually a ObjectFileParser.LinkageContext + super().__init__(parser) + self.copyFrom(ctx) + + def GLOBAL(self): + return self.getToken(ObjectFileParser.GLOBAL, 0) + + def accept(self, visitor:ParseTreeVisitor): + if hasattr( visitor, "visitGlobal" ): + return visitor.visitGlobal(self) + else: + return visitor.visitChildren(self) + + + + def linkage(self): - localctx = ObjectFileParser.AttributeContext(self, self._ctx, self.state) - self.enterRule(localctx, 30, self.RULE_attribute) + localctx = ObjectFileParser.LinkageContext(self, self._ctx, self.state) + self.enterRule(localctx, 32, self.RULE_linkage) try: - self.state = 212 + self.state = 207 self._errHandler.sync(self) token = self._input.LA(1) if token in [11]: - localctx = ObjectFileParser.WeakContext(self, localctx) + localctx = ObjectFileParser.GlobalContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 210 - self.match(ObjectFileParser.WEAK) + self.state = 204 + self.match(ObjectFileParser.GLOBAL) pass elif token in [12]: - localctx = ObjectFileParser.LocalContext(self, localctx) + localctx = ObjectFileParser.WeakContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 211 + self.state = 205 + self.match(ObjectFileParser.WEAK) + pass + elif token in [13]: + localctx = ObjectFileParser.LocalContext(self, localctx) + self.enterOuterAlt(localctx, 3) + self.state = 206 self.match(ObjectFileParser.LOCAL) pass else: @@ -1403,10 +1438,10 @@ def accept(self, visitor:ParseTreeVisitor): def data(self): localctx = ObjectFileParser.DataContext(self, self._ctx, self.state) - self.enterRule(localctx, 32, self.RULE_data) + self.enterRule(localctx, 34, self.RULE_data) try: self.enterOuterAlt(localctx, 1) - self.state = 214 + self.state = 209 self.match(ObjectFileParser.BYTES) except RecognitionException as re: localctx.exception = re @@ -1442,10 +1477,10 @@ def accept(self, visitor:ParseTreeVisitor): def filepath(self): localctx = ObjectFileParser.FilepathContext(self, self._ctx, self.state) - self.enterRule(localctx, 34, self.RULE_filepath) + self.enterRule(localctx, 36, self.RULE_filepath) try: self.enterOuterAlt(localctx, 1) - self.state = 216 + self.state = 211 self.match(ObjectFileParser.FILEPATH) except RecognitionException as re: localctx.exception = re @@ -1497,33 +1532,33 @@ def accept(self, visitor:ParseTreeVisitor): def entry_usage(self): localctx = ObjectFileParser.Entry_usageContext(self, self._ctx, self.state) - self.enterRule(localctx, 36, self.RULE_entry_usage) + self.enterRule(localctx, 38, self.RULE_entry_usage) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 219 + self.state = 214 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==17: - self.state = 218 + if _la==18: + self.state = 213 self.minus() - self.state = 221 + self.state = 216 self.number() - self.state = 227 + self.state = 222 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==16: - self.state = 222 + if _la==17: + self.state = 217 self.match(ObjectFileParser.COLON) - self.state = 223 + self.state = 218 self.range_() - self.state = 225 + self.state = 220 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==18: - self.state = 224 + if _la==19: + self.state = 219 self.lower_part() @@ -1570,14 +1605,14 @@ def accept(self, visitor:ParseTreeVisitor): def range_(self): localctx = ObjectFileParser.RangeContext(self, self._ctx, self.state) - self.enterRule(localctx, 38, self.RULE_range) + self.enterRule(localctx, 40, self.RULE_range) try: self.enterOuterAlt(localctx, 1) - self.state = 229 + self.state = 224 self.number() - self.state = 230 + self.state = 225 self.match(ObjectFileParser.COLON) - self.state = 231 + self.state = 226 self.number() except RecognitionException as re: localctx.exception = re @@ -1617,12 +1652,12 @@ def accept(self, visitor:ParseTreeVisitor): def lower_part(self): localctx = ObjectFileParser.Lower_partContext(self, self._ctx, self.state) - self.enterRule(localctx, 40, self.RULE_lower_part) + self.enterRule(localctx, 42, self.RULE_lower_part) try: self.enterOuterAlt(localctx, 1) - self.state = 233 + self.state = 228 self.match(ObjectFileParser.PLUS) - self.state = 234 + self.state = 229 self.number() except RecognitionException as re: localctx.exception = re @@ -1668,18 +1703,18 @@ def accept(self, visitor:ParseTreeVisitor): def location(self): localctx = ObjectFileParser.LocationContext(self, self._ctx, self.state) - self.enterRule(localctx, 42, self.RULE_location) + self.enterRule(localctx, 44, self.RULE_location) try: self.enterOuterAlt(localctx, 1) - self.state = 236 + self.state = 231 self.number() - self.state = 237 + self.state = 232 self.match(ObjectFileParser.COLON) - self.state = 238 + self.state = 233 self.number() - self.state = 239 + self.state = 234 self.match(ObjectFileParser.COLON) - self.state = 240 + self.state = 235 self.number() except RecognitionException as re: localctx.exception = re @@ -1715,10 +1750,10 @@ def accept(self, visitor:ParseTreeVisitor): def abs_address(self): localctx = ObjectFileParser.Abs_addressContext(self, self._ctx, self.state) - self.enterRule(localctx, 44, self.RULE_abs_address) + self.enterRule(localctx, 46, self.RULE_abs_address) try: self.enterOuterAlt(localctx, 1) - self.state = 242 + self.state = 237 self.match(ObjectFileParser.WORD_ABS) except RecognitionException as re: localctx.exception = re @@ -1754,10 +1789,10 @@ def accept(self, visitor:ParseTreeVisitor): def number(self): localctx = ObjectFileParser.NumberContext(self, self._ctx, self.state) - self.enterRule(localctx, 46, self.RULE_number) + self.enterRule(localctx, 48, self.RULE_number) try: self.enterOuterAlt(localctx, 1) - self.state = 244 + self.state = 239 self.match(ObjectFileParser.WORD) except RecognitionException as re: localctx.exception = re @@ -1796,13 +1831,13 @@ def accept(self, visitor:ParseTreeVisitor): def label(self): localctx = ObjectFileParser.LabelContext(self, self._ctx, self.state) - self.enterRule(localctx, 48, self.RULE_label) + self.enterRule(localctx, 50, self.RULE_label) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 246 + self.state = 241 _la = self._input.LA(1) - if not(_la==13 or _la==14): + if not(_la==14 or _la==15): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) @@ -1844,13 +1879,13 @@ def accept(self, visitor:ParseTreeVisitor): def section(self): localctx = ObjectFileParser.SectionContext(self, self._ctx, self.state) - self.enterRule(localctx, 50, self.RULE_section) + self.enterRule(localctx, 52, self.RULE_section) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 248 + self.state = 243 _la = self._input.LA(1) - if not(_la==13 or _la==15): + if not(_la==14 or _la==16): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) @@ -1889,10 +1924,10 @@ def accept(self, visitor:ParseTreeVisitor): def minus(self): localctx = ObjectFileParser.MinusContext(self, self._ctx, self.state) - self.enterRule(localctx, 52, self.RULE_minus) + self.enterRule(localctx, 54, self.RULE_minus) try: self.enterOuterAlt(localctx, 1) - self.state = 250 + self.state = 245 self.match(ObjectFileParser.MINUS) except RecognitionException as re: localctx.exception = re diff --git a/cocas/object_file/generated/ObjectFileParserVisitor.py b/cocas/object_file/generated/ObjectFileParserVisitor.py index 5d97f60f..5ec15bed 100644 --- a/cocas/object_file/generated/ObjectFileParserVisitor.py +++ b/cocas/object_file/generated/ObjectFileParserVisitor.py @@ -84,6 +84,16 @@ def visitXtrn_record(self, ctx:ObjectFileParser.Xtrn_recordContext): return self.visitChildren(ctx) + # Visit a parse tree produced by ObjectFileParser#linkage_spec. + def visitLinkage_spec(self, ctx:ObjectFileParser.Linkage_specContext): + return self.visitChildren(ctx) + + + # Visit a parse tree produced by ObjectFileParser#Global. + def visitGlobal(self, ctx:ObjectFileParser.GlobalContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ObjectFileParser#Weak. def visitWeak(self, ctx:ObjectFileParser.WeakContext): return self.visitChildren(ctx) diff --git a/cocas/object_file/grammar/ObjectFileLexer.g4 b/cocas/object_file/grammar/ObjectFileLexer.g4 index 76c096f4..c8e43919 100644 --- a/cocas/object_file/grammar/ObjectFileLexer.g4 +++ b/cocas/object_file/grammar/ObjectFileLexer.g4 @@ -11,6 +11,7 @@ DATA: 'DATA' -> pushMode(IN_BYTES); REL : 'REL'; XTRN: 'XTRN'; +GLOBAL: 'GLOBAL'; WEAK: 'WEAK'; LOCAL: 'LOCAL'; diff --git a/cocas/object_file/grammar/ObjectFileParser.g4 b/cocas/object_file/grammar/ObjectFileParser.g4 index dd5041b5..f3b5323b 100644 --- a/cocas/object_file/grammar/ObjectFileParser.g4 +++ b/cocas/object_file/grammar/ObjectFileParser.g4 @@ -40,17 +40,20 @@ targ_record: TARG label NEWLINE; source_record: FILE SPACES_FILE filepath NEWLINE; abs_record: ABS abs_address COLON_ABS data? NEWLINE_BYTES+; loc_record: LOC location* NEWLINE; -ntry_record: NTRY label (PLUS attribute)* number NEWLINE; +ntry_record: NTRY label linkage_spec number NEWLINE; name_record: NAME section NEWLINE; alig_record: ALIG number NEWLINE; data_record: DATA data? NEWLINE_BYTES+; rel_record: REL entry_usage* NEWLINE; -xtrn_record: XTRN label (PLUS attribute)* COLON (section entry_usage)* NEWLINE; +xtrn_record: XTRN label linkage_spec COLON (section entry_usage)* NEWLINE; -attribute - : WEAK # Weak +linkage_spec: (PLUS linkage)?; +linkage + : GLOBAL # Global + | WEAK # Weak | LOCAL # Local ; + data: BYTES; filepath: FILEPATH; entry_usage: minus? number (COLON range lower_part?)?; diff --git a/cocas/object_file/object_export.py b/cocas/object_file/object_export.py index 68940b73..53d6d9b8 100644 --- a/cocas/object_file/object_export.py +++ b/cocas/object_file/object_export.py @@ -2,16 +2,16 @@ from pathlib import Path from typing import Union -from cocas.object_module import CodeLocation, ExternalEntry, ObjectModule, ObjectSectionRecord +from cocas.object_module import CodeLocation, ExternalEntry, ObjectModule, ObjectSectionRecord, EntryKey from .targets import TargetParams, import_target -def data_to_str(array: bytearray): +def data_to_str(array: bytearray) -> str: return ' '.join(map(lambda x: f'{x:02x}', array)) -def sect_entry_to_str(pair: tuple[str, ExternalEntry]): +def sect_entry_to_str(pair: tuple[str, ExternalEntry]) -> str: name, entry = pair return f'{name} {entry}' @@ -70,8 +70,8 @@ def export_object(objs: list[ObjectModule], target: str, debug: bool) -> list[st if debug: result += export_code_locations(asect.code_locations) for asect in obj.asects: - for label, entry in asect.entries.items(): - result.append(f'NTRY {label} {entry}\n') + for key, entry in asect.entries.items(): + result.append(f'NTRY {key} {entry}\n') for rsect in obj.rsects: result.append(f'NAME {rsect.name}\n') if rsect.alignment != target_params.default_alignment: @@ -81,15 +81,16 @@ def export_object(objs: list[ObjectModule], target: str, debug: bool) -> list[st if debug: result += export_code_locations(rsect.code_locations) result.append(f'REL {" ".join(map(str, rsect.relocatable))}\n') - for label, entry in rsect.entries.items(): - result.append(f'NTRY {label} {entry}\n') - external = defaultdict(list) + for key, entry in rsect.entries.items(): + result.append(f'NTRY {key} {entry}\n') + + object_exts: dict[EntryKey, list[tuple[str, ExternalEntry]]] = defaultdict(list) for sect in (obj.asects if asects_exist else []) + obj.rsects: - for label, entries in sect.external.items(): - for entry in entries: - external[label].append((sect.name, entry)) - for label, entries in external.items(): - result.append(f'XTRN {label}: {" ".join(map(sect_entry_to_str, entries))}\n') + for key, sect_exts in sect.external.items(): + for ext in sect_exts: + object_exts[key].append((sect.name, ext)) + for key, sect_ext_pairs in object_exts.items(): + result.append(f'XTRN {key}: {" ".join(map(sect_entry_to_str, sect_ext_pairs))}\n') pass return result diff --git a/cocas/object_file/object_import.py b/cocas/object_file/object_import.py index 8552bb61..87100a9c 100644 --- a/cocas/object_file/object_import.py +++ b/cocas/object_file/object_import.py @@ -6,8 +6,7 @@ import antlr4 from antlr4 import CommonTokenStream, InputStream -from cocas.object_module import CodeLocation, ExternalEntry, ObjectModule, ObjectSectionRecord, Linkage, SymbolAttribute, Entry -from cocas.object_module.external_label_key import ExternalLabelKey +from cocas.object_module import CodeLocation, ExternalEntry, ObjectModule, ObjectSectionRecord, Linkage, Entry, EntryKey from .exceptions import AntlrErrorListener, ObjectFileException from .generated import ObjectFileLexer, ObjectFileParser, ObjectFileParserVisitor @@ -61,7 +60,7 @@ def visitObject_block(self, ctx: ObjectFileParser.Object_blockContext) -> Object xtrn: ObjectFileParser.Xtrn_recordContext for xtrn in ctx.xtrn_record(): - label, entries, attributes = self.visitXtrn_record(xtrn) + key, entries = self.visitXtrn_record(xtrn) for sect, entry in entries: if sect == '$abs': if not asects: @@ -69,9 +68,9 @@ def visitObject_block(self, ctx: ObjectFileParser.Object_blockContext) -> Object 'No absolute sections found, but needed for xtrn entry') # what is this? ind = max(bisect.bisect_right(asect_addr, entry.offset) - 1, 0) - asects[asect_addr[ind]].external[ExternalLabelKey(label, attributes=attributes)].append(entry) + asects[asect_addr[ind]].external[key].append(entry) elif sect in rsects: - rsects[sect].external[ExternalLabelKey(label, attributes=attributes)].append(entry) + rsects[sect].external[key].append(entry) else: raise ObjectFileException(self.file, xtrn.start.line, f'Section not found: {sect}') if filename: @@ -93,9 +92,9 @@ def visitAsect_block(self, ctx: ObjectFileParser.Asect_blockContext): if not asects and ctx.ntry_record(): asects[0] = ObjectSectionRecord('$abs', 0, bytearray(), {}, [], {}, 1) asect_addr = sorted(asects.keys()) - for label, addr, attributes in map(self.visitNtry_record, ctx.ntry_record()): + for key, entry in map(self.visitNtry_record, ctx.ntry_record()): ind = max(bisect.bisect_right(asect_addr, addr) - 1, 0) - asects[asect_addr[ind]].entries[label] = Entry(addr, attributes) + asects[asect_addr[ind]].entries[key] = entry return asects, asect_addr def visitAbs_block(self, ctx: ObjectFileParser.Abs_blockContext): @@ -117,8 +116,8 @@ def visitRsect_block(self, ctx: ObjectFileParser.Rsect_blockContext): else: rel = [] entries = {} - for label, address, attributes in map(self.visitNtry_record, ctx.ntry_record()): - entries[label] = Entry(address, attributes) + for key, entry in map(self.visitNtry_record, ctx.ntry_record()): + entries[key] = entry code_locations = {} for cl in map(self.visitLoc_record, ctx.loc_record()): code_locations |= cl @@ -141,25 +140,23 @@ def visitLoc_record(self, ctx: ObjectFileParser.Loc_recordContext): res[byte] = CodeLocation(None, line, col) return res + def visitGlobal(self, ctx: ObjectFileParser.GlobalContext): + return Linkage.GLOBAL + def visitWeak(self, ctx: ObjectFileParser.WeakContext): - return SymbolAttribute.WEAK + return Linkage.WEAK_GLOBAL def visitLocal(self, ctx: ObjectFileParser.LocalContext): - return SymbolAttribute.LOCAL - - def visitAttributes(self, attributes: list[ObjectFileParser.AttributeContext]): - parsed = list(map(self.visit, attributes)) + return Linkage.FILE_LOCAL - if SymbolAttribute.WEAK in parsed and SymbolAttribute.LOCAL in parsed: - raise ObjectFileException(self.file, attributes[0].start.line, 'Symbol cannot have WEAK and LOCAL attributes at the same time') - - return parsed + def visitLinkage_spec(self, ctx: ObjectFileParser.Linkage_specContext): + return self.visit(ctx.linkage()) if ctx.linkage() else Linkage.GLOBAL - def visitNtry_record(self, ctx: ObjectFileParser.Ntry_recordContext): + def visitNtry_record(self, ctx: ObjectFileParser.Ntry_recordContext) -> tuple[EntryKey, Entry]: label = self.visitLabel(ctx.label()) address = self.visitNumber(ctx.number()) - attributes = self.visitAttributes(ctx.attribute()) - return label, address, attributes + linkage = self.visitLinkage_spec(ctx.linkage_spec()) + return EntryKey(label, linkage), Entry(address) def visitName_record(self, ctx: ObjectFileParser.Name_recordContext): return self.visitSection(ctx.section()) @@ -176,12 +173,12 @@ def visitFilepath(self, ctx: ObjectFileParser.FilepathContext): def visitRel_record(self, ctx: ObjectFileParser.Rel_recordContext): return [self.visitEntry_usage(eu) for eu in ctx.entry_usage()] - def visitXtrn_record(self, ctx: ObjectFileParser.Xtrn_recordContext): + def visitXtrn_record(self, ctx: ObjectFileParser.Xtrn_recordContext) -> tuple[str, Linkage, list[tuple[str, ExternalEntry]]]: label = self.visitLabel(ctx.label()) + linkage = self.visitLinkage_spec(ctx.linkage_spec()) entries = [(self.visitSection(n), self.visitEntry_usage(e)) for (n, e) in zip(ctx.section(), ctx.entry_usage())] - attributes = self.visitAttributes(ctx.attribute()) - return label, entries, attributes + return EntryKey(label, linkage), entries def parse_byte(self, byte: str, ctx: ObjectFileParser.DataContext): try: diff --git a/cocas/object_module/__init__.py b/cocas/object_module/__init__.py index ca8dc542..4d2ed98b 100644 --- a/cocas/object_module/__init__.py +++ b/cocas/object_module/__init__.py @@ -4,7 +4,4 @@ from .external_entry import ExternalEntry from .location import CodeLocation from .object_module import ObjectModule, ObjectSectionRecord -from .linkage import Linkage -from .external_label_key import ExternalLabelKey -from .entry import Entry -from .symbol_attribute import SymbolAttribute +from .entry import Entry, EntryKey, Linkage diff --git a/cocas/object_module/concat_rsects.py b/cocas/object_module/concat_rsects.py index 48811373..9b788d1c 100644 --- a/cocas/object_module/concat_rsects.py +++ b/cocas/object_module/concat_rsects.py @@ -34,7 +34,7 @@ def concat_rsects(rsects: Iterable["ObjectSectionRecord"]) -> list["ObjectSectio prev_size = (prev_size + rsect.alignment - 1) // rsect.alignment * rsect.alignment new.data.extend(bytearray(prev_size - len(new.data))) new.data += rsect.data - new.entries.update({name: Entry(entry.address + prev_size, entry.attrs) for name, entry in rsect.entries.items()}) + new.entries.update({key: Entry(entry.address + prev_size) for key, entry in rsect.entries.items()}) for pos, loc in rsect.code_locations.items(): new.code_locations[pos + prev_size] = loc for label, exts in rsect.external.items(): diff --git a/cocas/object_module/entry.py b/cocas/object_module/entry.py index cbad89f2..701716d4 100644 --- a/cocas/object_module/entry.py +++ b/cocas/object_module/entry.py @@ -1,30 +1,47 @@ -from dataclasses import dataclass, field -from typing import Optional +from dataclasses import dataclass +from enum import IntEnum -from .symbol_attribute import SymbolAttribute -from .linkage import Linkage -@dataclass +@dataclass(frozen=True) class Entry: + "A symbol entry in a section of an object module." address: int - attrs: list[SymbolAttribute] = field(default_factory=list) - - def add_linkage_attribute(self, linkage: Optional[Linkage]): - if linkage: - attr: Optional[SymbolAttribute] = linkage.to_attribute() - if attr: - self.attrs.append(attr) + "The offset from the start of the section this entry is defined at." def __str__(self): - string = "" - if len(self.attrs) > 0: - # ATTR1 +ATTR2 ... +ATTRn - string = " +".join(map(str, self.attrs)) - # +ATTR1 +ATTR2 ... +ATTRn address - return f"+{string} {self.address:02x}" - return f"{self.address:02x}" - - def __repr__(self): - return str(self) + +@dataclass(frozen=True) +class EntryKey: + "A key for identifying entries in sections." + name: str + "The name of this entry." + linkage: Linkage + "The linkage type of this entry." + + def __str__(self): + match self.linkage: + case Linkage.FILE_LOCAL: + return f"{self.name} +LOCAL" + case Linkage.WEAK_GLOBAL: + return f"{self.name} +WEAK" + case Linkage.GLOBAL: + return f"{self.name} +GLOBAL" + case _: + return self.name + + +class Linkage(IntEnum): + "Describes the way an entry or external is linked." + FILE_LOCAL = 1 + "The entry is visible in the current object module only." + GLOBAL = 2 + "The entry is visible in all object modules." + WEAK_GLOBAL = 3 + """ + The entry is visible in all object modules. + When applied to an entry, it makes it possible to override with a GLOBAL entry. + When applied to an external, it becomes optional (e.g. doesn't throw an error + when there is no matching entry, leaving the value as is. + """ diff --git a/cocas/object_module/external_label_key.py b/cocas/object_module/external_label_key.py deleted file mode 100644 index 8ee565c0..00000000 --- a/cocas/object_module/external_label_key.py +++ /dev/null @@ -1,50 +0,0 @@ -from cocas.object_module.linkage import Linkage -from cocas.object_module.symbol_attribute import SymbolAttribute -from typing import Optional - -class ExternalLabelKey: - """Describes the key for adding ExternalEntry objects to a dictionary. - Contains the label name, attributes, sorted in non-descending order, anb - their string representation.""" - - label: str - attributes: set[SymbolAttribute] - key: str - - def __init__(self, label: str, - linkage_attr: Optional[Linkage] = None, - attributes: Optional[list[SymbolAttribute]] = None): - self.label = label - self.attributes = set() - self.key = label - - if linkage_attr: - attr: Optional[SymbolAttribute] = linkage_attr.to_attribute() - if attr: - self.attributes.add(attr) - - if attributes: - self.attributes.update(attributes) - - if len(self.attributes) > 0: - # ATTR1 +ATTR2 ... +ATTRn - string = " +".join(map(str, sorted(self.attributes))) - # label +ATTR1 +ATTR2 ... +ATTRn - self.key += f" +{string}" - - def __hash__(self): - return hash(self.key) - - def __eq__(self, other): - if not isinstance(other, type(self)): - return False - return self.key == self.key - - def __str__(self): - return self.key - - def __repr__(self): - return str(self) - - def is_file_local(self): - return SymbolAttribute.LOCAL in self.attributes diff --git a/cocas/object_module/linkage.py b/cocas/object_module/linkage.py deleted file mode 100644 index 7f52eff1..00000000 --- a/cocas/object_module/linkage.py +++ /dev/null @@ -1,17 +0,0 @@ -from enum import Enum -from typing import Optional -from .symbol_attribute import SymbolAttribute - -class Linkage(Enum): - FILE_LOCAL = 1 - GLOBAL = 2 - WEAK_GLOBAL = 3 - - def to_attribute(self) -> Optional[SymbolAttribute]: - match self: - case Linkage.FILE_LOCAL: - return SymbolAttribute.LOCAL - case Linkage.WEAK_GLOBAL: - return SymbolAttribute.WEAK - case _: - return None diff --git a/cocas/object_module/object_module.py b/cocas/object_module/object_module.py index 3e633c2a..9d310fe6 100644 --- a/cocas/object_module/object_module.py +++ b/cocas/object_module/object_module.py @@ -5,8 +5,7 @@ from .external_entry import ExternalEntry from .location import CodeLocation -from .entry import Entry -from .external_label_key import ExternalLabelKey +from .entry import Entry, EntryKey @dataclass @@ -18,7 +17,7 @@ class ObjectSectionRecord: """Address of the section. 0 for every relocatable section""" data: bytearray """Compiled binary image of that section before linking""" - entries: dict[str, Entry] + entries: dict[EntryKey, Entry] """Exported labels of this section and their Entries (address, attributes e.t.c.)""" relocatable: list[ExternalEntry] """Places where the address of this relocatable section should be added""" @@ -26,7 +25,7 @@ class ObjectSectionRecord: """Mapping between addresses in binary image and locations in the source file""" alignment: int = field(default=1) """If the relocatable section should get address that is a multiple of some number""" - external: defaultdict[ExternalLabelKey, list[ExternalEntry]] = field(default_factory=lambda: defaultdict(list)) + external: defaultdict[EntryKey, list[ExternalEntry]] = field(default_factory=lambda: defaultdict(list)) """List of places in section where some external label is used""" diff --git a/cocas/object_module/symbol_attribute.py b/cocas/object_module/symbol_attribute.py deleted file mode 100644 index 19556b89..00000000 --- a/cocas/object_module/symbol_attribute.py +++ /dev/null @@ -1,14 +0,0 @@ -from enum import IntEnum - -class SymbolAttribute(IntEnum): - LOCAL = 1 - WEAK = 2 - - def __str__(self): - match self: - case SymbolAttribute.LOCAL: - return "LOCAL" - case SymbolAttribute.WEAK: - return "WEAK" - case _: - raise ValueError("Unknown symbol attribute") From d045b8ff5b90a96b35e52a542d0c9f7df7577324 Mon Sep 17 00:00:00 2001 From: Andrey Eliseev Date: Sun, 8 Mar 2026 21:17:06 +0700 Subject: [PATCH 31/42] [cocas] Fix refs to weak labels in local section This commit changes the way references to weak labels defined in the cuurent section behave. These can now be overriden, by a normal GLOBAL symbol, instead of always being bound to the local definition. This is how weak symbols work in GAS. Example: rsect text foo> jsr bar rts bar~> ldi r0, 123 rts rsect text2 bar> ldi r0, 456 rts end Prior to this commit `foo` would have called `bar` from `text` (r0: 123) After this commit `foo` would call `bar` from `text2` (r0: 456) --- cocas/assembler/code_block.py | 4 ++++ cocas/assembler/targets/cdm8e/code_segments.py | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/cocas/assembler/code_block.py b/cocas/assembler/code_block.py index 7601f5d2..4fe2712a 100644 --- a/cocas/assembler/code_block.py +++ b/cocas/assembler/code_block.py @@ -77,6 +77,10 @@ def assemble_label_declaration(self, line: LabelDeclarationNode, __): if line.external: self.exts[label_name] = line.linkage + elif line.linkage == Linkage.WEAK_GLOBAL: + self.append_label(label_name) + self.ents[label_name] = Linkage.WEAK_GLOBAL + self.exts[label_name] = Linkage.GLOBAL else: self.append_label(label_name) if line.linkage: diff --git a/cocas/assembler/targets/cdm8e/code_segments.py b/cocas/assembler/targets/cdm8e/code_segments.py index 6fcaffea..b6f50385 100644 --- a/cocas/assembler/targets/cdm8e/code_segments.py +++ b/cocas/assembler/targets/cdm8e/code_segments.py @@ -212,15 +212,15 @@ def eval_rel_expr_seg(seg: RelocatableExpressionSegment, s: "Section", local_dim = 0 for term, m in [(t, 1) for t in seg.expr.add_terms] + [(t, -1) for t in seg.expr.sub_terms]: if isinstance(term, LabelNode): - if term.name in labels: + if term.name in s.exts: + used_exts.setdefault(term.name, 0) + used_exts[term.name] += m + elif term.name in labels: local_dim += m val_long += labels[term.name] * m elif term.name in s.labels: s_dim += m val_long += s.labels[term.name] * m - elif term.name in s.exts: - used_exts.setdefault(term.name, 0) - used_exts[term.name] += m else: _error(seg, f'Label "{term.name}" not found') elif isinstance(term, TemplateFieldNode): From b72c0dd31e4a0527e5e716b3ce296f3a2ad77077 Mon Sep 17 00:00:00 2001 From: Andrey Eliseev Date: Sun, 8 Mar 2026 21:49:47 +0700 Subject: [PATCH 32/42] [cocas] Change weak label and weak ext syntax `weak` keyword was replaced with `ext?` to reflect the fact that it matches the same symbols as the regular `ext`, but is optional. `~>` was replaced with `?>` to reflect the fact that the definition is optional and may be overridden. --- cocas/assembler/generated/AsmLexer.py | 279 +++++----- cocas/assembler/generated/AsmParser.py | 645 ++++++++++++----------- cocas/assembler/generated/MacroLexer.py | 36 +- cocas/assembler/generated/MacroParser.py | 212 ++++---- cocas/assembler/grammar/AsmLexer.g4 | 4 +- cocas/assembler/grammar/AsmParser.g4 | 9 +- cocas/assembler/grammar/Macro.g4 | 8 +- 7 files changed, 604 insertions(+), 589 deletions(-) diff --git a/cocas/assembler/generated/AsmLexer.py b/cocas/assembler/generated/AsmLexer.py index f97cd462..36dbc5d0 100644 --- a/cocas/assembler/generated/AsmLexer.py +++ b/cocas/assembler/generated/AsmLexer.py @@ -10,7 +10,7 @@ def serializedATN(): return [ - 4,0,44,323,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5, + 4,0,44,320,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5, 2,6,7,6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2, 13,7,13,2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7, 19,2,20,7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,2, @@ -19,114 +19,113 @@ def serializedATN(): 39,7,39,2,40,7,40,2,41,7,41,2,42,7,42,2,43,7,43,1,0,1,0,1,0,1,0, 1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2, 1,2,1,3,1,3,1,3,1,4,1,4,1,4,1,4,1,4,1,5,1,5,1,5,1,5,1,6,1,6,1,6, - 1,6,1,7,1,7,1,7,1,7,1,7,1,8,1,8,1,8,1,8,1,8,1,9,1,9,1,9,1,10,1,10, - 1,10,1,11,1,11,1,11,1,12,1,12,1,12,1,12,1,12,1,12,1,13,1,13,1,13, - 1,13,1,13,1,13,1,14,1,14,1,14,1,14,1,14,1,14,1,15,1,15,1,15,1,15, - 1,15,1,16,1,16,1,16,1,16,1,16,1,16,1,16,1,17,1,17,1,17,1,17,1,17, - 1,17,1,18,1,18,1,18,1,18,1,18,1,19,1,19,1,19,1,19,1,19,1,19,1,20, - 1,20,1,21,1,21,1,22,1,22,1,23,1,23,1,24,1,24,1,25,1,25,1,26,1,26, - 1,26,1,27,1,27,1,27,1,28,1,28,1,29,1,29,1,30,1,30,1,30,1,31,1,31, - 1,31,1,32,1,32,5,32,223,8,32,10,32,12,32,226,9,32,1,33,1,33,5,33, - 230,8,33,10,33,12,33,233,9,33,1,33,1,33,5,33,237,8,33,10,33,12,33, - 240,9,33,1,33,1,33,1,34,4,34,245,8,34,11,34,12,34,246,1,35,1,35, - 1,35,1,35,4,35,253,8,35,11,35,12,35,254,1,36,1,36,1,36,1,36,4,36, - 261,8,36,11,36,12,36,262,1,37,1,37,4,37,267,8,37,11,37,12,37,268, - 1,37,1,37,5,37,273,8,37,10,37,12,37,276,9,37,1,37,1,37,1,38,1,38, - 4,38,282,8,38,11,38,12,38,283,1,38,1,38,5,38,288,8,38,10,38,12,38, - 291,9,38,1,38,1,38,1,39,3,39,296,8,39,1,39,1,39,1,40,1,40,5,40,302, - 8,40,10,40,12,40,305,9,40,1,40,1,40,1,41,1,41,1,41,1,41,1,42,1,42, - 1,42,1,42,1,42,4,42,318,8,42,11,42,12,42,319,1,43,1,43,0,0,44,1, - 1,3,2,5,3,7,4,9,5,11,6,13,7,15,8,17,9,19,10,21,11,23,12,25,13,27, - 14,29,15,31,16,33,17,35,18,37,19,39,20,41,21,43,22,45,23,47,24,49, - 25,51,26,53,27,55,28,57,29,59,30,61,31,63,32,65,33,67,34,69,35,71, - 36,73,37,75,38,77,39,79,40,81,41,83,42,85,43,87,44,1,0,12,3,0,65, - 90,95,95,97,122,4,0,48,57,65,90,95,95,97,122,5,0,46,46,48,57,65, - 90,95,95,97,122,1,0,48,57,1,0,48,49,3,0,48,57,65,70,97,102,2,0,34, - 34,92,92,2,0,39,39,92,92,1,0,10,10,2,0,9,9,32,32,5,0,43,43,47,57, - 61,61,65,90,97,122,1,0,0,65534,337,0,1,1,0,0,0,0,3,1,0,0,0,0,5,1, - 0,0,0,0,7,1,0,0,0,0,9,1,0,0,0,0,11,1,0,0,0,0,13,1,0,0,0,0,15,1,0, - 0,0,0,17,1,0,0,0,0,19,1,0,0,0,0,21,1,0,0,0,0,23,1,0,0,0,0,25,1,0, - 0,0,0,27,1,0,0,0,0,29,1,0,0,0,0,31,1,0,0,0,0,33,1,0,0,0,0,35,1,0, - 0,0,0,37,1,0,0,0,0,39,1,0,0,0,0,41,1,0,0,0,0,43,1,0,0,0,0,45,1,0, - 0,0,0,47,1,0,0,0,0,49,1,0,0,0,0,51,1,0,0,0,0,53,1,0,0,0,0,55,1,0, - 0,0,0,57,1,0,0,0,0,59,1,0,0,0,0,61,1,0,0,0,0,63,1,0,0,0,0,65,1,0, - 0,0,0,67,1,0,0,0,0,69,1,0,0,0,0,71,1,0,0,0,0,73,1,0,0,0,0,75,1,0, - 0,0,0,77,1,0,0,0,0,79,1,0,0,0,0,81,1,0,0,0,0,83,1,0,0,0,0,85,1,0, - 0,0,0,87,1,0,0,0,1,89,1,0,0,0,3,95,1,0,0,0,5,101,1,0,0,0,7,110,1, - 0,0,0,9,113,1,0,0,0,11,118,1,0,0,0,13,122,1,0,0,0,15,126,1,0,0,0, - 17,131,1,0,0,0,19,136,1,0,0,0,21,139,1,0,0,0,23,142,1,0,0,0,25,145, - 1,0,0,0,27,151,1,0,0,0,29,157,1,0,0,0,31,163,1,0,0,0,33,168,1,0, - 0,0,35,175,1,0,0,0,37,181,1,0,0,0,39,186,1,0,0,0,41,192,1,0,0,0, - 43,194,1,0,0,0,45,196,1,0,0,0,47,198,1,0,0,0,49,200,1,0,0,0,51,202, - 1,0,0,0,53,204,1,0,0,0,55,207,1,0,0,0,57,210,1,0,0,0,59,212,1,0, - 0,0,61,214,1,0,0,0,63,217,1,0,0,0,65,220,1,0,0,0,67,227,1,0,0,0, - 69,244,1,0,0,0,71,248,1,0,0,0,73,256,1,0,0,0,75,264,1,0,0,0,77,279, - 1,0,0,0,79,295,1,0,0,0,81,299,1,0,0,0,83,308,1,0,0,0,85,312,1,0, - 0,0,87,321,1,0,0,0,89,90,5,97,0,0,90,91,5,115,0,0,91,92,5,101,0, - 0,92,93,5,99,0,0,93,94,5,116,0,0,94,2,1,0,0,0,95,96,5,98,0,0,96, - 97,5,114,0,0,97,98,5,101,0,0,98,99,5,97,0,0,99,100,5,107,0,0,100, - 4,1,0,0,0,101,102,5,99,0,0,102,103,5,111,0,0,103,104,5,110,0,0,104, - 105,5,116,0,0,105,106,5,105,0,0,106,107,5,110,0,0,107,108,5,117, - 0,0,108,109,5,101,0,0,109,6,1,0,0,0,110,111,5,100,0,0,111,112,5, - 111,0,0,112,8,1,0,0,0,113,114,5,101,0,0,114,115,5,108,0,0,115,116, - 5,115,0,0,116,117,5,101,0,0,117,10,1,0,0,0,118,119,5,101,0,0,119, - 120,5,110,0,0,120,121,5,100,0,0,121,12,1,0,0,0,122,123,5,101,0,0, - 123,124,5,120,0,0,124,125,5,116,0,0,125,14,1,0,0,0,126,127,5,102, - 0,0,127,128,5,105,0,0,128,129,5,108,0,0,129,130,5,101,0,0,130,16, - 1,0,0,0,131,132,5,119,0,0,132,133,5,101,0,0,133,134,5,97,0,0,134, - 135,5,107,0,0,135,18,1,0,0,0,136,137,5,102,0,0,137,138,5,105,0,0, - 138,20,1,0,0,0,139,140,5,105,0,0,140,141,5,102,0,0,141,22,1,0,0, - 0,142,143,5,105,0,0,143,144,5,115,0,0,144,24,1,0,0,0,145,146,5,109, - 0,0,146,147,5,97,0,0,147,148,5,99,0,0,148,149,5,114,0,0,149,150, - 5,111,0,0,150,26,1,0,0,0,151,152,5,114,0,0,152,153,5,115,0,0,153, - 154,5,101,0,0,154,155,5,99,0,0,155,156,5,116,0,0,156,28,1,0,0,0, - 157,158,5,115,0,0,158,159,5,116,0,0,159,160,5,97,0,0,160,161,5,121, - 0,0,161,162,5,115,0,0,162,30,1,0,0,0,163,164,5,116,0,0,164,165,5, - 104,0,0,165,166,5,101,0,0,166,167,5,110,0,0,167,32,1,0,0,0,168,169, - 5,116,0,0,169,170,5,112,0,0,170,171,5,108,0,0,171,172,5,97,0,0,172, - 173,5,116,0,0,173,174,5,101,0,0,174,34,1,0,0,0,175,176,5,117,0,0, - 176,177,5,110,0,0,177,178,5,116,0,0,178,179,5,105,0,0,179,180,5, - 108,0,0,180,36,1,0,0,0,181,182,5,119,0,0,182,183,5,101,0,0,183,184, - 5,110,0,0,184,185,5,100,0,0,185,38,1,0,0,0,186,187,5,119,0,0,187, - 188,5,104,0,0,188,189,5,105,0,0,189,190,5,108,0,0,190,191,5,101, - 0,0,191,40,1,0,0,0,192,193,5,46,0,0,193,42,1,0,0,0,194,195,5,44, - 0,0,195,44,1,0,0,0,196,197,5,43,0,0,197,46,1,0,0,0,198,199,5,45, - 0,0,199,48,1,0,0,0,200,201,5,58,0,0,201,50,1,0,0,0,202,203,5,62, - 0,0,203,52,1,0,0,0,204,205,5,58,0,0,205,206,5,62,0,0,206,54,1,0, - 0,0,207,208,5,126,0,0,208,209,5,62,0,0,209,56,1,0,0,0,210,211,5, - 40,0,0,211,58,1,0,0,0,212,213,5,41,0,0,213,60,1,0,0,0,214,215,5, - 45,0,0,215,216,5,124,0,0,216,62,1,0,0,0,217,218,5,114,0,0,218,219, - 3,69,34,0,219,64,1,0,0,0,220,224,7,0,0,0,221,223,7,1,0,0,222,221, - 1,0,0,0,223,226,1,0,0,0,224,222,1,0,0,0,224,225,1,0,0,0,225,66,1, - 0,0,0,226,224,1,0,0,0,227,231,7,0,0,0,228,230,7,1,0,0,229,228,1, - 0,0,0,230,233,1,0,0,0,231,229,1,0,0,0,231,232,1,0,0,0,232,234,1, - 0,0,0,233,231,1,0,0,0,234,238,3,41,20,0,235,237,7,2,0,0,236,235, - 1,0,0,0,237,240,1,0,0,0,238,236,1,0,0,0,238,239,1,0,0,0,239,241, - 1,0,0,0,240,238,1,0,0,0,241,242,7,1,0,0,242,68,1,0,0,0,243,245,7, - 3,0,0,244,243,1,0,0,0,245,246,1,0,0,0,246,244,1,0,0,0,246,247,1, - 0,0,0,247,70,1,0,0,0,248,249,5,48,0,0,249,250,5,98,0,0,250,252,1, - 0,0,0,251,253,7,4,0,0,252,251,1,0,0,0,253,254,1,0,0,0,254,252,1, - 0,0,0,254,255,1,0,0,0,255,72,1,0,0,0,256,257,5,48,0,0,257,258,5, - 120,0,0,258,260,1,0,0,0,259,261,7,5,0,0,260,259,1,0,0,0,261,262, - 1,0,0,0,262,260,1,0,0,0,262,263,1,0,0,0,263,74,1,0,0,0,264,274,5, - 34,0,0,265,267,8,6,0,0,266,265,1,0,0,0,267,268,1,0,0,0,268,266,1, - 0,0,0,268,269,1,0,0,0,269,273,1,0,0,0,270,271,5,92,0,0,271,273,9, - 0,0,0,272,266,1,0,0,0,272,270,1,0,0,0,273,276,1,0,0,0,274,272,1, - 0,0,0,274,275,1,0,0,0,275,277,1,0,0,0,276,274,1,0,0,0,277,278,5, - 34,0,0,278,76,1,0,0,0,279,289,5,39,0,0,280,282,8,7,0,0,281,280,1, - 0,0,0,282,283,1,0,0,0,283,281,1,0,0,0,283,284,1,0,0,0,284,288,1, - 0,0,0,285,286,5,92,0,0,286,288,9,0,0,0,287,281,1,0,0,0,287,285,1, - 0,0,0,288,291,1,0,0,0,289,287,1,0,0,0,289,290,1,0,0,0,290,292,1, - 0,0,0,291,289,1,0,0,0,292,293,5,39,0,0,293,78,1,0,0,0,294,296,5, - 13,0,0,295,294,1,0,0,0,295,296,1,0,0,0,296,297,1,0,0,0,297,298,5, - 10,0,0,298,80,1,0,0,0,299,303,5,35,0,0,300,302,8,8,0,0,301,300,1, - 0,0,0,302,305,1,0,0,0,303,301,1,0,0,0,303,304,1,0,0,0,304,306,1, - 0,0,0,305,303,1,0,0,0,306,307,6,40,0,0,307,82,1,0,0,0,308,309,7, - 9,0,0,309,310,1,0,0,0,310,311,6,41,0,0,311,84,1,0,0,0,312,313,5, - 102,0,0,313,314,5,112,0,0,314,315,5,45,0,0,315,317,1,0,0,0,316,318, - 7,10,0,0,317,316,1,0,0,0,318,319,1,0,0,0,319,317,1,0,0,0,319,320, - 1,0,0,0,320,86,1,0,0,0,321,322,7,11,0,0,322,88,1,0,0,0,16,0,224, - 231,238,246,254,262,268,272,274,283,287,289,295,303,319,1,6,0,0 + 1,6,1,7,1,7,1,7,1,7,1,7,1,8,1,8,1,8,1,9,1,9,1,9,1,10,1,10,1,10,1, + 11,1,11,1,11,1,11,1,11,1,11,1,12,1,12,1,12,1,12,1,12,1,12,1,13,1, + 13,1,13,1,13,1,13,1,13,1,14,1,14,1,14,1,14,1,14,1,15,1,15,1,15,1, + 15,1,15,1,15,1,15,1,16,1,16,1,16,1,16,1,16,1,16,1,17,1,17,1,17,1, + 17,1,17,1,18,1,18,1,18,1,18,1,18,1,18,1,19,1,19,1,20,1,20,1,21,1, + 21,1,22,1,22,1,23,1,23,1,24,1,24,1,25,1,25,1,25,1,26,1,26,1,26,1, + 27,1,27,1,28,1,28,1,29,1,29,1,30,1,30,1,30,1,31,1,31,1,31,1,32,1, + 32,5,32,220,8,32,10,32,12,32,223,9,32,1,33,1,33,5,33,227,8,33,10, + 33,12,33,230,9,33,1,33,1,33,5,33,234,8,33,10,33,12,33,237,9,33,1, + 33,1,33,1,34,4,34,242,8,34,11,34,12,34,243,1,35,1,35,1,35,1,35,4, + 35,250,8,35,11,35,12,35,251,1,36,1,36,1,36,1,36,4,36,258,8,36,11, + 36,12,36,259,1,37,1,37,4,37,264,8,37,11,37,12,37,265,1,37,1,37,5, + 37,270,8,37,10,37,12,37,273,9,37,1,37,1,37,1,38,1,38,4,38,279,8, + 38,11,38,12,38,280,1,38,1,38,5,38,285,8,38,10,38,12,38,288,9,38, + 1,38,1,38,1,39,3,39,293,8,39,1,39,1,39,1,40,1,40,5,40,299,8,40,10, + 40,12,40,302,9,40,1,40,1,40,1,41,1,41,1,41,1,41,1,42,1,42,1,42,1, + 42,1,42,4,42,315,8,42,11,42,12,42,316,1,43,1,43,0,0,44,1,1,3,2,5, + 3,7,4,9,5,11,6,13,7,15,8,17,9,19,10,21,11,23,12,25,13,27,14,29,15, + 31,16,33,17,35,18,37,19,39,20,41,21,43,22,45,23,47,24,49,25,51,26, + 53,27,55,28,57,29,59,30,61,31,63,32,65,33,67,34,69,35,71,36,73,37, + 75,38,77,39,79,40,81,41,83,42,85,43,87,44,1,0,12,3,0,65,90,95,95, + 97,122,4,0,48,57,65,90,95,95,97,122,5,0,46,46,48,57,65,90,95,95, + 97,122,1,0,48,57,1,0,48,49,3,0,48,57,65,70,97,102,2,0,34,34,92,92, + 2,0,39,39,92,92,1,0,10,10,2,0,9,9,32,32,5,0,43,43,47,57,61,61,65, + 90,97,122,1,0,0,65534,334,0,1,1,0,0,0,0,3,1,0,0,0,0,5,1,0,0,0,0, + 7,1,0,0,0,0,9,1,0,0,0,0,11,1,0,0,0,0,13,1,0,0,0,0,15,1,0,0,0,0,17, + 1,0,0,0,0,19,1,0,0,0,0,21,1,0,0,0,0,23,1,0,0,0,0,25,1,0,0,0,0,27, + 1,0,0,0,0,29,1,0,0,0,0,31,1,0,0,0,0,33,1,0,0,0,0,35,1,0,0,0,0,37, + 1,0,0,0,0,39,1,0,0,0,0,41,1,0,0,0,0,43,1,0,0,0,0,45,1,0,0,0,0,47, + 1,0,0,0,0,49,1,0,0,0,0,51,1,0,0,0,0,53,1,0,0,0,0,55,1,0,0,0,0,57, + 1,0,0,0,0,59,1,0,0,0,0,61,1,0,0,0,0,63,1,0,0,0,0,65,1,0,0,0,0,67, + 1,0,0,0,0,69,1,0,0,0,0,71,1,0,0,0,0,73,1,0,0,0,0,75,1,0,0,0,0,77, + 1,0,0,0,0,79,1,0,0,0,0,81,1,0,0,0,0,83,1,0,0,0,0,85,1,0,0,0,0,87, + 1,0,0,0,1,89,1,0,0,0,3,95,1,0,0,0,5,101,1,0,0,0,7,110,1,0,0,0,9, + 113,1,0,0,0,11,118,1,0,0,0,13,122,1,0,0,0,15,126,1,0,0,0,17,131, + 1,0,0,0,19,134,1,0,0,0,21,137,1,0,0,0,23,140,1,0,0,0,25,146,1,0, + 0,0,27,152,1,0,0,0,29,158,1,0,0,0,31,163,1,0,0,0,33,170,1,0,0,0, + 35,176,1,0,0,0,37,181,1,0,0,0,39,187,1,0,0,0,41,189,1,0,0,0,43,191, + 1,0,0,0,45,193,1,0,0,0,47,195,1,0,0,0,49,197,1,0,0,0,51,199,1,0, + 0,0,53,202,1,0,0,0,55,205,1,0,0,0,57,207,1,0,0,0,59,209,1,0,0,0, + 61,211,1,0,0,0,63,214,1,0,0,0,65,217,1,0,0,0,67,224,1,0,0,0,69,241, + 1,0,0,0,71,245,1,0,0,0,73,253,1,0,0,0,75,261,1,0,0,0,77,276,1,0, + 0,0,79,292,1,0,0,0,81,296,1,0,0,0,83,305,1,0,0,0,85,309,1,0,0,0, + 87,318,1,0,0,0,89,90,5,97,0,0,90,91,5,115,0,0,91,92,5,101,0,0,92, + 93,5,99,0,0,93,94,5,116,0,0,94,2,1,0,0,0,95,96,5,98,0,0,96,97,5, + 114,0,0,97,98,5,101,0,0,98,99,5,97,0,0,99,100,5,107,0,0,100,4,1, + 0,0,0,101,102,5,99,0,0,102,103,5,111,0,0,103,104,5,110,0,0,104,105, + 5,116,0,0,105,106,5,105,0,0,106,107,5,110,0,0,107,108,5,117,0,0, + 108,109,5,101,0,0,109,6,1,0,0,0,110,111,5,100,0,0,111,112,5,111, + 0,0,112,8,1,0,0,0,113,114,5,101,0,0,114,115,5,108,0,0,115,116,5, + 115,0,0,116,117,5,101,0,0,117,10,1,0,0,0,118,119,5,101,0,0,119,120, + 5,110,0,0,120,121,5,100,0,0,121,12,1,0,0,0,122,123,5,101,0,0,123, + 124,5,120,0,0,124,125,5,116,0,0,125,14,1,0,0,0,126,127,5,102,0,0, + 127,128,5,105,0,0,128,129,5,108,0,0,129,130,5,101,0,0,130,16,1,0, + 0,0,131,132,5,102,0,0,132,133,5,105,0,0,133,18,1,0,0,0,134,135,5, + 105,0,0,135,136,5,102,0,0,136,20,1,0,0,0,137,138,5,105,0,0,138,139, + 5,115,0,0,139,22,1,0,0,0,140,141,5,109,0,0,141,142,5,97,0,0,142, + 143,5,99,0,0,143,144,5,114,0,0,144,145,5,111,0,0,145,24,1,0,0,0, + 146,147,5,114,0,0,147,148,5,115,0,0,148,149,5,101,0,0,149,150,5, + 99,0,0,150,151,5,116,0,0,151,26,1,0,0,0,152,153,5,115,0,0,153,154, + 5,116,0,0,154,155,5,97,0,0,155,156,5,121,0,0,156,157,5,115,0,0,157, + 28,1,0,0,0,158,159,5,116,0,0,159,160,5,104,0,0,160,161,5,101,0,0, + 161,162,5,110,0,0,162,30,1,0,0,0,163,164,5,116,0,0,164,165,5,112, + 0,0,165,166,5,108,0,0,166,167,5,97,0,0,167,168,5,116,0,0,168,169, + 5,101,0,0,169,32,1,0,0,0,170,171,5,117,0,0,171,172,5,110,0,0,172, + 173,5,116,0,0,173,174,5,105,0,0,174,175,5,108,0,0,175,34,1,0,0,0, + 176,177,5,119,0,0,177,178,5,101,0,0,178,179,5,110,0,0,179,180,5, + 100,0,0,180,36,1,0,0,0,181,182,5,119,0,0,182,183,5,104,0,0,183,184, + 5,105,0,0,184,185,5,108,0,0,185,186,5,101,0,0,186,38,1,0,0,0,187, + 188,5,46,0,0,188,40,1,0,0,0,189,190,5,44,0,0,190,42,1,0,0,0,191, + 192,5,43,0,0,192,44,1,0,0,0,193,194,5,45,0,0,194,46,1,0,0,0,195, + 196,5,58,0,0,196,48,1,0,0,0,197,198,5,62,0,0,198,50,1,0,0,0,199, + 200,5,58,0,0,200,201,5,62,0,0,201,52,1,0,0,0,202,203,5,63,0,0,203, + 204,5,62,0,0,204,54,1,0,0,0,205,206,5,63,0,0,206,56,1,0,0,0,207, + 208,5,40,0,0,208,58,1,0,0,0,209,210,5,41,0,0,210,60,1,0,0,0,211, + 212,5,45,0,0,212,213,5,124,0,0,213,62,1,0,0,0,214,215,5,114,0,0, + 215,216,3,69,34,0,216,64,1,0,0,0,217,221,7,0,0,0,218,220,7,1,0,0, + 219,218,1,0,0,0,220,223,1,0,0,0,221,219,1,0,0,0,221,222,1,0,0,0, + 222,66,1,0,0,0,223,221,1,0,0,0,224,228,7,0,0,0,225,227,7,1,0,0,226, + 225,1,0,0,0,227,230,1,0,0,0,228,226,1,0,0,0,228,229,1,0,0,0,229, + 231,1,0,0,0,230,228,1,0,0,0,231,235,3,39,19,0,232,234,7,2,0,0,233, + 232,1,0,0,0,234,237,1,0,0,0,235,233,1,0,0,0,235,236,1,0,0,0,236, + 238,1,0,0,0,237,235,1,0,0,0,238,239,7,1,0,0,239,68,1,0,0,0,240,242, + 7,3,0,0,241,240,1,0,0,0,242,243,1,0,0,0,243,241,1,0,0,0,243,244, + 1,0,0,0,244,70,1,0,0,0,245,246,5,48,0,0,246,247,5,98,0,0,247,249, + 1,0,0,0,248,250,7,4,0,0,249,248,1,0,0,0,250,251,1,0,0,0,251,249, + 1,0,0,0,251,252,1,0,0,0,252,72,1,0,0,0,253,254,5,48,0,0,254,255, + 5,120,0,0,255,257,1,0,0,0,256,258,7,5,0,0,257,256,1,0,0,0,258,259, + 1,0,0,0,259,257,1,0,0,0,259,260,1,0,0,0,260,74,1,0,0,0,261,271,5, + 34,0,0,262,264,8,6,0,0,263,262,1,0,0,0,264,265,1,0,0,0,265,263,1, + 0,0,0,265,266,1,0,0,0,266,270,1,0,0,0,267,268,5,92,0,0,268,270,9, + 0,0,0,269,263,1,0,0,0,269,267,1,0,0,0,270,273,1,0,0,0,271,269,1, + 0,0,0,271,272,1,0,0,0,272,274,1,0,0,0,273,271,1,0,0,0,274,275,5, + 34,0,0,275,76,1,0,0,0,276,286,5,39,0,0,277,279,8,7,0,0,278,277,1, + 0,0,0,279,280,1,0,0,0,280,278,1,0,0,0,280,281,1,0,0,0,281,285,1, + 0,0,0,282,283,5,92,0,0,283,285,9,0,0,0,284,278,1,0,0,0,284,282,1, + 0,0,0,285,288,1,0,0,0,286,284,1,0,0,0,286,287,1,0,0,0,287,289,1, + 0,0,0,288,286,1,0,0,0,289,290,5,39,0,0,290,78,1,0,0,0,291,293,5, + 13,0,0,292,291,1,0,0,0,292,293,1,0,0,0,293,294,1,0,0,0,294,295,5, + 10,0,0,295,80,1,0,0,0,296,300,5,35,0,0,297,299,8,8,0,0,298,297,1, + 0,0,0,299,302,1,0,0,0,300,298,1,0,0,0,300,301,1,0,0,0,301,303,1, + 0,0,0,302,300,1,0,0,0,303,304,6,40,0,0,304,82,1,0,0,0,305,306,7, + 9,0,0,306,307,1,0,0,0,307,308,6,41,0,0,308,84,1,0,0,0,309,310,5, + 102,0,0,310,311,5,112,0,0,311,312,5,45,0,0,312,314,1,0,0,0,313,315, + 7,10,0,0,314,313,1,0,0,0,315,316,1,0,0,0,316,314,1,0,0,0,316,317, + 1,0,0,0,317,86,1,0,0,0,318,319,7,11,0,0,319,88,1,0,0,0,16,0,221, + 228,235,243,251,259,265,269,271,280,284,286,292,300,316,1,6,0,0 ] class AsmLexer(Lexer): @@ -143,26 +142,26 @@ class AsmLexer(Lexer): End = 6 Ext = 7 File = 8 - Weak = 9 - Fi = 10 - If = 11 - Is = 12 - Macro = 13 - Rsect = 14 - Stays = 15 - Then = 16 - Tplate = 17 - Until = 18 - Wend = 19 - While = 20 - DOT = 21 - COMMA = 22 - PLUS = 23 - MINUS = 24 - COLON = 25 - ANGLE_BRACKET = 26 - COLON_ANGLE = 27 - TILDE_ANGLE = 28 + Fi = 9 + If = 10 + Is = 11 + Macro = 12 + Rsect = 13 + Stays = 14 + Then = 15 + Tplate = 16 + Until = 17 + Wend = 18 + While = 19 + DOT = 20 + COMMA = 21 + PLUS = 22 + MINUS = 23 + COLON = 24 + ANGLE_BRACKET = 25 + COLON_ANGLE = 26 + QUESTION_ANGLE = 27 + QUESTION = 28 OPEN_PAREN = 29 CLOSE_PAREN = 30 LINE_MARK_MARKER = 31 @@ -186,26 +185,26 @@ class AsmLexer(Lexer): literalNames = [ "", "'asect'", "'break'", "'continue'", "'do'", "'else'", "'end'", - "'ext'", "'file'", "'weak'", "'fi'", "'if'", "'is'", "'macro'", - "'rsect'", "'stays'", "'then'", "'tplate'", "'until'", "'wend'", - "'while'", "'.'", "','", "'+'", "'-'", "':'", "'>'", "':>'", - "'~>'", "'('", "')'", "'-|'" ] + "'ext'", "'file'", "'fi'", "'if'", "'is'", "'macro'", "'rsect'", + "'stays'", "'then'", "'tplate'", "'until'", "'wend'", "'while'", + "'.'", "','", "'+'", "'-'", "':'", "'>'", "':>'", "'?>'", "'?'", + "'('", "')'", "'-|'" ] symbolicNames = [ "", "Asect", "Break", "Continue", "Do", "Else", "End", "Ext", "File", - "Weak", "Fi", "If", "Is", "Macro", "Rsect", "Stays", "Then", - "Tplate", "Until", "Wend", "While", "DOT", "COMMA", "PLUS", - "MINUS", "COLON", "ANGLE_BRACKET", "COLON_ANGLE", "TILDE_ANGLE", + "Fi", "If", "Is", "Macro", "Rsect", "Stays", "Then", "Tplate", + "Until", "Wend", "While", "DOT", "COMMA", "PLUS", "MINUS", "COLON", + "ANGLE_BRACKET", "COLON_ANGLE", "QUESTION_ANGLE", "QUESTION", "OPEN_PAREN", "CLOSE_PAREN", "LINE_MARK_MARKER", "REGISTER", "WORD", "WORD_WITH_DOTS", "DECIMAL_NUMBER", "BINARY_NUMBER", "HEX_NUMBER", "STRING", "CHAR", "NEWLINE", "COMMENT", "WS", "BASE64", "UNEXPECTED_TOKEN" ] ruleNames = [ "Asect", "Break", "Continue", "Do", "Else", "End", "Ext", - "File", "Weak", "Fi", "If", "Is", "Macro", "Rsect", "Stays", - "Then", "Tplate", "Until", "Wend", "While", "DOT", "COMMA", - "PLUS", "MINUS", "COLON", "ANGLE_BRACKET", "COLON_ANGLE", - "TILDE_ANGLE", "OPEN_PAREN", "CLOSE_PAREN", "LINE_MARK_MARKER", + "File", "Fi", "If", "Is", "Macro", "Rsect", "Stays", "Then", + "Tplate", "Until", "Wend", "While", "DOT", "COMMA", "PLUS", + "MINUS", "COLON", "ANGLE_BRACKET", "COLON_ANGLE", "QUESTION_ANGLE", + "QUESTION", "OPEN_PAREN", "CLOSE_PAREN", "LINE_MARK_MARKER", "REGISTER", "WORD", "WORD_WITH_DOTS", "DECIMAL_NUMBER", "BINARY_NUMBER", "HEX_NUMBER", "STRING", "CHAR", "NEWLINE", "COMMENT", "WS", "BASE64", "UNEXPECTED_TOKEN" ] diff --git a/cocas/assembler/generated/AsmParser.py b/cocas/assembler/generated/AsmParser.py index a5e57fe6..fc441d63 100644 --- a/cocas/assembler/generated/AsmParser.py +++ b/cocas/assembler/generated/AsmParser.py @@ -13,7 +13,7 @@ def serializedATN(): return [ - 4,1,44,413,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, + 4,1,44,414,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, 6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2,13,7,13, 2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7,19,2,20, 7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,2,26,7,26, @@ -30,136 +30,137 @@ def serializedATN(): 1,8,1,8,1,8,1,8,3,8,184,8,8,1,8,4,8,187,8,8,11,8,12,8,188,1,8,1, 8,1,8,1,8,1,8,1,8,1,9,1,9,1,10,1,10,1,11,1,11,4,11,203,8,11,11,11, 12,11,204,1,12,1,12,4,12,209,8,12,11,12,12,12,210,1,13,1,13,1,14, - 1,14,1,14,3,14,218,8,14,1,15,1,15,1,15,1,15,3,15,224,8,15,1,16,1, - 16,3,16,228,8,16,1,16,4,16,231,8,16,11,16,12,16,232,1,16,3,16,236, - 8,16,1,16,1,16,3,16,240,8,16,1,16,4,16,243,8,16,11,16,12,16,244, - 3,16,247,8,16,1,17,1,17,1,17,1,18,1,18,1,18,5,18,255,8,18,10,18, - 12,18,258,9,18,1,19,1,19,1,19,5,19,263,8,19,10,19,12,19,266,9,19, - 1,20,1,20,4,20,270,8,20,11,20,12,20,271,1,20,1,20,1,20,3,20,277, - 8,20,1,20,1,20,4,20,281,8,20,11,20,12,20,282,1,21,5,21,286,8,21, - 10,21,12,21,289,9,21,1,21,1,21,4,21,293,8,21,11,21,12,21,294,1,21, - 1,21,4,21,299,8,21,11,21,12,21,300,3,21,303,8,21,1,22,1,22,1,22, - 1,22,4,22,309,8,22,11,22,12,22,310,1,23,1,23,1,23,1,23,1,24,1,24, - 4,24,319,8,24,11,24,12,24,320,1,24,1,24,1,25,1,25,1,26,1,26,1,27, - 1,27,4,27,331,8,27,11,27,12,27,332,1,27,1,27,1,27,1,27,4,27,339, - 8,27,11,27,12,27,340,1,27,1,27,1,27,4,27,346,8,27,11,27,12,27,347, - 1,28,1,28,1,29,1,29,4,29,354,8,29,11,29,12,29,355,1,29,1,29,1,29, - 1,29,4,29,362,8,29,11,29,12,29,363,1,30,1,30,1,30,1,30,1,30,3,30, - 371,8,30,1,31,1,31,1,31,1,31,1,31,1,32,1,32,5,32,380,8,32,10,32, - 12,32,383,9,32,1,33,3,33,386,8,33,1,33,1,33,1,34,1,34,1,34,1,35, - 1,35,3,35,395,8,35,1,36,1,36,1,37,1,37,1,38,1,38,1,39,1,39,1,40, - 1,40,1,41,1,41,1,42,1,42,1,43,1,43,1,43,0,0,44,0,2,4,6,8,10,12,14, - 16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58, - 60,62,64,66,68,70,72,74,76,78,80,82,84,86,0,3,1,0,23,24,1,0,35,37, - 2,0,1,20,33,34,425,0,91,1,0,0,0,2,111,1,0,0,0,4,142,1,0,0,0,6,144, - 1,0,0,0,8,151,1,0,0,0,10,158,1,0,0,0,12,165,1,0,0,0,14,176,1,0,0, - 0,16,179,1,0,0,0,18,196,1,0,0,0,20,198,1,0,0,0,22,200,1,0,0,0,24, - 206,1,0,0,0,26,212,1,0,0,0,28,217,1,0,0,0,30,223,1,0,0,0,32,246, - 1,0,0,0,34,248,1,0,0,0,36,251,1,0,0,0,38,259,1,0,0,0,40,267,1,0, - 0,0,42,287,1,0,0,0,44,304,1,0,0,0,46,312,1,0,0,0,48,316,1,0,0,0, - 50,324,1,0,0,0,52,326,1,0,0,0,54,328,1,0,0,0,56,349,1,0,0,0,58,351, - 1,0,0,0,60,370,1,0,0,0,62,372,1,0,0,0,64,377,1,0,0,0,66,385,1,0, - 0,0,68,389,1,0,0,0,70,394,1,0,0,0,72,396,1,0,0,0,74,398,1,0,0,0, - 76,400,1,0,0,0,78,402,1,0,0,0,80,404,1,0,0,0,82,406,1,0,0,0,84,408, - 1,0,0,0,86,410,1,0,0,0,88,90,5,40,0,0,89,88,1,0,0,0,90,93,1,0,0, - 0,91,89,1,0,0,0,91,92,1,0,0,0,92,97,1,0,0,0,93,91,1,0,0,0,94,96, - 3,26,13,0,95,94,1,0,0,0,96,99,1,0,0,0,97,95,1,0,0,0,97,98,1,0,0, - 0,98,103,1,0,0,0,99,97,1,0,0,0,100,102,3,4,2,0,101,100,1,0,0,0,102, - 105,1,0,0,0,103,101,1,0,0,0,103,104,1,0,0,0,104,106,1,0,0,0,105, - 103,1,0,0,0,106,107,5,6,0,0,107,1,1,0,0,0,108,110,5,40,0,0,109,108, - 1,0,0,0,110,113,1,0,0,0,111,109,1,0,0,0,111,112,1,0,0,0,112,115, - 1,0,0,0,113,111,1,0,0,0,114,116,3,16,8,0,115,114,1,0,0,0,116,117, - 1,0,0,0,117,115,1,0,0,0,117,118,1,0,0,0,118,122,1,0,0,0,119,121, - 3,26,13,0,120,119,1,0,0,0,121,124,1,0,0,0,122,120,1,0,0,0,122,123, - 1,0,0,0,123,128,1,0,0,0,124,122,1,0,0,0,125,127,3,4,2,0,126,125, - 1,0,0,0,127,130,1,0,0,0,128,126,1,0,0,0,128,129,1,0,0,0,129,131, - 1,0,0,0,130,128,1,0,0,0,131,132,5,6,0,0,132,3,1,0,0,0,133,134,3, - 6,3,0,134,135,3,12,6,0,135,143,1,0,0,0,136,137,3,8,4,0,137,138,3, - 12,6,0,138,143,1,0,0,0,139,140,3,10,5,0,140,141,3,12,6,0,141,143, - 1,0,0,0,142,133,1,0,0,0,142,136,1,0,0,0,142,139,1,0,0,0,143,5,1, - 0,0,0,144,145,5,1,0,0,145,147,3,84,42,0,146,148,5,40,0,0,147,146, - 1,0,0,0,148,149,1,0,0,0,149,147,1,0,0,0,149,150,1,0,0,0,150,7,1, - 0,0,0,151,152,5,14,0,0,152,154,3,86,43,0,153,155,5,40,0,0,154,153, - 1,0,0,0,155,156,1,0,0,0,156,154,1,0,0,0,156,157,1,0,0,0,157,9,1, - 0,0,0,158,159,5,17,0,0,159,161,3,86,43,0,160,162,5,40,0,0,161,160, - 1,0,0,0,162,163,1,0,0,0,163,161,1,0,0,0,163,164,1,0,0,0,164,11,1, - 0,0,0,165,166,3,14,7,0,166,13,1,0,0,0,167,175,3,22,11,0,168,175, - 3,24,12,0,169,175,3,32,16,0,170,175,3,40,20,0,171,175,3,54,27,0, - 172,175,3,58,29,0,173,175,3,16,8,0,174,167,1,0,0,0,174,168,1,0,0, - 0,174,169,1,0,0,0,174,170,1,0,0,0,174,171,1,0,0,0,174,172,1,0,0, - 0,174,173,1,0,0,0,175,178,1,0,0,0,176,174,1,0,0,0,176,177,1,0,0, - 0,177,15,1,0,0,0,178,176,1,0,0,0,179,180,5,31,0,0,180,181,3,18,9, - 0,181,183,3,20,10,0,182,184,5,33,0,0,183,182,1,0,0,0,183,184,1,0, - 0,0,184,186,1,0,0,0,185,187,5,40,0,0,186,185,1,0,0,0,187,188,1,0, - 0,0,188,186,1,0,0,0,188,189,1,0,0,0,189,190,1,0,0,0,190,191,6,8, - -1,0,191,192,6,8,-1,0,192,193,6,8,-1,0,193,194,6,8,-1,0,194,195, - 6,8,-1,0,195,17,1,0,0,0,196,197,5,35,0,0,197,19,1,0,0,0,198,199, - 5,43,0,0,199,21,1,0,0,0,200,202,5,2,0,0,201,203,5,40,0,0,202,201, - 1,0,0,0,203,204,1,0,0,0,204,202,1,0,0,0,204,205,1,0,0,0,205,23,1, - 0,0,0,206,208,5,3,0,0,207,209,5,40,0,0,208,207,1,0,0,0,209,210,1, - 0,0,0,210,208,1,0,0,0,210,211,1,0,0,0,211,25,1,0,0,0,212,213,3,32, - 16,0,213,27,1,0,0,0,214,218,5,7,0,0,215,218,5,8,0,0,216,218,5,9, - 0,0,217,214,1,0,0,0,217,215,1,0,0,0,217,216,1,0,0,0,218,29,1,0,0, - 0,219,224,5,25,0,0,220,224,5,26,0,0,221,224,5,27,0,0,222,224,5,28, - 0,0,223,219,1,0,0,0,223,220,1,0,0,0,223,221,1,0,0,0,223,222,1,0, - 0,0,224,31,1,0,0,0,225,227,3,34,17,0,226,228,3,28,14,0,227,226,1, - 0,0,0,227,228,1,0,0,0,228,230,1,0,0,0,229,231,5,40,0,0,230,229,1, - 0,0,0,231,232,1,0,0,0,232,230,1,0,0,0,232,233,1,0,0,0,233,247,1, - 0,0,0,234,236,3,34,17,0,235,234,1,0,0,0,235,236,1,0,0,0,236,237, - 1,0,0,0,237,239,3,76,38,0,238,240,3,38,19,0,239,238,1,0,0,0,239, - 240,1,0,0,0,240,242,1,0,0,0,241,243,5,40,0,0,242,241,1,0,0,0,243, - 244,1,0,0,0,244,242,1,0,0,0,244,245,1,0,0,0,245,247,1,0,0,0,246, - 225,1,0,0,0,246,235,1,0,0,0,247,33,1,0,0,0,248,249,3,36,18,0,249, - 250,3,30,15,0,250,35,1,0,0,0,251,256,3,74,37,0,252,253,5,22,0,0, - 253,255,3,74,37,0,254,252,1,0,0,0,255,258,1,0,0,0,256,254,1,0,0, - 0,256,257,1,0,0,0,257,37,1,0,0,0,258,256,1,0,0,0,259,264,3,60,30, - 0,260,261,5,22,0,0,261,263,3,60,30,0,262,260,1,0,0,0,263,266,1,0, - 0,0,264,262,1,0,0,0,264,265,1,0,0,0,265,39,1,0,0,0,266,264,1,0,0, - 0,267,269,5,11,0,0,268,270,5,40,0,0,269,268,1,0,0,0,270,271,1,0, - 0,0,271,269,1,0,0,0,271,272,1,0,0,0,272,273,1,0,0,0,273,274,3,42, - 21,0,274,276,3,14,7,0,275,277,3,48,24,0,276,275,1,0,0,0,276,277, - 1,0,0,0,277,278,1,0,0,0,278,280,5,10,0,0,279,281,5,40,0,0,280,279, - 1,0,0,0,281,282,1,0,0,0,282,280,1,0,0,0,282,283,1,0,0,0,283,41,1, - 0,0,0,284,286,3,44,22,0,285,284,1,0,0,0,286,289,1,0,0,0,287,285, - 1,0,0,0,287,288,1,0,0,0,288,290,1,0,0,0,289,287,1,0,0,0,290,292, - 3,46,23,0,291,293,5,40,0,0,292,291,1,0,0,0,293,294,1,0,0,0,294,292, - 1,0,0,0,294,295,1,0,0,0,295,302,1,0,0,0,296,298,5,16,0,0,297,299, - 5,40,0,0,298,297,1,0,0,0,299,300,1,0,0,0,300,298,1,0,0,0,300,301, - 1,0,0,0,301,303,1,0,0,0,302,296,1,0,0,0,302,303,1,0,0,0,303,43,1, - 0,0,0,304,305,3,46,23,0,305,306,5,22,0,0,306,308,3,52,26,0,307,309, - 5,40,0,0,308,307,1,0,0,0,309,310,1,0,0,0,310,308,1,0,0,0,310,311, - 1,0,0,0,311,45,1,0,0,0,312,313,3,14,7,0,313,314,5,12,0,0,314,315, - 3,50,25,0,315,47,1,0,0,0,316,318,5,5,0,0,317,319,5,40,0,0,318,317, - 1,0,0,0,319,320,1,0,0,0,320,318,1,0,0,0,320,321,1,0,0,0,321,322, - 1,0,0,0,322,323,3,14,7,0,323,49,1,0,0,0,324,325,5,33,0,0,325,51, - 1,0,0,0,326,327,5,33,0,0,327,53,1,0,0,0,328,330,5,20,0,0,329,331, - 5,40,0,0,330,329,1,0,0,0,331,332,1,0,0,0,332,330,1,0,0,0,332,333, - 1,0,0,0,333,334,1,0,0,0,334,335,3,56,28,0,335,336,5,15,0,0,336,338, - 3,50,25,0,337,339,5,40,0,0,338,337,1,0,0,0,339,340,1,0,0,0,340,338, - 1,0,0,0,340,341,1,0,0,0,341,342,1,0,0,0,342,343,3,14,7,0,343,345, - 5,19,0,0,344,346,5,40,0,0,345,344,1,0,0,0,346,347,1,0,0,0,347,345, - 1,0,0,0,347,348,1,0,0,0,348,55,1,0,0,0,349,350,3,14,7,0,350,57,1, - 0,0,0,351,353,5,4,0,0,352,354,5,40,0,0,353,352,1,0,0,0,354,355,1, - 0,0,0,355,353,1,0,0,0,355,356,1,0,0,0,356,357,1,0,0,0,357,358,3, - 14,7,0,358,359,5,18,0,0,359,361,3,50,25,0,360,362,5,40,0,0,361,360, - 1,0,0,0,362,363,1,0,0,0,363,361,1,0,0,0,363,364,1,0,0,0,364,59,1, - 0,0,0,365,371,3,82,41,0,366,371,3,78,39,0,367,371,3,80,40,0,368, - 371,3,64,32,0,369,371,3,62,31,0,370,365,1,0,0,0,370,366,1,0,0,0, - 370,367,1,0,0,0,370,368,1,0,0,0,370,369,1,0,0,0,371,61,1,0,0,0,372, - 373,3,72,36,0,373,374,5,29,0,0,374,375,3,64,32,0,375,376,5,30,0, - 0,376,63,1,0,0,0,377,381,3,66,33,0,378,380,3,68,34,0,379,378,1,0, - 0,0,380,383,1,0,0,0,381,379,1,0,0,0,381,382,1,0,0,0,382,65,1,0,0, - 0,383,381,1,0,0,0,384,386,7,0,0,0,385,384,1,0,0,0,385,386,1,0,0, - 0,386,387,1,0,0,0,387,388,3,70,35,0,388,67,1,0,0,0,389,390,7,0,0, - 0,390,391,3,70,35,0,391,69,1,0,0,0,392,395,3,84,42,0,393,395,3,74, - 37,0,394,392,1,0,0,0,394,393,1,0,0,0,395,71,1,0,0,0,396,397,3,86, - 43,0,397,73,1,0,0,0,398,399,3,86,43,0,399,75,1,0,0,0,400,401,5,33, - 0,0,401,77,1,0,0,0,402,403,5,38,0,0,403,79,1,0,0,0,404,405,5,32, - 0,0,405,81,1,0,0,0,406,407,5,39,0,0,407,83,1,0,0,0,408,409,7,1,0, - 0,409,85,1,0,0,0,410,411,7,2,0,0,411,87,1,0,0,0,45,91,97,103,111, - 117,122,128,142,149,156,163,174,176,183,188,204,210,217,223,227, - 232,235,239,244,246,256,264,271,276,282,287,294,300,302,310,320, - 332,340,347,355,363,370,381,385,394 + 1,14,1,14,1,14,3,14,219,8,14,1,15,1,15,1,15,1,15,3,15,225,8,15,1, + 16,1,16,3,16,229,8,16,1,16,4,16,232,8,16,11,16,12,16,233,1,16,3, + 16,237,8,16,1,16,1,16,3,16,241,8,16,1,16,4,16,244,8,16,11,16,12, + 16,245,3,16,248,8,16,1,17,1,17,1,17,1,18,1,18,1,18,5,18,256,8,18, + 10,18,12,18,259,9,18,1,19,1,19,1,19,5,19,264,8,19,10,19,12,19,267, + 9,19,1,20,1,20,4,20,271,8,20,11,20,12,20,272,1,20,1,20,1,20,3,20, + 278,8,20,1,20,1,20,4,20,282,8,20,11,20,12,20,283,1,21,5,21,287,8, + 21,10,21,12,21,290,9,21,1,21,1,21,4,21,294,8,21,11,21,12,21,295, + 1,21,1,21,4,21,300,8,21,11,21,12,21,301,3,21,304,8,21,1,22,1,22, + 1,22,1,22,4,22,310,8,22,11,22,12,22,311,1,23,1,23,1,23,1,23,1,24, + 1,24,4,24,320,8,24,11,24,12,24,321,1,24,1,24,1,25,1,25,1,26,1,26, + 1,27,1,27,4,27,332,8,27,11,27,12,27,333,1,27,1,27,1,27,1,27,4,27, + 340,8,27,11,27,12,27,341,1,27,1,27,1,27,4,27,347,8,27,11,27,12,27, + 348,1,28,1,28,1,29,1,29,4,29,355,8,29,11,29,12,29,356,1,29,1,29, + 1,29,1,29,4,29,363,8,29,11,29,12,29,364,1,30,1,30,1,30,1,30,1,30, + 3,30,372,8,30,1,31,1,31,1,31,1,31,1,31,1,32,1,32,5,32,381,8,32,10, + 32,12,32,384,9,32,1,33,3,33,387,8,33,1,33,1,33,1,34,1,34,1,34,1, + 35,1,35,3,35,396,8,35,1,36,1,36,1,37,1,37,1,38,1,38,1,39,1,39,1, + 40,1,40,1,41,1,41,1,42,1,42,1,43,1,43,1,43,0,0,44,0,2,4,6,8,10,12, + 14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56, + 58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,0,3,1,0,22,23,1,0,35, + 37,2,0,1,19,33,34,426,0,91,1,0,0,0,2,111,1,0,0,0,4,142,1,0,0,0,6, + 144,1,0,0,0,8,151,1,0,0,0,10,158,1,0,0,0,12,165,1,0,0,0,14,176,1, + 0,0,0,16,179,1,0,0,0,18,196,1,0,0,0,20,198,1,0,0,0,22,200,1,0,0, + 0,24,206,1,0,0,0,26,212,1,0,0,0,28,218,1,0,0,0,30,224,1,0,0,0,32, + 247,1,0,0,0,34,249,1,0,0,0,36,252,1,0,0,0,38,260,1,0,0,0,40,268, + 1,0,0,0,42,288,1,0,0,0,44,305,1,0,0,0,46,313,1,0,0,0,48,317,1,0, + 0,0,50,325,1,0,0,0,52,327,1,0,0,0,54,329,1,0,0,0,56,350,1,0,0,0, + 58,352,1,0,0,0,60,371,1,0,0,0,62,373,1,0,0,0,64,378,1,0,0,0,66,386, + 1,0,0,0,68,390,1,0,0,0,70,395,1,0,0,0,72,397,1,0,0,0,74,399,1,0, + 0,0,76,401,1,0,0,0,78,403,1,0,0,0,80,405,1,0,0,0,82,407,1,0,0,0, + 84,409,1,0,0,0,86,411,1,0,0,0,88,90,5,40,0,0,89,88,1,0,0,0,90,93, + 1,0,0,0,91,89,1,0,0,0,91,92,1,0,0,0,92,97,1,0,0,0,93,91,1,0,0,0, + 94,96,3,26,13,0,95,94,1,0,0,0,96,99,1,0,0,0,97,95,1,0,0,0,97,98, + 1,0,0,0,98,103,1,0,0,0,99,97,1,0,0,0,100,102,3,4,2,0,101,100,1,0, + 0,0,102,105,1,0,0,0,103,101,1,0,0,0,103,104,1,0,0,0,104,106,1,0, + 0,0,105,103,1,0,0,0,106,107,5,6,0,0,107,1,1,0,0,0,108,110,5,40,0, + 0,109,108,1,0,0,0,110,113,1,0,0,0,111,109,1,0,0,0,111,112,1,0,0, + 0,112,115,1,0,0,0,113,111,1,0,0,0,114,116,3,16,8,0,115,114,1,0,0, + 0,116,117,1,0,0,0,117,115,1,0,0,0,117,118,1,0,0,0,118,122,1,0,0, + 0,119,121,3,26,13,0,120,119,1,0,0,0,121,124,1,0,0,0,122,120,1,0, + 0,0,122,123,1,0,0,0,123,128,1,0,0,0,124,122,1,0,0,0,125,127,3,4, + 2,0,126,125,1,0,0,0,127,130,1,0,0,0,128,126,1,0,0,0,128,129,1,0, + 0,0,129,131,1,0,0,0,130,128,1,0,0,0,131,132,5,6,0,0,132,3,1,0,0, + 0,133,134,3,6,3,0,134,135,3,12,6,0,135,143,1,0,0,0,136,137,3,8,4, + 0,137,138,3,12,6,0,138,143,1,0,0,0,139,140,3,10,5,0,140,141,3,12, + 6,0,141,143,1,0,0,0,142,133,1,0,0,0,142,136,1,0,0,0,142,139,1,0, + 0,0,143,5,1,0,0,0,144,145,5,1,0,0,145,147,3,84,42,0,146,148,5,40, + 0,0,147,146,1,0,0,0,148,149,1,0,0,0,149,147,1,0,0,0,149,150,1,0, + 0,0,150,7,1,0,0,0,151,152,5,13,0,0,152,154,3,86,43,0,153,155,5,40, + 0,0,154,153,1,0,0,0,155,156,1,0,0,0,156,154,1,0,0,0,156,157,1,0, + 0,0,157,9,1,0,0,0,158,159,5,16,0,0,159,161,3,86,43,0,160,162,5,40, + 0,0,161,160,1,0,0,0,162,163,1,0,0,0,163,161,1,0,0,0,163,164,1,0, + 0,0,164,11,1,0,0,0,165,166,3,14,7,0,166,13,1,0,0,0,167,175,3,22, + 11,0,168,175,3,24,12,0,169,175,3,32,16,0,170,175,3,40,20,0,171,175, + 3,54,27,0,172,175,3,58,29,0,173,175,3,16,8,0,174,167,1,0,0,0,174, + 168,1,0,0,0,174,169,1,0,0,0,174,170,1,0,0,0,174,171,1,0,0,0,174, + 172,1,0,0,0,174,173,1,0,0,0,175,178,1,0,0,0,176,174,1,0,0,0,176, + 177,1,0,0,0,177,15,1,0,0,0,178,176,1,0,0,0,179,180,5,31,0,0,180, + 181,3,18,9,0,181,183,3,20,10,0,182,184,5,33,0,0,183,182,1,0,0,0, + 183,184,1,0,0,0,184,186,1,0,0,0,185,187,5,40,0,0,186,185,1,0,0,0, + 187,188,1,0,0,0,188,186,1,0,0,0,188,189,1,0,0,0,189,190,1,0,0,0, + 190,191,6,8,-1,0,191,192,6,8,-1,0,192,193,6,8,-1,0,193,194,6,8,-1, + 0,194,195,6,8,-1,0,195,17,1,0,0,0,196,197,5,35,0,0,197,19,1,0,0, + 0,198,199,5,43,0,0,199,21,1,0,0,0,200,202,5,2,0,0,201,203,5,40,0, + 0,202,201,1,0,0,0,203,204,1,0,0,0,204,202,1,0,0,0,204,205,1,0,0, + 0,205,23,1,0,0,0,206,208,5,3,0,0,207,209,5,40,0,0,208,207,1,0,0, + 0,209,210,1,0,0,0,210,208,1,0,0,0,210,211,1,0,0,0,211,25,1,0,0,0, + 212,213,3,32,16,0,213,27,1,0,0,0,214,219,5,7,0,0,215,219,5,8,0,0, + 216,217,5,7,0,0,217,219,5,28,0,0,218,214,1,0,0,0,218,215,1,0,0,0, + 218,216,1,0,0,0,219,29,1,0,0,0,220,225,5,24,0,0,221,225,5,25,0,0, + 222,225,5,26,0,0,223,225,5,27,0,0,224,220,1,0,0,0,224,221,1,0,0, + 0,224,222,1,0,0,0,224,223,1,0,0,0,225,31,1,0,0,0,226,228,3,34,17, + 0,227,229,3,28,14,0,228,227,1,0,0,0,228,229,1,0,0,0,229,231,1,0, + 0,0,230,232,5,40,0,0,231,230,1,0,0,0,232,233,1,0,0,0,233,231,1,0, + 0,0,233,234,1,0,0,0,234,248,1,0,0,0,235,237,3,34,17,0,236,235,1, + 0,0,0,236,237,1,0,0,0,237,238,1,0,0,0,238,240,3,76,38,0,239,241, + 3,38,19,0,240,239,1,0,0,0,240,241,1,0,0,0,241,243,1,0,0,0,242,244, + 5,40,0,0,243,242,1,0,0,0,244,245,1,0,0,0,245,243,1,0,0,0,245,246, + 1,0,0,0,246,248,1,0,0,0,247,226,1,0,0,0,247,236,1,0,0,0,248,33,1, + 0,0,0,249,250,3,36,18,0,250,251,3,30,15,0,251,35,1,0,0,0,252,257, + 3,74,37,0,253,254,5,21,0,0,254,256,3,74,37,0,255,253,1,0,0,0,256, + 259,1,0,0,0,257,255,1,0,0,0,257,258,1,0,0,0,258,37,1,0,0,0,259,257, + 1,0,0,0,260,265,3,60,30,0,261,262,5,21,0,0,262,264,3,60,30,0,263, + 261,1,0,0,0,264,267,1,0,0,0,265,263,1,0,0,0,265,266,1,0,0,0,266, + 39,1,0,0,0,267,265,1,0,0,0,268,270,5,10,0,0,269,271,5,40,0,0,270, + 269,1,0,0,0,271,272,1,0,0,0,272,270,1,0,0,0,272,273,1,0,0,0,273, + 274,1,0,0,0,274,275,3,42,21,0,275,277,3,14,7,0,276,278,3,48,24,0, + 277,276,1,0,0,0,277,278,1,0,0,0,278,279,1,0,0,0,279,281,5,9,0,0, + 280,282,5,40,0,0,281,280,1,0,0,0,282,283,1,0,0,0,283,281,1,0,0,0, + 283,284,1,0,0,0,284,41,1,0,0,0,285,287,3,44,22,0,286,285,1,0,0,0, + 287,290,1,0,0,0,288,286,1,0,0,0,288,289,1,0,0,0,289,291,1,0,0,0, + 290,288,1,0,0,0,291,293,3,46,23,0,292,294,5,40,0,0,293,292,1,0,0, + 0,294,295,1,0,0,0,295,293,1,0,0,0,295,296,1,0,0,0,296,303,1,0,0, + 0,297,299,5,15,0,0,298,300,5,40,0,0,299,298,1,0,0,0,300,301,1,0, + 0,0,301,299,1,0,0,0,301,302,1,0,0,0,302,304,1,0,0,0,303,297,1,0, + 0,0,303,304,1,0,0,0,304,43,1,0,0,0,305,306,3,46,23,0,306,307,5,21, + 0,0,307,309,3,52,26,0,308,310,5,40,0,0,309,308,1,0,0,0,310,311,1, + 0,0,0,311,309,1,0,0,0,311,312,1,0,0,0,312,45,1,0,0,0,313,314,3,14, + 7,0,314,315,5,11,0,0,315,316,3,50,25,0,316,47,1,0,0,0,317,319,5, + 5,0,0,318,320,5,40,0,0,319,318,1,0,0,0,320,321,1,0,0,0,321,319,1, + 0,0,0,321,322,1,0,0,0,322,323,1,0,0,0,323,324,3,14,7,0,324,49,1, + 0,0,0,325,326,5,33,0,0,326,51,1,0,0,0,327,328,5,33,0,0,328,53,1, + 0,0,0,329,331,5,19,0,0,330,332,5,40,0,0,331,330,1,0,0,0,332,333, + 1,0,0,0,333,331,1,0,0,0,333,334,1,0,0,0,334,335,1,0,0,0,335,336, + 3,56,28,0,336,337,5,14,0,0,337,339,3,50,25,0,338,340,5,40,0,0,339, + 338,1,0,0,0,340,341,1,0,0,0,341,339,1,0,0,0,341,342,1,0,0,0,342, + 343,1,0,0,0,343,344,3,14,7,0,344,346,5,18,0,0,345,347,5,40,0,0,346, + 345,1,0,0,0,347,348,1,0,0,0,348,346,1,0,0,0,348,349,1,0,0,0,349, + 55,1,0,0,0,350,351,3,14,7,0,351,57,1,0,0,0,352,354,5,4,0,0,353,355, + 5,40,0,0,354,353,1,0,0,0,355,356,1,0,0,0,356,354,1,0,0,0,356,357, + 1,0,0,0,357,358,1,0,0,0,358,359,3,14,7,0,359,360,5,17,0,0,360,362, + 3,50,25,0,361,363,5,40,0,0,362,361,1,0,0,0,363,364,1,0,0,0,364,362, + 1,0,0,0,364,365,1,0,0,0,365,59,1,0,0,0,366,372,3,82,41,0,367,372, + 3,78,39,0,368,372,3,80,40,0,369,372,3,64,32,0,370,372,3,62,31,0, + 371,366,1,0,0,0,371,367,1,0,0,0,371,368,1,0,0,0,371,369,1,0,0,0, + 371,370,1,0,0,0,372,61,1,0,0,0,373,374,3,72,36,0,374,375,5,29,0, + 0,375,376,3,64,32,0,376,377,5,30,0,0,377,63,1,0,0,0,378,382,3,66, + 33,0,379,381,3,68,34,0,380,379,1,0,0,0,381,384,1,0,0,0,382,380,1, + 0,0,0,382,383,1,0,0,0,383,65,1,0,0,0,384,382,1,0,0,0,385,387,7,0, + 0,0,386,385,1,0,0,0,386,387,1,0,0,0,387,388,1,0,0,0,388,389,3,70, + 35,0,389,67,1,0,0,0,390,391,7,0,0,0,391,392,3,70,35,0,392,69,1,0, + 0,0,393,396,3,84,42,0,394,396,3,74,37,0,395,393,1,0,0,0,395,394, + 1,0,0,0,396,71,1,0,0,0,397,398,3,86,43,0,398,73,1,0,0,0,399,400, + 3,86,43,0,400,75,1,0,0,0,401,402,5,33,0,0,402,77,1,0,0,0,403,404, + 5,38,0,0,404,79,1,0,0,0,405,406,5,32,0,0,406,81,1,0,0,0,407,408, + 5,39,0,0,408,83,1,0,0,0,409,410,7,1,0,0,410,85,1,0,0,0,411,412,7, + 2,0,0,412,87,1,0,0,0,45,91,97,103,111,117,122,128,142,149,156,163, + 174,176,183,188,204,210,218,224,228,233,236,240,245,247,257,265, + 272,277,283,288,295,301,303,311,321,333,341,348,356,364,371,382, + 386,395 ] class AsmParser ( Parser ): @@ -173,17 +174,17 @@ class AsmParser ( Parser ): sharedContextCache = PredictionContextCache() literalNames = [ "", "'asect'", "'break'", "'continue'", "'do'", - "'else'", "'end'", "'ext'", "'file'", "'weak'", "'fi'", - "'if'", "'is'", "'macro'", "'rsect'", "'stays'", "'then'", + "'else'", "'end'", "'ext'", "'file'", "'fi'", "'if'", + "'is'", "'macro'", "'rsect'", "'stays'", "'then'", "'tplate'", "'until'", "'wend'", "'while'", "'.'", - "','", "'+'", "'-'", "':'", "'>'", "':>'", "'~>'", - "'('", "')'", "'-|'" ] + "','", "'+'", "'-'", "':'", "'>'", "':>'", "'?>'", + "'?'", "'('", "')'", "'-|'" ] symbolicNames = [ "", "Asect", "Break", "Continue", "Do", "Else", - "End", "Ext", "File", "Weak", "Fi", "If", "Is", "Macro", - "Rsect", "Stays", "Then", "Tplate", "Until", "Wend", - "While", "DOT", "COMMA", "PLUS", "MINUS", "COLON", - "ANGLE_BRACKET", "COLON_ANGLE", "TILDE_ANGLE", "OPEN_PAREN", + "End", "Ext", "File", "Fi", "If", "Is", "Macro", "Rsect", + "Stays", "Then", "Tplate", "Until", "Wend", "While", + "DOT", "COMMA", "PLUS", "MINUS", "COLON", "ANGLE_BRACKET", + "COLON_ANGLE", "QUESTION_ANGLE", "QUESTION", "OPEN_PAREN", "CLOSE_PAREN", "LINE_MARK_MARKER", "REGISTER", "WORD", "WORD_WITH_DOTS", "DECIMAL_NUMBER", "BINARY_NUMBER", "HEX_NUMBER", "STRING", "CHAR", "NEWLINE", "COMMENT", @@ -255,26 +256,26 @@ class AsmParser ( Parser ): End=6 Ext=7 File=8 - Weak=9 - Fi=10 - If=11 - Is=12 - Macro=13 - Rsect=14 - Stays=15 - Then=16 - Tplate=17 - Until=18 - Wend=19 - While=20 - DOT=21 - COMMA=22 - PLUS=23 - MINUS=24 - COLON=25 - ANGLE_BRACKET=26 - COLON_ANGLE=27 - TILDE_ANGLE=28 + Fi=9 + If=10 + Is=11 + Macro=12 + Rsect=13 + Stays=14 + Then=15 + Tplate=16 + Until=17 + Wend=18 + While=19 + DOT=20 + COMMA=21 + PLUS=22 + MINUS=23 + COLON=24 + ANGLE_BRACKET=25 + COLON_ANGLE=26 + QUESTION_ANGLE=27 + QUESTION=28 OPEN_PAREN=29 CLOSE_PAREN=30 LINE_MARK_MARKER=31 @@ -379,7 +380,7 @@ def program_nomacros(self): self.state = 103 self._errHandler.sync(self) _la = self._input.LA(1) - while (((_la) & ~0x3f) == 0 and ((1 << _la) & 147458) != 0): + while (((_la) & ~0x3f) == 0 and ((1 << _la) & 73730) != 0): self.state = 100 self.section() self.state = 105 @@ -489,7 +490,7 @@ def program(self): self.state = 128 self._errHandler.sync(self) _la = self._input.LA(1) - while (((_la) & ~0x3f) == 0 and ((1 << _la) & 147458) != 0): + while (((_la) & ~0x3f) == 0 and ((1 << _la) & 73730) != 0): self.state = 125 self.section() self.state = 130 @@ -601,7 +602,7 @@ def section(self): self.state = 134 self.section_body() pass - elif token in [14]: + elif token in [13]: localctx = AsmParser.RelocatableSectionContext(self, localctx) self.enterOuterAlt(localctx, 2) self.state = 136 @@ -609,7 +610,7 @@ def section(self): self.state = 137 self.section_body() pass - elif token in [17]: + elif token in [16]: localctx = AsmParser.TemplateSectionContext(self, localctx) self.enterOuterAlt(localctx, 3) self.state = 139 @@ -1339,8 +1340,10 @@ def __init__(self, parser, ctx:ParserRuleContext): # actually a AsmParser.Ext_ty super().__init__(parser) self.copyFrom(ctx) - def Weak(self): - return self.getToken(AsmParser.Weak, 0) + def Ext(self): + return self.getToken(AsmParser.Ext, 0) + def QUESTION(self): + return self.getToken(AsmParser.QUESTION, 0) def accept(self, visitor:ParseTreeVisitor): if hasattr( visitor, "visitWeakExtType" ): @@ -1387,29 +1390,32 @@ def ext_type(self): localctx = AsmParser.Ext_typeContext(self, self._ctx, self.state) self.enterRule(localctx, 28, self.RULE_ext_type) try: - self.state = 217 + self.state = 218 self._errHandler.sync(self) - token = self._input.LA(1) - if token in [7]: + la_ = self._interp.adaptivePredict(self._input,17,self._ctx) + if la_ == 1: localctx = AsmParser.GlobalExtTypeContext(self, localctx) self.enterOuterAlt(localctx, 1) self.state = 214 self.match(AsmParser.Ext) pass - elif token in [8]: + + elif la_ == 2: localctx = AsmParser.FileExtTypeContext(self, localctx) self.enterOuterAlt(localctx, 2) self.state = 215 self.match(AsmParser.File) pass - elif token in [9]: + + elif la_ == 3: localctx = AsmParser.WeakExtTypeContext(self, localctx) self.enterOuterAlt(localctx, 3) self.state = 216 - self.match(AsmParser.Weak) + self.match(AsmParser.Ext) + self.state = 217 + self.match(AsmParser.QUESTION) pass - else: - raise NoViableAltException(self) + except RecognitionException as re: localctx.exception = re @@ -1459,8 +1465,8 @@ def __init__(self, parser, ctx:ParserRuleContext): # actually a AsmParser.Label_ super().__init__(parser) self.copyFrom(ctx) - def TILDE_ANGLE(self): - return self.getToken(AsmParser.TILDE_ANGLE, 0) + def QUESTION_ANGLE(self): + return self.getToken(AsmParser.QUESTION_ANGLE, 0) def accept(self, visitor:ParseTreeVisitor): if hasattr( visitor, "visitWeakLabelSuffix" ): @@ -1507,32 +1513,32 @@ def label_suffix(self): localctx = AsmParser.Label_suffixContext(self, self._ctx, self.state) self.enterRule(localctx, 30, self.RULE_label_suffix) try: - self.state = 223 + self.state = 224 self._errHandler.sync(self) token = self._input.LA(1) - if token in [25]: + if token in [24]: localctx = AsmParser.LocalLabelSuffixContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 219 + self.state = 220 self.match(AsmParser.COLON) pass - elif token in [26]: + elif token in [25]: localctx = AsmParser.GlobalLabelSuffixContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 220 + self.state = 221 self.match(AsmParser.ANGLE_BRACKET) pass - elif token in [27]: + elif token in [26]: localctx = AsmParser.FileLabelSuffixContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 221 + self.state = 222 self.match(AsmParser.COLON_ANGLE) pass - elif token in [28]: + elif token in [27]: localctx = AsmParser.WeakLabelSuffixContext(self, localctx) self.enterOuterAlt(localctx, 4) - self.state = 222 - self.match(AsmParser.TILDE_ANGLE) + self.state = 223 + self.match(AsmParser.QUESTION_ANGLE) pass else: raise NoViableAltException(self) @@ -1623,29 +1629,29 @@ def line(self): self.enterRule(localctx, 32, self.RULE_line) self._la = 0 # Token type try: - self.state = 246 + self.state = 247 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,24,self._ctx) if la_ == 1: localctx = AsmParser.StandaloneLabelsContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 225 + self.state = 226 self.labels_declaration() - self.state = 227 + self.state = 228 self._errHandler.sync(self) _la = self._input.LA(1) - if (((_la) & ~0x3f) == 0 and ((1 << _la) & 896) != 0): - self.state = 226 + if _la==7 or _la==8: + self.state = 227 self.ext_type() - self.state = 230 + self.state = 231 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 229 + self.state = 230 self.match(AsmParser.NEWLINE) - self.state = 232 + self.state = 233 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==40): @@ -1656,31 +1662,31 @@ def line(self): elif la_ == 2: localctx = AsmParser.InstructionLineContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 235 + self.state = 236 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,21,self._ctx) if la_ == 1: - self.state = 234 + self.state = 235 self.labels_declaration() - self.state = 237 + self.state = 238 self.instruction() - self.state = 239 + self.state = 240 self._errHandler.sync(self) _la = self._input.LA(1) - if (((_la) & ~0x3f) == 0 and ((1 << _la) & 1095243923454) != 0): - self.state = 238 + if (((_la) & ~0x3f) == 0 and ((1 << _la) & 1095230291966) != 0): + self.state = 239 self.arguments() - self.state = 242 + self.state = 243 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 241 + self.state = 242 self.match(AsmParser.NEWLINE) - self.state = 244 + self.state = 245 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==40): @@ -1731,9 +1737,9 @@ def labels_declaration(self): self.enterRule(localctx, 34, self.RULE_labels_declaration) try: self.enterOuterAlt(localctx, 1) - self.state = 248 - self.labels() self.state = 249 + self.labels() + self.state = 250 self.label_suffix() except RecognitionException as re: localctx.exception = re @@ -1783,17 +1789,17 @@ def labels(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 251 + self.state = 252 self.label() - self.state = 256 + self.state = 257 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==22: - self.state = 252 - self.match(AsmParser.COMMA) + while _la==21: self.state = 253 + self.match(AsmParser.COMMA) + self.state = 254 self.label() - self.state = 258 + self.state = 259 self._errHandler.sync(self) _la = self._input.LA(1) @@ -1845,17 +1851,17 @@ def arguments(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 259 + self.state = 260 self.argument() - self.state = 264 + self.state = 265 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==22: - self.state = 260 - self.match(AsmParser.COMMA) + while _la==21: self.state = 261 + self.match(AsmParser.COMMA) + self.state = 262 self.argument() - self.state = 266 + self.state = 267 self._errHandler.sync(self) _la = self._input.LA(1) @@ -1918,41 +1924,41 @@ def conditional(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 267 + self.state = 268 self.match(AsmParser.If) - self.state = 269 + self.state = 270 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 268 + self.state = 269 self.match(AsmParser.NEWLINE) - self.state = 271 + self.state = 272 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==40): break - self.state = 273 - self.conditions() self.state = 274 + self.conditions() + self.state = 275 self.code_block() - self.state = 276 + self.state = 277 self._errHandler.sync(self) _la = self._input.LA(1) if _la==5: - self.state = 275 + self.state = 276 self.else_clause() - self.state = 278 + self.state = 279 self.match(AsmParser.Fi) - self.state = 280 + self.state = 281 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 279 + self.state = 280 self.match(AsmParser.NEWLINE) - self.state = 282 + self.state = 283 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==40): @@ -2013,44 +2019,44 @@ def conditions(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 287 + self.state = 288 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,30,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 284 + self.state = 285 self.connective_condition() - self.state = 289 + self.state = 290 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,30,self._ctx) - self.state = 290 + self.state = 291 self.condition() - self.state = 292 + self.state = 293 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 291 + self.state = 292 self.match(AsmParser.NEWLINE) - self.state = 294 + self.state = 295 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==40): break - self.state = 302 + self.state = 303 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,33,self._ctx) if la_ == 1: - self.state = 296 + self.state = 297 self.match(AsmParser.Then) - self.state = 298 + self.state = 299 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 297 + self.state = 298 self.match(AsmParser.NEWLINE) - self.state = 300 + self.state = 301 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==40): @@ -2110,19 +2116,19 @@ def connective_condition(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 304 - self.condition() self.state = 305 - self.match(AsmParser.COMMA) + self.condition() self.state = 306 + self.match(AsmParser.COMMA) + self.state = 307 self.conjunction() - self.state = 308 + self.state = 309 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 307 + self.state = 308 self.match(AsmParser.NEWLINE) - self.state = 310 + self.state = 311 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==40): @@ -2173,11 +2179,11 @@ def condition(self): self.enterRule(localctx, 46, self.RULE_condition) try: self.enterOuterAlt(localctx, 1) - self.state = 312 - self.code_block() self.state = 313 - self.match(AsmParser.Is) + self.code_block() self.state = 314 + self.match(AsmParser.Is) + self.state = 315 self.branch_mnemonic() except RecognitionException as re: localctx.exception = re @@ -2227,21 +2233,21 @@ def else_clause(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 316 + self.state = 317 self.match(AsmParser.Else) - self.state = 318 + self.state = 319 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 317 + self.state = 318 self.match(AsmParser.NEWLINE) - self.state = 320 + self.state = 321 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==40): break - self.state = 322 + self.state = 323 self.code_block() except RecognitionException as re: localctx.exception = re @@ -2280,7 +2286,7 @@ def branch_mnemonic(self): self.enterRule(localctx, 50, self.RULE_branch_mnemonic) try: self.enterOuterAlt(localctx, 1) - self.state = 324 + self.state = 325 self.match(AsmParser.WORD) except RecognitionException as re: localctx.exception = re @@ -2319,7 +2325,7 @@ def conjunction(self): self.enterRule(localctx, 52, self.RULE_conjunction) try: self.enterOuterAlt(localctx, 1) - self.state = 326 + self.state = 327 self.match(AsmParser.WORD) except RecognitionException as re: localctx.exception = re @@ -2383,49 +2389,49 @@ def while_loop(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 328 + self.state = 329 self.match(AsmParser.While) - self.state = 330 + self.state = 331 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 329 + self.state = 330 self.match(AsmParser.NEWLINE) - self.state = 332 + self.state = 333 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==40): break - self.state = 334 - self.while_condition() self.state = 335 - self.match(AsmParser.Stays) + self.while_condition() self.state = 336 + self.match(AsmParser.Stays) + self.state = 337 self.branch_mnemonic() - self.state = 338 + self.state = 339 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 337 + self.state = 338 self.match(AsmParser.NEWLINE) - self.state = 340 + self.state = 341 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==40): break - self.state = 342 - self.code_block() self.state = 343 + self.code_block() + self.state = 344 self.match(AsmParser.Wend) - self.state = 345 + self.state = 346 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 344 + self.state = 345 self.match(AsmParser.NEWLINE) - self.state = 347 + self.state = 348 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==40): @@ -2469,7 +2475,7 @@ def while_condition(self): self.enterRule(localctx, 56, self.RULE_while_condition) try: self.enterOuterAlt(localctx, 1) - self.state = 349 + self.state = 350 self.code_block() except RecognitionException as re: localctx.exception = re @@ -2526,33 +2532,33 @@ def until_loop(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 351 + self.state = 352 self.match(AsmParser.Do) - self.state = 353 + self.state = 354 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 352 + self.state = 353 self.match(AsmParser.NEWLINE) - self.state = 355 + self.state = 356 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==40): break - self.state = 357 - self.code_block() self.state = 358 - self.match(AsmParser.Until) + self.code_block() self.state = 359 + self.match(AsmParser.Until) + self.state = 360 self.branch_mnemonic() - self.state = 361 + self.state = 362 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 360 + self.state = 361 self.match(AsmParser.NEWLINE) - self.state = 363 + self.state = 364 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==40): @@ -2611,36 +2617,36 @@ def argument(self): localctx = AsmParser.ArgumentContext(self, self._ctx, self.state) self.enterRule(localctx, 60, self.RULE_argument) try: - self.state = 370 + self.state = 371 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,41,self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 365 + self.state = 366 self.character() pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 366 + self.state = 367 self.string() pass elif la_ == 3: self.enterOuterAlt(localctx, 3) - self.state = 367 + self.state = 368 self.register() pass elif la_ == 4: self.enterOuterAlt(localctx, 4) - self.state = 368 + self.state = 369 self.addr_expr() pass elif la_ == 5: self.enterOuterAlt(localctx, 5) - self.state = 369 + self.state = 370 self.byte_expr() pass @@ -2693,13 +2699,13 @@ def byte_expr(self): self.enterRule(localctx, 62, self.RULE_byte_expr) try: self.enterOuterAlt(localctx, 1) - self.state = 372 - self.byte_specifier() self.state = 373 - self.match(AsmParser.OPEN_PAREN) + self.byte_specifier() self.state = 374 - self.addr_expr() + self.match(AsmParser.OPEN_PAREN) self.state = 375 + self.addr_expr() + self.state = 376 self.match(AsmParser.CLOSE_PAREN) except RecognitionException as re: localctx.exception = re @@ -2747,15 +2753,15 @@ def addr_expr(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 377 + self.state = 378 self.first_term() - self.state = 381 + self.state = 382 self._errHandler.sync(self) _la = self._input.LA(1) - while _la==23 or _la==24: - self.state = 378 + while _la==22 or _la==23: + self.state = 379 self.add_term() - self.state = 383 + self.state = 384 self._errHandler.sync(self) _la = self._input.LA(1) @@ -2804,20 +2810,20 @@ def first_term(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 385 + self.state = 386 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==23 or _la==24: - self.state = 384 + if _la==22 or _la==23: + self.state = 385 _la = self._input.LA(1) - if not(_la==23 or _la==24): + if not(_la==22 or _la==23): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) self.consume() - self.state = 387 + self.state = 388 self.term() except RecognitionException as re: localctx.exception = re @@ -2864,14 +2870,14 @@ def add_term(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 389 + self.state = 390 _la = self._input.LA(1) - if not(_la==23 or _la==24): + if not(_la==22 or _la==23): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) self.consume() - self.state = 390 + self.state = 391 self.term() except RecognitionException as re: localctx.exception = re @@ -2914,17 +2920,17 @@ def term(self): localctx = AsmParser.TermContext(self, self._ctx, self.state) self.enterRule(localctx, 70, self.RULE_term) try: - self.state = 394 + self.state = 395 self._errHandler.sync(self) token = self._input.LA(1) if token in [35, 36, 37]: self.enterOuterAlt(localctx, 1) - self.state = 392 + self.state = 393 self.number() pass - elif token in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 33, 34]: + elif token in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 33, 34]: self.enterOuterAlt(localctx, 2) - self.state = 393 + self.state = 394 self.label() pass else: @@ -2968,7 +2974,7 @@ def byte_specifier(self): self.enterRule(localctx, 72, self.RULE_byte_specifier) try: self.enterOuterAlt(localctx, 1) - self.state = 396 + self.state = 397 self.name() except RecognitionException as re: localctx.exception = re @@ -3008,7 +3014,7 @@ def label(self): self.enterRule(localctx, 74, self.RULE_label) try: self.enterOuterAlt(localctx, 1) - self.state = 398 + self.state = 399 self.name() except RecognitionException as re: localctx.exception = re @@ -3047,7 +3053,7 @@ def instruction(self): self.enterRule(localctx, 76, self.RULE_instruction) try: self.enterOuterAlt(localctx, 1) - self.state = 400 + self.state = 401 self.match(AsmParser.WORD) except RecognitionException as re: localctx.exception = re @@ -3086,7 +3092,7 @@ def string(self): self.enterRule(localctx, 78, self.RULE_string) try: self.enterOuterAlt(localctx, 1) - self.state = 402 + self.state = 403 self.match(AsmParser.STRING) except RecognitionException as re: localctx.exception = re @@ -3125,7 +3131,7 @@ def register(self): self.enterRule(localctx, 80, self.RULE_register) try: self.enterOuterAlt(localctx, 1) - self.state = 404 + self.state = 405 self.match(AsmParser.REGISTER) except RecognitionException as re: localctx.exception = re @@ -3164,7 +3170,7 @@ def character(self): self.enterRule(localctx, 82, self.RULE_character) try: self.enterOuterAlt(localctx, 1) - self.state = 406 + self.state = 407 self.match(AsmParser.CHAR) except RecognitionException as re: localctx.exception = re @@ -3210,7 +3216,7 @@ def number(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 408 + self.state = 409 _la = self._input.LA(1) if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 240518168576) != 0)): self._errHandler.recoverInline(self) @@ -3257,9 +3263,6 @@ def Ext(self): def File(self): return self.getToken(AsmParser.File, 0) - def Weak(self): - return self.getToken(AsmParser.Weak, 0) - def Fi(self): return self.getToken(AsmParser.Fi, 0) @@ -3318,9 +3321,9 @@ def name(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 410 + self.state = 411 _la = self._input.LA(1) - if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 25771900926) != 0)): + if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 25770852350) != 0)): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) diff --git a/cocas/assembler/generated/MacroLexer.py b/cocas/assembler/generated/MacroLexer.py index 6a773f31..e82292ac 100644 --- a/cocas/assembler/generated/MacroLexer.py +++ b/cocas/assembler/generated/MacroLexer.py @@ -46,24 +46,24 @@ def serializedATN(): 0,0,76,79,1,0,0,0,77,75,1,0,0,0,77,78,1,0,0,0,78,80,1,0,0,0,79,77, 1,0,0,0,80,81,6,4,0,0,81,10,1,0,0,0,82,83,5,42,0,0,83,12,1,0,0,0, 84,85,5,44,0,0,85,14,1,0,0,0,86,92,7,2,0,0,87,88,5,58,0,0,88,92, - 5,62,0,0,89,90,5,126,0,0,90,92,5,62,0,0,91,86,1,0,0,0,91,87,1,0, - 0,0,91,89,1,0,0,0,92,16,1,0,0,0,93,94,5,63,0,0,94,18,1,0,0,0,95, - 105,5,34,0,0,96,98,8,3,0,0,97,96,1,0,0,0,98,99,1,0,0,0,99,97,1,0, - 0,0,99,100,1,0,0,0,100,104,1,0,0,0,101,102,5,92,0,0,102,104,9,0, - 0,0,103,97,1,0,0,0,103,101,1,0,0,0,104,107,1,0,0,0,105,103,1,0,0, - 0,105,106,1,0,0,0,106,108,1,0,0,0,107,105,1,0,0,0,108,109,5,34,0, - 0,109,20,1,0,0,0,110,120,5,39,0,0,111,113,8,4,0,0,112,111,1,0,0, - 0,113,114,1,0,0,0,114,112,1,0,0,0,114,115,1,0,0,0,115,119,1,0,0, - 0,116,117,5,92,0,0,117,119,9,0,0,0,118,112,1,0,0,0,118,116,1,0,0, - 0,119,122,1,0,0,0,120,118,1,0,0,0,120,121,1,0,0,0,121,123,1,0,0, - 0,122,120,1,0,0,0,123,124,5,39,0,0,124,22,1,0,0,0,125,129,7,5,0, - 0,126,128,7,6,0,0,127,126,1,0,0,0,128,131,1,0,0,0,129,127,1,0,0, - 0,129,130,1,0,0,0,130,24,1,0,0,0,131,129,1,0,0,0,132,133,7,7,0,0, - 133,26,1,0,0,0,134,135,5,47,0,0,135,28,1,0,0,0,136,137,5,39,0,0, - 137,30,1,0,0,0,138,139,5,36,0,0,139,32,1,0,0,0,140,142,7,8,0,0,141, - 140,1,0,0,0,142,143,1,0,0,0,143,141,1,0,0,0,143,144,1,0,0,0,144, - 34,1,0,0,0,16,0,44,55,59,66,69,77,91,99,103,105,114,118,120,129, - 143,1,6,0,0 + 5,62,0,0,89,90,5,63,0,0,90,92,5,62,0,0,91,86,1,0,0,0,91,87,1,0,0, + 0,91,89,1,0,0,0,92,16,1,0,0,0,93,94,5,63,0,0,94,18,1,0,0,0,95,105, + 5,34,0,0,96,98,8,3,0,0,97,96,1,0,0,0,98,99,1,0,0,0,99,97,1,0,0,0, + 99,100,1,0,0,0,100,104,1,0,0,0,101,102,5,92,0,0,102,104,9,0,0,0, + 103,97,1,0,0,0,103,101,1,0,0,0,104,107,1,0,0,0,105,103,1,0,0,0,105, + 106,1,0,0,0,106,108,1,0,0,0,107,105,1,0,0,0,108,109,5,34,0,0,109, + 20,1,0,0,0,110,120,5,39,0,0,111,113,8,4,0,0,112,111,1,0,0,0,113, + 114,1,0,0,0,114,112,1,0,0,0,114,115,1,0,0,0,115,119,1,0,0,0,116, + 117,5,92,0,0,117,119,9,0,0,0,118,112,1,0,0,0,118,116,1,0,0,0,119, + 122,1,0,0,0,120,118,1,0,0,0,120,121,1,0,0,0,121,123,1,0,0,0,122, + 120,1,0,0,0,123,124,5,39,0,0,124,22,1,0,0,0,125,129,7,5,0,0,126, + 128,7,6,0,0,127,126,1,0,0,0,128,131,1,0,0,0,129,127,1,0,0,0,129, + 130,1,0,0,0,130,24,1,0,0,0,131,129,1,0,0,0,132,133,7,7,0,0,133,26, + 1,0,0,0,134,135,5,47,0,0,135,28,1,0,0,0,136,137,5,39,0,0,137,30, + 1,0,0,0,138,139,5,36,0,0,139,32,1,0,0,0,140,142,7,8,0,0,141,140, + 1,0,0,0,142,143,1,0,0,0,143,141,1,0,0,0,143,144,1,0,0,0,144,34,1, + 0,0,0,16,0,44,55,59,66,69,77,91,99,103,105,114,118,120,129,143,1, + 6,0,0 ] class MacroLexer(Lexer): diff --git a/cocas/assembler/generated/MacroParser.py b/cocas/assembler/generated/MacroParser.py index bad410cc..47f4688b 100644 --- a/cocas/assembler/generated/MacroParser.py +++ b/cocas/assembler/generated/MacroParser.py @@ -10,7 +10,7 @@ def serializedATN(): return [ - 4,1,17,242,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, + 4,1,17,245,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, 6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2,13,7,13, 2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7,19,1,0, 5,0,42,8,0,10,0,12,0,45,9,0,1,0,5,0,48,8,0,10,0,12,0,51,9,0,1,0, @@ -28,76 +28,77 @@ def serializedATN(): 1,11,5,11,189,8,11,10,11,12,11,192,9,11,1,12,1,12,4,12,196,8,12, 11,12,12,12,197,1,12,1,12,1,12,4,12,203,8,12,11,12,12,12,204,1,12, 5,12,208,8,12,10,12,12,12,211,9,12,1,12,4,12,214,8,12,11,12,12,12, - 215,3,12,218,8,12,1,13,1,13,1,14,1,14,1,15,1,15,1,15,3,15,227,8, - 15,1,16,1,16,4,16,231,8,16,11,16,12,16,232,1,17,1,17,1,18,1,18,1, - 18,1,19,1,19,1,19,1,119,0,20,0,2,4,6,8,10,12,14,16,18,20,22,24,26, - 28,30,32,34,36,38,0,3,3,0,3,3,7,7,17,17,2,0,3,3,17,17,2,0,1,1,10, - 13,263,0,43,1,0,0,0,2,54,1,0,0,0,4,58,1,0,0,0,6,82,1,0,0,0,8,87, - 1,0,0,0,10,92,1,0,0,0,12,119,1,0,0,0,14,122,1,0,0,0,16,140,1,0,0, - 0,18,149,1,0,0,0,20,162,1,0,0,0,22,184,1,0,0,0,24,217,1,0,0,0,26, - 219,1,0,0,0,28,221,1,0,0,0,30,226,1,0,0,0,32,228,1,0,0,0,34,234, - 1,0,0,0,36,236,1,0,0,0,38,239,1,0,0,0,40,42,5,4,0,0,41,40,1,0,0, - 0,42,45,1,0,0,0,43,41,1,0,0,0,43,44,1,0,0,0,44,49,1,0,0,0,45,43, - 1,0,0,0,46,48,3,2,1,0,47,46,1,0,0,0,48,51,1,0,0,0,49,47,1,0,0,0, - 49,50,1,0,0,0,50,52,1,0,0,0,51,49,1,0,0,0,52,53,5,0,0,1,53,1,1,0, - 0,0,54,55,3,4,2,0,55,56,3,12,6,0,56,3,1,0,0,0,57,59,5,3,0,0,58,57, - 1,0,0,0,58,59,1,0,0,0,59,60,1,0,0,0,60,62,5,6,0,0,61,63,5,3,0,0, - 62,61,1,0,0,0,62,63,1,0,0,0,63,64,1,0,0,0,64,66,5,12,0,0,65,67,5, - 3,0,0,66,65,1,0,0,0,66,67,1,0,0,0,67,68,1,0,0,0,68,70,5,14,0,0,69, - 71,5,3,0,0,70,69,1,0,0,0,70,71,1,0,0,0,71,72,1,0,0,0,72,74,5,13, - 0,0,73,75,5,3,0,0,74,73,1,0,0,0,74,75,1,0,0,0,75,76,1,0,0,0,76,77, - 5,4,0,0,77,5,1,0,0,0,78,81,3,8,4,0,79,81,3,14,7,0,80,78,1,0,0,0, - 80,79,1,0,0,0,81,84,1,0,0,0,82,80,1,0,0,0,82,83,1,0,0,0,83,85,1, - 0,0,0,84,82,1,0,0,0,85,86,5,0,0,1,86,7,1,0,0,0,87,88,3,10,5,0,88, - 89,3,12,6,0,89,90,5,2,0,0,90,9,1,0,0,0,91,93,5,3,0,0,92,91,1,0,0, - 0,92,93,1,0,0,0,93,94,1,0,0,0,94,96,5,1,0,0,95,97,5,3,0,0,96,95, - 1,0,0,0,96,97,1,0,0,0,97,98,1,0,0,0,98,100,5,12,0,0,99,101,5,3,0, - 0,100,99,1,0,0,0,100,101,1,0,0,0,101,102,1,0,0,0,102,104,5,14,0, - 0,103,105,5,3,0,0,104,103,1,0,0,0,104,105,1,0,0,0,105,106,1,0,0, - 0,106,108,5,13,0,0,107,109,5,3,0,0,108,107,1,0,0,0,108,109,1,0,0, - 0,109,110,1,0,0,0,110,111,5,4,0,0,111,11,1,0,0,0,112,114,5,3,0,0, - 113,112,1,0,0,0,113,114,1,0,0,0,114,115,1,0,0,0,115,118,5,4,0,0, - 116,118,3,14,7,0,117,113,1,0,0,0,117,116,1,0,0,0,118,121,1,0,0,0, - 119,120,1,0,0,0,119,117,1,0,0,0,120,13,1,0,0,0,121,119,1,0,0,0,122, - 126,3,16,8,0,123,124,3,24,12,0,124,125,3,18,9,0,125,127,1,0,0,0, - 126,123,1,0,0,0,126,127,1,0,0,0,127,132,1,0,0,0,128,129,5,7,0,0, - 129,131,3,22,11,0,130,128,1,0,0,0,131,134,1,0,0,0,132,130,1,0,0, - 0,132,133,1,0,0,0,133,135,1,0,0,0,134,132,1,0,0,0,135,136,5,4,0, - 0,136,15,1,0,0,0,137,139,3,20,10,0,138,137,1,0,0,0,139,142,1,0,0, - 0,140,138,1,0,0,0,140,141,1,0,0,0,141,144,1,0,0,0,142,140,1,0,0, - 0,143,145,5,3,0,0,144,143,1,0,0,0,144,145,1,0,0,0,145,17,1,0,0,0, - 146,147,5,3,0,0,147,150,3,22,11,0,148,150,1,0,0,0,149,146,1,0,0, - 0,149,148,1,0,0,0,150,19,1,0,0,0,151,161,3,30,15,0,152,154,3,32, - 16,0,153,152,1,0,0,0,154,155,1,0,0,0,155,153,1,0,0,0,155,156,1,0, - 0,0,156,157,1,0,0,0,157,158,3,26,13,0,158,161,1,0,0,0,159,161,3, - 26,13,0,160,151,1,0,0,0,160,153,1,0,0,0,160,159,1,0,0,0,161,164, - 1,0,0,0,162,160,1,0,0,0,162,163,1,0,0,0,163,168,1,0,0,0,164,162, - 1,0,0,0,165,167,3,32,16,0,166,165,1,0,0,0,167,170,1,0,0,0,168,166, - 1,0,0,0,168,169,1,0,0,0,169,171,1,0,0,0,170,168,1,0,0,0,171,172, - 5,8,0,0,172,21,1,0,0,0,173,183,3,30,15,0,174,176,3,32,16,0,175,174, - 1,0,0,0,176,177,1,0,0,0,177,175,1,0,0,0,177,178,1,0,0,0,178,179, - 1,0,0,0,179,180,3,28,14,0,180,183,1,0,0,0,181,183,3,28,14,0,182, - 173,1,0,0,0,182,175,1,0,0,0,182,181,1,0,0,0,183,186,1,0,0,0,184, - 182,1,0,0,0,184,185,1,0,0,0,185,190,1,0,0,0,186,184,1,0,0,0,187, - 189,3,32,16,0,188,187,1,0,0,0,189,192,1,0,0,0,190,188,1,0,0,0,190, - 191,1,0,0,0,191,23,1,0,0,0,192,190,1,0,0,0,193,203,3,30,15,0,194, - 196,3,32,16,0,195,194,1,0,0,0,196,197,1,0,0,0,197,195,1,0,0,0,197, - 198,1,0,0,0,198,199,1,0,0,0,199,200,5,17,0,0,200,203,1,0,0,0,201, - 203,5,17,0,0,202,193,1,0,0,0,202,195,1,0,0,0,202,201,1,0,0,0,203, - 204,1,0,0,0,204,202,1,0,0,0,204,205,1,0,0,0,205,209,1,0,0,0,206, - 208,3,32,16,0,207,206,1,0,0,0,208,211,1,0,0,0,209,207,1,0,0,0,209, - 210,1,0,0,0,210,218,1,0,0,0,211,209,1,0,0,0,212,214,3,32,16,0,213, - 212,1,0,0,0,214,215,1,0,0,0,215,213,1,0,0,0,215,216,1,0,0,0,216, - 218,1,0,0,0,217,202,1,0,0,0,217,213,1,0,0,0,218,25,1,0,0,0,219,220, - 7,0,0,0,220,27,1,0,0,0,221,222,7,1,0,0,222,29,1,0,0,0,223,227,3, - 34,17,0,224,227,3,36,18,0,225,227,3,38,19,0,226,223,1,0,0,0,226, - 224,1,0,0,0,226,225,1,0,0,0,227,31,1,0,0,0,228,230,5,9,0,0,229,231, - 3,30,15,0,230,229,1,0,0,0,231,232,1,0,0,0,232,230,1,0,0,0,232,233, - 1,0,0,0,233,33,1,0,0,0,234,235,7,2,0,0,235,35,1,0,0,0,236,237,5, - 16,0,0,237,238,5,13,0,0,238,37,1,0,0,0,239,240,5,15,0,0,240,39,1, - 0,0,0,38,43,49,58,62,66,70,74,80,82,92,96,100,104,108,113,117,119, - 126,132,140,144,149,155,160,162,168,177,182,184,190,197,202,204, - 209,215,217,226,232 + 215,3,12,218,8,12,1,12,3,12,221,8,12,1,13,1,13,1,14,1,14,1,15,1, + 15,1,15,3,15,230,8,15,1,16,1,16,4,16,234,8,16,11,16,12,16,235,1, + 17,1,17,1,18,1,18,1,18,1,19,1,19,1,19,1,119,0,20,0,2,4,6,8,10,12, + 14,16,18,20,22,24,26,28,30,32,34,36,38,0,3,3,0,3,3,7,7,17,17,2,0, + 3,3,17,17,2,0,1,1,10,13,267,0,43,1,0,0,0,2,54,1,0,0,0,4,58,1,0,0, + 0,6,82,1,0,0,0,8,87,1,0,0,0,10,92,1,0,0,0,12,119,1,0,0,0,14,122, + 1,0,0,0,16,140,1,0,0,0,18,149,1,0,0,0,20,162,1,0,0,0,22,184,1,0, + 0,0,24,217,1,0,0,0,26,222,1,0,0,0,28,224,1,0,0,0,30,229,1,0,0,0, + 32,231,1,0,0,0,34,237,1,0,0,0,36,239,1,0,0,0,38,242,1,0,0,0,40,42, + 5,4,0,0,41,40,1,0,0,0,42,45,1,0,0,0,43,41,1,0,0,0,43,44,1,0,0,0, + 44,49,1,0,0,0,45,43,1,0,0,0,46,48,3,2,1,0,47,46,1,0,0,0,48,51,1, + 0,0,0,49,47,1,0,0,0,49,50,1,0,0,0,50,52,1,0,0,0,51,49,1,0,0,0,52, + 53,5,0,0,1,53,1,1,0,0,0,54,55,3,4,2,0,55,56,3,12,6,0,56,3,1,0,0, + 0,57,59,5,3,0,0,58,57,1,0,0,0,58,59,1,0,0,0,59,60,1,0,0,0,60,62, + 5,6,0,0,61,63,5,3,0,0,62,61,1,0,0,0,62,63,1,0,0,0,63,64,1,0,0,0, + 64,66,5,12,0,0,65,67,5,3,0,0,66,65,1,0,0,0,66,67,1,0,0,0,67,68,1, + 0,0,0,68,70,5,14,0,0,69,71,5,3,0,0,70,69,1,0,0,0,70,71,1,0,0,0,71, + 72,1,0,0,0,72,74,5,13,0,0,73,75,5,3,0,0,74,73,1,0,0,0,74,75,1,0, + 0,0,75,76,1,0,0,0,76,77,5,4,0,0,77,5,1,0,0,0,78,81,3,8,4,0,79,81, + 3,14,7,0,80,78,1,0,0,0,80,79,1,0,0,0,81,84,1,0,0,0,82,80,1,0,0,0, + 82,83,1,0,0,0,83,85,1,0,0,0,84,82,1,0,0,0,85,86,5,0,0,1,86,7,1,0, + 0,0,87,88,3,10,5,0,88,89,3,12,6,0,89,90,5,2,0,0,90,9,1,0,0,0,91, + 93,5,3,0,0,92,91,1,0,0,0,92,93,1,0,0,0,93,94,1,0,0,0,94,96,5,1,0, + 0,95,97,5,3,0,0,96,95,1,0,0,0,96,97,1,0,0,0,97,98,1,0,0,0,98,100, + 5,12,0,0,99,101,5,3,0,0,100,99,1,0,0,0,100,101,1,0,0,0,101,102,1, + 0,0,0,102,104,5,14,0,0,103,105,5,3,0,0,104,103,1,0,0,0,104,105,1, + 0,0,0,105,106,1,0,0,0,106,108,5,13,0,0,107,109,5,3,0,0,108,107,1, + 0,0,0,108,109,1,0,0,0,109,110,1,0,0,0,110,111,5,4,0,0,111,11,1,0, + 0,0,112,114,5,3,0,0,113,112,1,0,0,0,113,114,1,0,0,0,114,115,1,0, + 0,0,115,118,5,4,0,0,116,118,3,14,7,0,117,113,1,0,0,0,117,116,1,0, + 0,0,118,121,1,0,0,0,119,120,1,0,0,0,119,117,1,0,0,0,120,13,1,0,0, + 0,121,119,1,0,0,0,122,126,3,16,8,0,123,124,3,24,12,0,124,125,3,18, + 9,0,125,127,1,0,0,0,126,123,1,0,0,0,126,127,1,0,0,0,127,132,1,0, + 0,0,128,129,5,7,0,0,129,131,3,22,11,0,130,128,1,0,0,0,131,134,1, + 0,0,0,132,130,1,0,0,0,132,133,1,0,0,0,133,135,1,0,0,0,134,132,1, + 0,0,0,135,136,5,4,0,0,136,15,1,0,0,0,137,139,3,20,10,0,138,137,1, + 0,0,0,139,142,1,0,0,0,140,138,1,0,0,0,140,141,1,0,0,0,141,144,1, + 0,0,0,142,140,1,0,0,0,143,145,5,3,0,0,144,143,1,0,0,0,144,145,1, + 0,0,0,145,17,1,0,0,0,146,147,5,3,0,0,147,150,3,22,11,0,148,150,1, + 0,0,0,149,146,1,0,0,0,149,148,1,0,0,0,150,19,1,0,0,0,151,161,3,30, + 15,0,152,154,3,32,16,0,153,152,1,0,0,0,154,155,1,0,0,0,155,153,1, + 0,0,0,155,156,1,0,0,0,156,157,1,0,0,0,157,158,3,26,13,0,158,161, + 1,0,0,0,159,161,3,26,13,0,160,151,1,0,0,0,160,153,1,0,0,0,160,159, + 1,0,0,0,161,164,1,0,0,0,162,160,1,0,0,0,162,163,1,0,0,0,163,168, + 1,0,0,0,164,162,1,0,0,0,165,167,3,32,16,0,166,165,1,0,0,0,167,170, + 1,0,0,0,168,166,1,0,0,0,168,169,1,0,0,0,169,171,1,0,0,0,170,168, + 1,0,0,0,171,172,5,8,0,0,172,21,1,0,0,0,173,183,3,30,15,0,174,176, + 3,32,16,0,175,174,1,0,0,0,176,177,1,0,0,0,177,175,1,0,0,0,177,178, + 1,0,0,0,178,179,1,0,0,0,179,180,3,28,14,0,180,183,1,0,0,0,181,183, + 3,28,14,0,182,173,1,0,0,0,182,175,1,0,0,0,182,181,1,0,0,0,183,186, + 1,0,0,0,184,182,1,0,0,0,184,185,1,0,0,0,185,190,1,0,0,0,186,184, + 1,0,0,0,187,189,3,32,16,0,188,187,1,0,0,0,189,192,1,0,0,0,190,188, + 1,0,0,0,190,191,1,0,0,0,191,23,1,0,0,0,192,190,1,0,0,0,193,203,3, + 30,15,0,194,196,3,32,16,0,195,194,1,0,0,0,196,197,1,0,0,0,197,195, + 1,0,0,0,197,198,1,0,0,0,198,199,1,0,0,0,199,200,5,17,0,0,200,203, + 1,0,0,0,201,203,5,17,0,0,202,193,1,0,0,0,202,195,1,0,0,0,202,201, + 1,0,0,0,203,204,1,0,0,0,204,202,1,0,0,0,204,205,1,0,0,0,205,209, + 1,0,0,0,206,208,3,32,16,0,207,206,1,0,0,0,208,211,1,0,0,0,209,207, + 1,0,0,0,209,210,1,0,0,0,210,218,1,0,0,0,211,209,1,0,0,0,212,214, + 3,32,16,0,213,212,1,0,0,0,214,215,1,0,0,0,215,213,1,0,0,0,215,216, + 1,0,0,0,216,218,1,0,0,0,217,202,1,0,0,0,217,213,1,0,0,0,218,220, + 1,0,0,0,219,221,5,9,0,0,220,219,1,0,0,0,220,221,1,0,0,0,221,25,1, + 0,0,0,222,223,7,0,0,0,223,27,1,0,0,0,224,225,7,1,0,0,225,29,1,0, + 0,0,226,230,3,34,17,0,227,230,3,36,18,0,228,230,3,38,19,0,229,226, + 1,0,0,0,229,227,1,0,0,0,229,228,1,0,0,0,230,31,1,0,0,0,231,233,5, + 9,0,0,232,234,3,30,15,0,233,232,1,0,0,0,234,235,1,0,0,0,235,233, + 1,0,0,0,235,236,1,0,0,0,236,33,1,0,0,0,237,238,7,2,0,0,238,35,1, + 0,0,0,239,240,5,16,0,0,240,241,5,13,0,0,241,37,1,0,0,0,242,243,5, + 15,0,0,243,39,1,0,0,0,39,43,49,58,62,66,70,74,80,82,92,96,100,104, + 108,113,117,119,126,132,140,144,149,155,160,162,168,177,182,184, + 190,197,202,204,209,215,217,220,229,235 ] class MacroParser ( Parser ): @@ -1149,6 +1150,9 @@ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): super().__init__(parent, invokingState) self.parser = parser + def QUESTION_MARK(self): + return self.getToken(MacroParser.QUESTION_MARK, 0) + def macro_piece(self, i:int=None): if i is None: return self.getTypedRuleContexts(MacroParser.Macro_pieceContext) @@ -1187,11 +1191,11 @@ def instruction(self): self.enterRule(localctx, 24, self.RULE_instruction) self._la = 0 # Token type try: + self.enterOuterAlt(localctx, 1) self.state = 217 self._errHandler.sync(self) la_ = self._interp.adaptivePredict(self._input,35,self._ctx) if la_ == 1: - self.enterOuterAlt(localctx, 1) self.state = 202 self._errHandler.sync(self) _alt = 1 @@ -1236,33 +1240,43 @@ def instruction(self): self.state = 209 self._errHandler.sync(self) - _la = self._input.LA(1) - while _la==9: - self.state = 206 - self.macro_variable() + _alt = self._interp.adaptivePredict(self._input,33,self._ctx) + while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: + if _alt==1: + self.state = 206 + self.macro_variable() self.state = 211 self._errHandler.sync(self) - _la = self._input.LA(1) + _alt = self._interp.adaptivePredict(self._input,33,self._ctx) pass elif la_ == 2: - self.enterOuterAlt(localctx, 2) self.state = 213 self._errHandler.sync(self) - _la = self._input.LA(1) - while True: - self.state = 212 - self.macro_variable() + _alt = 1 + while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: + if _alt == 1: + self.state = 212 + self.macro_variable() + + else: + raise NoViableAltException(self) self.state = 215 self._errHandler.sync(self) - _la = self._input.LA(1) - if not (_la==9): - break + _alt = self._interp.adaptivePredict(self._input,34,self._ctx) pass + self.state = 220 + self._errHandler.sync(self) + _la = self._input.LA(1) + if _la==9: + self.state = 219 + self.match(MacroParser.QUESTION_MARK) + + except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -1307,7 +1321,7 @@ def l_sep(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 219 + self.state = 222 _la = self._input.LA(1) if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 131208) != 0)): self._errHandler.recoverInline(self) @@ -1355,7 +1369,7 @@ def p_sep(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 221 + self.state = 224 _la = self._input.LA(1) if not(_la==3 or _la==17): self._errHandler.recoverInline(self) @@ -1407,22 +1421,22 @@ def macro_piece(self): localctx = MacroParser.Macro_pieceContext(self, self._ctx, self.state) self.enterRule(localctx, 30, self.RULE_macro_piece) try: - self.state = 226 + self.state = 229 self._errHandler.sync(self) token = self._input.LA(1) if token in [1, 10, 11, 12, 13]: self.enterOuterAlt(localctx, 1) - self.state = 223 + self.state = 226 self.macro_text() pass elif token in [16]: self.enterOuterAlt(localctx, 2) - self.state = 224 + self.state = 227 self.macro_param() pass elif token in [15]: self.enterOuterAlt(localctx, 3) - self.state = 225 + self.state = 228 self.macro_nonce() pass else: @@ -1473,15 +1487,15 @@ def macro_variable(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 228 + self.state = 231 self.match(MacroParser.QUESTION_MARK) - self.state = 230 + self.state = 233 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 229 + self.state = 232 self.macro_piece() - self.state = 232 + self.state = 235 self._errHandler.sync(self) _la = self._input.LA(1) if not ((((_la) & ~0x3f) == 0 and ((1 << _la) & 113666) != 0)): @@ -1537,7 +1551,7 @@ def macro_text(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 234 + self.state = 237 _la = self._input.LA(1) if not((((_la) & ~0x3f) == 0 and ((1 << _la) & 15362) != 0)): self._errHandler.recoverInline(self) @@ -1584,9 +1598,9 @@ def macro_param(self): self.enterRule(localctx, 36, self.RULE_macro_param) try: self.enterOuterAlt(localctx, 1) - self.state = 236 + self.state = 239 self.match(MacroParser.DOLLAR_SIGN) - self.state = 237 + self.state = 240 self.match(MacroParser.DIGIT) except RecognitionException as re: localctx.exception = re @@ -1625,7 +1639,7 @@ def macro_nonce(self): self.enterRule(localctx, 38, self.RULE_macro_nonce) try: self.enterOuterAlt(localctx, 1) - self.state = 239 + self.state = 242 self.match(MacroParser.APOSTROPHE) except RecognitionException as re: localctx.exception = re diff --git a/cocas/assembler/grammar/AsmLexer.g4 b/cocas/assembler/grammar/AsmLexer.g4 index 1f33677b..6ae6c8d3 100644 --- a/cocas/assembler/grammar/AsmLexer.g4 +++ b/cocas/assembler/grammar/AsmLexer.g4 @@ -8,7 +8,6 @@ Else : 'else' ; End : 'end' ; Ext : 'ext' ; File : 'file' ; -Weak : 'weak' ; Fi : 'fi' ; If : 'if' ; Is : 'is' ; @@ -28,7 +27,8 @@ MINUS : '-' ; COLON : ':' ; ANGLE_BRACKET : '>' ; COLON_ANGLE : ':>' ; -TILDE_ANGLE : '~>' ; +QUESTION_ANGLE : '?>' ; +QUESTION : '?' ; OPEN_PAREN : '(' ; CLOSE_PAREN : ')' ; LINE_MARK_MARKER: '-|'; diff --git a/cocas/assembler/grammar/AsmParser.g4 b/cocas/assembler/grammar/AsmParser.g4 index 09ca3ce0..ed8cb163 100644 --- a/cocas/assembler/grammar/AsmParser.g4 +++ b/cocas/assembler/grammar/AsmParser.g4 @@ -59,16 +59,16 @@ continue_statement : Continue NEWLINE+ ; top_line: line; ext_type - : Ext # globalExtType - | File # fileExtType - | Weak # weakExtType + : Ext # globalExtType + | File # fileExtType + | Ext QUESTION # weakExtType ; label_suffix : COLON # localLabelSuffix | ANGLE_BRACKET # globalLabelSuffix | COLON_ANGLE # fileLabelSuffix - | TILDE_ANGLE # weakLabelSuffix + | QUESTION_ANGLE # weakLabelSuffix ; line @@ -129,7 +129,6 @@ name | End | Ext | File - | Weak | Fi | If | Is diff --git a/cocas/assembler/grammar/Macro.g4 b/cocas/assembler/grammar/Macro.g4 index d1ceada2..5d67172f 100644 --- a/cocas/assembler/grammar/Macro.g4 +++ b/cocas/assembler/grammar/Macro.g4 @@ -15,13 +15,13 @@ first_param : WS param | ; label : (macro_piece | macro_variable+ l_sep | l_sep)* macro_variable* LABEL_END ; param : (macro_piece | macro_variable+ p_sep | p_sep)* macro_variable* ; -instruction : (macro_piece | macro_variable+ OTHER | OTHER)+ macro_variable* | macro_variable+ ; +instruction : ((macro_piece | macro_variable+ OTHER | OTHER)+ macro_variable* | macro_variable+) QUESTION_MARK? ; l_sep : OTHER | WS | COMMA ; p_sep : OTHER | WS ; macro_piece : macro_text | macro_param | macro_nonce ; macro_variable : QUESTION_MARK macro_piece+ ; -macro_text : Macro | NAME | DIGIT | STRING | CHAR ; +macro_text : Macro | NAME | DIGIT | STRING | CHAR; macro_param : DOLLAR_SIGN DIGIT ; macro_nonce : APOSTROPHE ; @@ -34,12 +34,12 @@ COMMENT : '#'~[\n]* -> skip ; ASTERISK : '*' ; COMMA : ',' ; -LABEL_END : ':' | '>' | ':>' | '~>' ; +LABEL_END : ':' | '>' | ':>' | '?>' ; QUESTION_MARK : '?' ; STRING: '"' (~[\\"\n]+ | '\\' .)* '"' ; CHAR : '\'' (~[\\'\n]+ | '\\' .)* '\'' ; -NAME : [_a-zA-Z][_a-zA-Z0-9.]* ; +NAME : [_a-zA-Z][_a-zA-Z0-9.]*; DIGIT : [0-9] ; SLASH : '/' ; From d3c0f8731f6da8f6cd2a355b9c91752a21601869 Mon Sep 17 00:00:00 2001 From: Andrey Eliseev Date: Mon, 9 Mar 2026 00:21:41 +0700 Subject: [PATCH 33/42] [cocas] Merge sections at AST level during assembly This is much less error-prone than the previous approach. It also allows usage of label declarations (including section-local labels) across different sub-sections. --- cocas/assembler/code_block.py | 28 ++++++++++++++++++---------- cocas/assembler/object_generator.py | 20 +++++++++++++++----- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/cocas/assembler/code_block.py b/cocas/assembler/code_block.py index 4fe2712a..fcbd4627 100644 --- a/cocas/assembler/code_block.py +++ b/cocas/assembler/code_block.py @@ -171,16 +171,8 @@ def assemble_continue_statement(self, line: ContinueStatementNode, _): @dataclass class Section(CodeBlock): - def __init__(self, sn: SectionNode, target_instructions: TargetInstructions): - if isinstance(sn, AbsoluteSectionNode): - self.name = '$abs' - address = sn.address - elif isinstance(sn, RelocatableSectionNode): - self.name = sn.name - address = 0 - else: - raise Exception('Section is neither abs nor rel, can it happen? It was elif instead of else here') - super().__init__(address, sn.lines, target_instructions) + def __init__(self, address: int, lines: list, target_instructions: TargetInstructions): + super().__init__(address, lines, target_instructions) def to_object_section_record(self, labels: dict[str, int], templates: dict[str, dict[str, int]]): entries = { @@ -192,3 +184,19 @@ def to_object_section_record(self, labels: dict[str, int], templates: dict[str, for seg in self.segments: seg.fill(out, self, labels, templates) return out + +@dataclass +class AbsoluteSection(Section): + def __init__(self, sn: SectionNode, target_instructions: TargetInstructions): + self.name = '$abs' + address = sn.address + super().__init__(address, sn.lines, target_instructions) + +@dataclass +class RelocatableSection(Section): + def __init__(self, name: str, nodes: list[SectionNode], target_instructions: TargetInstructions): + if not nodes: + raise ValueError("Node list must not be empty.") + self.name = name + address = 0 + super().__init__(address, [line for node in nodes for line in node.lines], target_instructions) diff --git a/cocas/assembler/object_generator.py b/cocas/assembler/object_generator.py index b900ce60..bb9d2702 100644 --- a/cocas/assembler/object_generator.py +++ b/cocas/assembler/object_generator.py @@ -1,8 +1,9 @@ import itertools +from collections import defaultdict from dataclasses import dataclass from typing import Any, Union -from cocas.object_module import CodeLocation, ObjectModule, Linkage, concat_rsects +from cocas.object_module import CodeLocation, ObjectModule, Linkage from .ast_nodes import ( InstructionNode, @@ -14,7 +15,7 @@ TemplateFieldNode, TemplateSectionNode, ) -from .code_block import Section +from .code_block import AbsoluteSection, RelocatableSection from .exceptions import AssemblerException, AssemblerExceptionTag from .targets import IVaryingLengthSegment, TargetInstructions @@ -102,6 +103,13 @@ def label_or_template(label: Union[LabelNode, Any], template_fields: dict[str, d return label +def group_rsects(nodes: list[RelocatableSectionNode]) -> dict[str, list[RelocatableSectionNode]]: + grouped = defaultdict(list) + for node in nodes: + grouped[node.name].append(node) + return grouped + + def generate_object_module(pn: ProgramNode, target_instructions: TargetInstructions) -> ObjectModule: templates = [Template(t, target_instructions) for t in pn.template_sections] template_fields = dict([(t.name, t.labels) for t in templates]) @@ -130,8 +138,10 @@ def generate_object_module(pn: ProgramNode, target_instructions: TargetInstructi arg.add_terms = list( map(lambda x: label_or_template(x, template_fields), arg.add_terms)) - asects = sorted((Section(asect, target_instructions) for asect in pn.absolute_sections), key=lambda s: s.address) - rsects = [Section(rsect, target_instructions) for rsect in pn.relocatable_sections] + asects = [AbsoluteSection(asect, target_instructions) + for asect in sorted(pn.absolute_sections, key=lambda s: s.address)] + rsects = [RelocatableSection(name, nodes, target_instructions) + for name, nodes in group_rsects(pn.relocatable_sections).items()] shared_externals = dict(map(lambda x: (x.label.name, x.linkage), pn.shared_externals)) for i in itertools.chain(asects, rsects): @@ -151,7 +161,7 @@ def generate_object_module(pn: ProgramNode, target_instructions: TargetInstructi update_varying_length([rsect], all_labels, template_fields) asect_records = [asect.to_object_section_record(all_labels, template_fields) for asect in asects] - rsect_records = concat_rsects(map(lambda x: x.to_object_section_record(all_labels, template_fields), rsects)) + rsect_records = [rsect.to_object_section_record(all_labels, template_fields) for rsect in rsects] for section in itertools.chain(asect_records, rsect_records): for label in section.entries.keys(): From 00d424ae69935ffc14aa617dfe86c06d3e90f3c5 Mon Sep 17 00:00:00 2001 From: Andrey Eliseev Date: Mon, 9 Mar 2026 01:31:49 +0700 Subject: [PATCH 34/42] [cocas] Improve missing and duplicate label errors --- cocas/assembler/code_block.py | 6 --- cocas/assembler/object_generator.py | 66 ++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 26 deletions(-) diff --git a/cocas/assembler/code_block.py b/cocas/assembler/code_block.py index fcbd4627..b9611cde 100644 --- a/cocas/assembler/code_block.py +++ b/cocas/assembler/code_block.py @@ -69,12 +69,6 @@ def assemble_lines(self, lines: list, temp_storage): def assemble_label_declaration(self, line: LabelDeclarationNode, __): label_name = line.label.name - if (label_name in self.labels or - label_name in self.ents or - label_name in self.exts): - raise AssemblerException(AssemblerExceptionTag.ASM, line.location.file, line.location.line, - f'Duplicate label "{label_name}" declaration') - if line.external: self.exts[label_name] = line.linkage elif line.linkage == Linkage.WEAK_GLOBAL: diff --git a/cocas/assembler/object_generator.py b/cocas/assembler/object_generator.py index bb9d2702..24a29f9a 100644 --- a/cocas/assembler/object_generator.py +++ b/cocas/assembler/object_generator.py @@ -6,6 +6,8 @@ from cocas.object_module import CodeLocation, ObjectModule, Linkage from .ast_nodes import ( + AbsoluteSectionNode, + RelocatableSectionNode, InstructionNode, LabelDeclarationNode, LabelNode, @@ -33,7 +35,7 @@ def __init__(self, sn: TemplateSectionNode, target_instructions: TargetInstructi label_name = line.label.name if label_name in self.labels: raise AssemblerException(AssemblerExceptionTag.TPLATE, line.location.file, line.location.line, - f'Duplicate label "{label_name}" declaration') + f'Duplicate definition of label "{label_name}" in template') if line.external: raise AssemblerException(AssemblerExceptionTag.TPLATE, line.location.file, line.location.line, 'External labels not allowed in templates') @@ -113,7 +115,11 @@ def group_rsects(nodes: list[RelocatableSectionNode]) -> dict[str, list[Relocata def generate_object_module(pn: ProgramNode, target_instructions: TargetInstructions) -> ObjectModule: templates = [Template(t, target_instructions) for t in pn.template_sections] template_fields = dict([(t.name, t.labels) for t in templates]) - undefined_file_locals: dict[str, CodeLocation] = dict() + + section_labels: dict[Union[str, int], dict[str, CodeLocation]] = defaultdict(dict) + global_labels: dict[str, CodeLocation] = dict() + file_local_labels: dict[str, CodeLocation] = dict() + file_local_exts: dict[str, CodeLocation] = dict() # LabelDeclarationNode # InstructionNode @@ -123,21 +129,56 @@ def generate_object_module(pn: ProgramNode, target_instructions: TargetInstructi # BreakStatementNode # ContinueStatementNode for i in pn.absolute_sections + pn.relocatable_sections: + section_key: Union[str, int] + match i: + case AbsoluteSectionNode(): + section_key = i.address + case RelocatableSectionNode(): + section_key = i.name for line in i.lines: if isinstance(line, LabelDeclarationNode): if '.' in line.label.name: prefix = line.label.name.split('.')[0] if prefix in template_fields: raise AssemblerException(AssemblerExceptionTag.ASM, line.location.file, line.location.line, - f"Label {line.label.name} conflicts with template {prefix}") - if line.external and line.linkage == Linkage.FILE_LOCAL: - undefined_file_locals[line.label.name] = line.location + f'Label "{line.label.name}" conflicts with template "{prefix}"') + + if line.label.name in section_labels[section_key]: + first_line = section_labels[section_key][line.label.name].line + raise AssemblerException(AssemblerExceptionTag.ASM, line.location.file, line.location.line, + (f'Duplicate definition of label "{line.label.name}" in section\n' + f'First definition at line {first_line}')) + + section_labels[section_key][line.label.name] = line.location + match line.linkage, line.external: + case Linkage.FILE_LOCAL, True: + file_local_exts[line.label.name] = line.location + case Linkage.GLOBAL, False: + if line.label.name in global_labels: + first_line = global_labels[line.label.name].line + raise AssemblerException(AssemblerExceptionTag.ASM, line.location.file, line.location.line, + (f'Duplicate definition of global label "{line.label.name}" in file\n' + f'First definition at line {first_line}')) + global_labels[line.label.name] = line.location + case Linkage.FILE_LOCAL, False: + if line.label.name in file_local_labels: + first_line = file_local_labels[line.label.name].line + raise AssemblerException(AssemblerExceptionTag.ASM, line.location.file, line.location.line, + (f'Duplicate definition of file-local label "{line.label.name}" in file\n' + f'First definition at line {first_line}')) + file_local_labels[line.label.name] = line.location + elif isinstance(line, InstructionNode): for arg in line.arguments: if isinstance(arg, RelocatableExpressionNode): arg.add_terms = list( map(lambda x: label_or_template(x, template_fields), arg.add_terms)) + for name in set(file_local_exts) - set(file_local_labels): + location = file_local_exts[name] + raise AssemblerException(AssemblerExceptionTag.ASM, location.file, location.line, + f'Undefined file-local label "{name}"') + asects = [AbsoluteSection(asect, target_instructions) for asect in sorted(pn.absolute_sections, key=lambda s: s.address)] rsects = [RelocatableSection(name, nodes, target_instructions) @@ -146,11 +187,6 @@ def generate_object_module(pn: ProgramNode, target_instructions: TargetInstructi shared_externals = dict(map(lambda x: (x.label.name, x.linkage), pn.shared_externals)) for i in itertools.chain(asects, rsects): i.exts |= shared_externals - undefined_file_locals |= { - decl.label.name: decl.location - for decl in pn.shared_externals - if decl.linkage == Linkage.FILE_LOCAL - } for _ in pn.top_instructions: pass # do something @@ -162,15 +198,5 @@ def generate_object_module(pn: ProgramNode, target_instructions: TargetInstructi asect_records = [asect.to_object_section_record(all_labels, template_fields) for asect in asects] rsect_records = [rsect.to_object_section_record(all_labels, template_fields) for rsect in rsects] - - for section in itertools.chain(asect_records, rsect_records): - for label in section.entries.keys(): - if label.name in undefined_file_locals: - undefined_file_locals.pop(label.name) - - if undefined_file_locals: - label, location = next(iter(undefined_file_locals.items())) - raise AssemblerException(AssemblerExceptionTag.ASM, location.file, location.line, - f'Undefined file-local label: {label}') return ObjectModule(asect_records, rsect_records) From 08c356253f7779b4f98b815b51f32dfafd31b016 Mon Sep 17 00:00:00 2001 From: Andrey Eliseev Date: Mon, 9 Mar 2026 10:28:52 +0700 Subject: [PATCH 35/42] [cocas] Move label validation into a separate function --- cocas/assembler/object_generator.py | 104 +++++++++++++++------------- 1 file changed, 54 insertions(+), 50 deletions(-) diff --git a/cocas/assembler/object_generator.py b/cocas/assembler/object_generator.py index 24a29f9a..ac7a320e 100644 --- a/cocas/assembler/object_generator.py +++ b/cocas/assembler/object_generator.py @@ -6,6 +6,7 @@ from cocas.object_module import CodeLocation, ObjectModule, Linkage from .ast_nodes import ( + SectionNode, AbsoluteSectionNode, RelocatableSectionNode, InstructionNode, @@ -105,6 +106,17 @@ def label_or_template(label: Union[LabelNode, Any], template_fields: dict[str, d return label +def apply_templates(section_nodes: list[SectionNode], template_fields: dict[str, dict[str,int]]): + for i in section_nodes: + for line in i.lines: + if not isinstance(line, InstructionNode): + continue + for arg in line.arguments: + if not isinstance(arg, RelocatableExpressionNode): + continue + arg.add_terms = list(map(lambda x: label_or_template(x, template_fields), arg.add_terms)) + + def group_rsects(nodes: list[RelocatableSectionNode]) -> dict[str, list[RelocatableSectionNode]]: grouped = defaultdict(list) for node in nodes: @@ -112,23 +124,13 @@ def group_rsects(nodes: list[RelocatableSectionNode]) -> dict[str, list[Relocata return grouped -def generate_object_module(pn: ProgramNode, target_instructions: TargetInstructions) -> ObjectModule: - templates = [Template(t, target_instructions) for t in pn.template_sections] - template_fields = dict([(t.name, t.labels) for t in templates]) - +def validate_labels(section_nodes: list[SectionNode], template_fields: set[str]) : section_labels: dict[Union[str, int], dict[str, CodeLocation]] = defaultdict(dict) global_labels: dict[str, CodeLocation] = dict() file_local_labels: dict[str, CodeLocation] = dict() file_local_exts: dict[str, CodeLocation] = dict() - # LabelDeclarationNode - # InstructionNode - # ConditionalStatementNode - # WhileLoopNode - # UntilLoopNode - # BreakStatementNode - # ContinueStatementNode - for i in pn.absolute_sections + pn.relocatable_sections: + for i in section_nodes: section_key: Union[str, int] match i: case AbsoluteSectionNode(): @@ -136,55 +138,57 @@ def generate_object_module(pn: ProgramNode, target_instructions: TargetInstructi case RelocatableSectionNode(): section_key = i.name for line in i.lines: - if isinstance(line, LabelDeclarationNode): - if '.' in line.label.name: - prefix = line.label.name.split('.')[0] - if prefix in template_fields: - raise AssemblerException(AssemblerExceptionTag.ASM, line.location.file, line.location.line, - f'Label "{line.label.name}" conflicts with template "{prefix}"') - - if line.label.name in section_labels[section_key]: - first_line = section_labels[section_key][line.label.name].line + if not isinstance(line, LabelDeclarationNode): + continue + if '.' in line.label.name: + prefix = line.label.name.split('.')[0] + if prefix in template_fields: raise AssemblerException(AssemblerExceptionTag.ASM, line.location.file, line.location.line, - (f'Duplicate definition of label "{line.label.name}" in section\n' - f'First definition at line {first_line}')) - - section_labels[section_key][line.label.name] = line.location - match line.linkage, line.external: - case Linkage.FILE_LOCAL, True: - file_local_exts[line.label.name] = line.location - case Linkage.GLOBAL, False: - if line.label.name in global_labels: - first_line = global_labels[line.label.name].line - raise AssemblerException(AssemblerExceptionTag.ASM, line.location.file, line.location.line, - (f'Duplicate definition of global label "{line.label.name}" in file\n' - f'First definition at line {first_line}')) - global_labels[line.label.name] = line.location - case Linkage.FILE_LOCAL, False: - if line.label.name in file_local_labels: - first_line = file_local_labels[line.label.name].line - raise AssemblerException(AssemblerExceptionTag.ASM, line.location.file, line.location.line, - (f'Duplicate definition of file-local label "{line.label.name}" in file\n' - f'First definition at line {first_line}')) - file_local_labels[line.label.name] = line.location - - elif isinstance(line, InstructionNode): - for arg in line.arguments: - if isinstance(arg, RelocatableExpressionNode): - arg.add_terms = list( - map(lambda x: label_or_template(x, template_fields), arg.add_terms)) + f'Label "{line.label.name}" conflicts with template "{prefix}"') + + if line.label.name in section_labels[section_key]: + first_line = section_labels[section_key][line.label.name].line + raise AssemblerException(AssemblerExceptionTag.ASM, line.location.file, line.location.line, + (f'Duplicate definition of label "{line.label.name}" in section\n' + f'First definition at line {first_line}')) + + section_labels[section_key][line.label.name] = line.location + match line.linkage, line.external: + case Linkage.FILE_LOCAL, True: + file_local_exts[line.label.name] = line.location + case Linkage.GLOBAL, False: + if line.label.name in global_labels: + first_line = global_labels[line.label.name].line + raise AssemblerException(AssemblerExceptionTag.ASM, line.location.file, line.location.line, + (f'Duplicate definition of global label "{line.label.name}" in file\n' + f'First definition at line {first_line}')) + global_labels[line.label.name] = line.location + case Linkage.FILE_LOCAL, False: + if line.label.name in file_local_labels: + first_line = file_local_labels[line.label.name].line + raise AssemblerException(AssemblerExceptionTag.ASM, line.location.file, line.location.line, + (f'Duplicate definition of file-local label "{line.label.name}" in file\n' + f'First definition at line {first_line}')) + file_local_labels[line.label.name] = line.location for name in set(file_local_exts) - set(file_local_labels): location = file_local_exts[name] raise AssemblerException(AssemblerExceptionTag.ASM, location.file, location.line, f'Undefined file-local label "{name}"') +def generate_object_module(pn: ProgramNode, target_instructions: TargetInstructions) -> ObjectModule: + templates = [Template(t, target_instructions) for t in pn.template_sections] + template_fields = dict([(t.name, t.labels) for t in templates]) + shared_externals = dict(map(lambda x: (x.label.name, x.linkage), pn.shared_externals)) + section_nodes = pn.absolute_sections + pn.relocatable_sections + + validate_labels(section_nodes, template_fields.keys()) + apply_templates(section_nodes, template_fields) + asects = [AbsoluteSection(asect, target_instructions) for asect in sorted(pn.absolute_sections, key=lambda s: s.address)] rsects = [RelocatableSection(name, nodes, target_instructions) for name, nodes in group_rsects(pn.relocatable_sections).items()] - - shared_externals = dict(map(lambda x: (x.label.name, x.linkage), pn.shared_externals)) for i in itertools.chain(asects, rsects): i.exts |= shared_externals From 4379bb05517362320757f6468776bb00bf8363b9 Mon Sep 17 00:00:00 2001 From: Andrey Eliseev Date: Mon, 9 Mar 2026 10:38:35 +0700 Subject: [PATCH 36/42] [cocas] Use same namespace for asects during validation --- cocas/assembler/object_generator.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/cocas/assembler/object_generator.py b/cocas/assembler/object_generator.py index ac7a320e..1dafb1a2 100644 --- a/cocas/assembler/object_generator.py +++ b/cocas/assembler/object_generator.py @@ -18,7 +18,7 @@ TemplateFieldNode, TemplateSectionNode, ) -from .code_block import AbsoluteSection, RelocatableSection +from .code_block import Section, AbsoluteSection, RelocatableSection from .exceptions import AssemblerException, AssemblerExceptionTag from .targets import IVaryingLengthSegment, TargetInstructions @@ -60,7 +60,7 @@ def __init__(self, sn: TemplateSectionNode, target_instructions: TargetInstructi def gather_local_labels(sects: list[Section]): local_labels = dict() for sect in sects: - local_labels.update({p for p in sect.labels.items() if not p[0].startswith('$')}) + local_labels.update({name: addr for name, addr in sect.labels.items() if not name.startswith('$')}) return local_labels @@ -125,18 +125,18 @@ def group_rsects(nodes: list[RelocatableSectionNode]) -> dict[str, list[Relocata def validate_labels(section_nodes: list[SectionNode], template_fields: set[str]) : - section_labels: dict[Union[str, int], dict[str, CodeLocation]] = defaultdict(dict) + section_labels: dict[str, dict[str, CodeLocation]] = defaultdict(dict) global_labels: dict[str, CodeLocation] = dict() file_local_labels: dict[str, CodeLocation] = dict() file_local_exts: dict[str, CodeLocation] = dict() for i in section_nodes: - section_key: Union[str, int] + section_name: str match i: case AbsoluteSectionNode(): - section_key = i.address + section_name = "$abs" case RelocatableSectionNode(): - section_key = i.name + section_name = i.name for line in i.lines: if not isinstance(line, LabelDeclarationNode): continue @@ -146,13 +146,13 @@ def validate_labels(section_nodes: list[SectionNode], template_fields: set[str]) raise AssemblerException(AssemblerExceptionTag.ASM, line.location.file, line.location.line, f'Label "{line.label.name}" conflicts with template "{prefix}"') - if line.label.name in section_labels[section_key]: - first_line = section_labels[section_key][line.label.name].line + if line.label.name in section_labels[section_name]: + first_line = section_labels[section_name][line.label.name].line raise AssemblerException(AssemblerExceptionTag.ASM, line.location.file, line.location.line, - (f'Duplicate definition of label "{line.label.name}" in section\n' + (f'Duplicate definition of label "{line.label.name}" in section "{section_name}"\n' f'First definition at line {first_line}')) - section_labels[section_key][line.label.name] = line.location + section_labels[section_name][line.label.name] = line.location match line.linkage, line.external: case Linkage.FILE_LOCAL, True: file_local_exts[line.label.name] = line.location From a08cd8624da0bb9227d72540aa4ed67cc66457f4 Mon Sep 17 00:00:00 2001 From: Andrey Eliseev Date: Mon, 9 Mar 2026 12:38:05 +0700 Subject: [PATCH 37/42] [cocas] Fix weak labels in asects --- cocas/assembler/code_block.py | 39 +++++++++---------- cocas/assembler/object_generator.py | 31 +++++++++++++-- .../assembler/targets/cdm16/code_segments.py | 8 ++-- cocas/assembler/targets/cdm8/code_segments.py | 8 ++-- .../assembler/targets/cdm8e/code_segments.py | 12 +++--- 5 files changed, 60 insertions(+), 38 deletions(-) diff --git a/cocas/assembler/code_block.py b/cocas/assembler/code_block.py index b9611cde..eebd84c4 100644 --- a/cocas/assembler/code_block.py +++ b/cocas/assembler/code_block.py @@ -30,7 +30,7 @@ def __init__(self, address: int, lines: list, target_instructions: TargetInstruc self.loop_stack: list = [] self.segments: list[ICodeSegment] = [] self.labels: dict[str, int] = dict() - self.ents: dict[str, Linkage] = dict() + self.entries: dict[EntryKey, Entry] = dict() self.exts: dict[str, Linkage] = dict() self.code_locations: dict[int, CodeLocation] = dict() temp_storage = dict() # variable to save information for future lines @@ -43,8 +43,11 @@ def __init__(self, address: int, lines: list, target_instructions: TargetInstruc raise AssemblerException(AssemblerExceptionTag.ASM, lines[-1].location.file, lines[-1].location.line, e.message) - def append_label(self, label_name): - self.labels[label_name] = self.address + self.size + def get_address(self): + return self.address + self.size + + def append_label(self, label_name: str): + self.labels[label_name] = self.get_address() def append_branch_instruction(self, location, mnemonic, label_name, inverse=False): self.code_locations[self.size] = location @@ -68,17 +71,20 @@ def assemble_lines(self, lines: list, temp_storage): ast_node_handlers[type(line)](line, temp_storage) def assemble_label_declaration(self, line: LabelDeclarationNode, __): - label_name = line.label.name + key = EntryKey(line.label.name, line.linkage) if line.external: - self.exts[label_name] = line.linkage + self.exts[key.name] = key.linkage elif line.linkage == Linkage.WEAK_GLOBAL: - self.append_label(label_name) - self.ents[label_name] = Linkage.WEAK_GLOBAL - self.exts[label_name] = Linkage.GLOBAL + # We don't know the values of WEAK_GLOBAL labels + # because these may be overridden at link time. + # This is why we don't store the address in the + # known label dictionary and instead add an external declaration. + self.entries[key] = Entry(self.get_address()) + self.exts[key.name] = Linkage.GLOBAL else: - self.append_label(label_name) + self.append_label(key.name) if line.linkage: - self.ents[label_name] = line.linkage + self.entries[key] = Entry(self.get_address()) def assemble_instruction(self, line: InstructionNode, temp_storage): for seg in self.target_instructions.assemble_instruction(line, temp_storage): @@ -169,12 +175,7 @@ def __init__(self, address: int, lines: list, target_instructions: TargetInstruc super().__init__(address, lines, target_instructions) def to_object_section_record(self, labels: dict[str, int], templates: dict[str, dict[str, int]]): - entries = { - EntryKey(name, self.ents[name]): Entry(offset) - for name, offset in self.labels.items() - if name in self.ents - } - out = ObjectSectionRecord(self.name, self.address, bytearray(), entries, [], self.code_locations) + out = ObjectSectionRecord(self.name, self.address, bytearray(), dict(self.entries), [], self.code_locations) for seg in self.segments: seg.fill(out, self, labels, templates) return out @@ -183,8 +184,7 @@ def to_object_section_record(self, labels: dict[str, int], templates: dict[str, class AbsoluteSection(Section): def __init__(self, sn: SectionNode, target_instructions: TargetInstructions): self.name = '$abs' - address = sn.address - super().__init__(address, sn.lines, target_instructions) + super().__init__(sn.address, sn.lines, target_instructions) @dataclass class RelocatableSection(Section): @@ -192,5 +192,4 @@ def __init__(self, name: str, nodes: list[SectionNode], target_instructions: Tar if not nodes: raise ValueError("Node list must not be empty.") self.name = name - address = 0 - super().__init__(address, [line for node in nodes for line in node.lines], target_instructions) + super().__init__(0, [line for node in nodes for line in node.lines], target_instructions) diff --git a/cocas/assembler/object_generator.py b/cocas/assembler/object_generator.py index 1dafb1a2..bfdd4229 100644 --- a/cocas/assembler/object_generator.py +++ b/cocas/assembler/object_generator.py @@ -3,7 +3,7 @@ from dataclasses import dataclass from typing import Any, Union -from cocas.object_module import CodeLocation, ObjectModule, Linkage +from cocas.object_module import CodeLocation, ObjectModule, EntryKey, Linkage from .ast_nodes import ( SectionNode, @@ -57,13 +57,31 @@ def __init__(self, sn: TemplateSectionNode, target_instructions: TargetInstructi self.labels['_'] = size -def gather_local_labels(sects: list[Section]): +def gather_local_labels(sects: list[Section]) -> dict[str, int]: local_labels = dict() for sect in sects: local_labels.update({name: addr for name, addr in sect.labels.items() if not name.startswith('$')}) return local_labels +def gather_weak_label_externals(sects: list[Section]) -> dict[str, Linkage]: + """ + Collects all weak external declarations that correspond to a weak label definition. + This is needed to support existing semantics and have weak labels defined in absolute sections + visible in all other sections, despite the fact that we don't emit labels for weak definitions. + """ + weak_externals: dict[str, Linkage] = dict() + for sect in sects: + # Take all weak externals that have + # a corresponding weak entry with the same name. + weak_externals.update({ + name: linkage + for name, linkage in sect.exts.items() + if EntryKey(name, Linkage.WEAK_GLOBAL) in sect.entries + }) + return weak_externals + + @dataclass class VaryingLengthEntry: seg: IVaryingLengthSegment @@ -124,7 +142,7 @@ def group_rsects(nodes: list[RelocatableSectionNode]) -> dict[str, list[Relocata return grouped -def validate_labels(section_nodes: list[SectionNode], template_fields: set[str]) : +def validate_labels(section_nodes: list[SectionNode], template_fields: set[str]): section_labels: dict[str, dict[str, CodeLocation]] = defaultdict(dict) global_labels: dict[str, CodeLocation] = dict() file_local_labels: dict[str, CodeLocation] = dict() @@ -189,8 +207,13 @@ def generate_object_module(pn: ProgramNode, target_instructions: TargetInstructi for asect in sorted(pn.absolute_sections, key=lambda s: s.address)] rsects = [RelocatableSection(name, nodes, target_instructions) for name, nodes in group_rsects(pn.relocatable_sections).items()] + + # Overwrite shared externals with weak definitions in asects + shared_externals.update(gather_weak_label_externals(asects)) for i in itertools.chain(asects, rsects): - i.exts |= shared_externals + # Prioritize local externals over shared externals + for name, linkage in shared_externals: + i.exts.setdefault(name, linkage) for _ in pn.top_instructions: pass # do something diff --git a/cocas/assembler/targets/cdm16/code_segments.py b/cocas/assembler/targets/cdm16/code_segments.py index bef98219..8d020353 100644 --- a/cocas/assembler/targets/cdm16/code_segments.py +++ b/cocas/assembler/targets/cdm16/code_segments.py @@ -304,15 +304,15 @@ def parse_expression(expr: RelocatableExpressionNode, section: "Section", labels result = ParsedExpression(expr.const_term) for term, sign in [(t, 1) for t in expr.add_terms] + [(t, -1) for t in expr.sub_terms]: if isinstance(term, LabelNode): - if term.name in section.exts: - entry_key = EntryKey(term.name, section.exts[term.name]) - result.ext_labels[entry_key] = result.ext_labels.get(entry_key, 0) + sign - elif term.name in section.labels and section.name != '$abs': + if term.name in section.labels and section.name != '$abs': result.rel_labels[term.name] = result.rel_labels.get(term.name, 0) + sign elif term.name in section.labels: result.asect[term.name] = result.asect.get(term.name, 0) + sign elif term.name in labels: result.asect[term.name] = result.asect.get(term.name, 0) + sign + elif term.name in section.exts: + entry_key = EntryKey(term.name, section.exts[term.name]) + result.ext_labels[entry_key] = result.ext_labels.get(entry_key, 0) + sign else: split = term.name.split(".") if len(split) == 1: diff --git a/cocas/assembler/targets/cdm8/code_segments.py b/cocas/assembler/targets/cdm8/code_segments.py index 4b424c67..5e052e29 100644 --- a/cocas/assembler/targets/cdm8/code_segments.py +++ b/cocas/assembler/targets/cdm8/code_segments.py @@ -88,15 +88,15 @@ def parse_expression(expr: RelocatableExpressionNode, section: "Section", labels result = ParsedExpression(expr.const_term) for term, sign in [(t, 1) for t in expr.add_terms] + [(t, -1) for t in expr.sub_terms]: if isinstance(term, LabelNode): - if term.name in section.exts: - entry_key = EntryKey(term.name, section.exts[term.name]) - result.ext_labels[entry_key] = result.ext_labels.get(entry_key, 0) + sign - elif term.name in section.labels and section.name != '$abs': + if term.name in section.labels and section.name != '$abs': result.rel_labels[term.name] = result.rel_labels.get(term.name, 0) + sign elif term.name in section.labels: result.asect[term.name] = result.asect.get(term.name, 0) + sign elif term.name in labels: result.asect[term.name] = result.asect.get(term.name, 0) + sign + elif term.name in section.exts: + entry_key = EntryKey(term.name, section.exts[term.name]) + result.ext_labels[entry_key] = result.ext_labels.get(entry_key, 0) + sign else: _error(segment, f'Label "{term.name}" not found') elif isinstance(term, TemplateFieldNode): diff --git a/cocas/assembler/targets/cdm8e/code_segments.py b/cocas/assembler/targets/cdm8e/code_segments.py index b6f50385..fe1b632a 100644 --- a/cocas/assembler/targets/cdm8e/code_segments.py +++ b/cocas/assembler/targets/cdm8e/code_segments.py @@ -212,15 +212,15 @@ def eval_rel_expr_seg(seg: RelocatableExpressionSegment, s: "Section", local_dim = 0 for term, m in [(t, 1) for t in seg.expr.add_terms] + [(t, -1) for t in seg.expr.sub_terms]: if isinstance(term, LabelNode): - if term.name in s.exts: - used_exts.setdefault(term.name, 0) - used_exts[term.name] += m + if term.name in s.labels: + s_dim += m + val_long += s.labels[term.name] * m elif term.name in labels: local_dim += m val_long += labels[term.name] * m - elif term.name in s.labels: - s_dim += m - val_long += s.labels[term.name] * m + elif term.name in s.exts: + used_exts.setdefault(term.name, 0) + used_exts[term.name] += m else: _error(seg, f'Label "{term.name}" not found') elif isinstance(term, TemplateFieldNode): From 3c19ba5d22e331379e3c6f6cecd7b3bd05d63b12 Mon Sep 17 00:00:00 2001 From: Andrey Eliseev Date: Mon, 9 Mar 2026 18:42:01 +0700 Subject: [PATCH 38/42] [cocas] Fix shared labels --- cocas/assembler/object_generator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocas/assembler/object_generator.py b/cocas/assembler/object_generator.py index bfdd4229..991a94b9 100644 --- a/cocas/assembler/object_generator.py +++ b/cocas/assembler/object_generator.py @@ -212,7 +212,7 @@ def generate_object_module(pn: ProgramNode, target_instructions: TargetInstructi shared_externals.update(gather_weak_label_externals(asects)) for i in itertools.chain(asects, rsects): # Prioritize local externals over shared externals - for name, linkage in shared_externals: + for name, linkage in shared_externals.items(): i.exts.setdefault(name, linkage) for _ in pn.top_instructions: From 5174d5ce29b40401245611f6ab1b7d63ebbbbb93 Mon Sep 17 00:00:00 2001 From: Proletcultist Date: Mon, 9 Mar 2026 18:45:08 +0700 Subject: [PATCH 39/42] [cocas] Replace concatenation of rsects with grouping --- cocas/linker/linker.py | 41 +++++++++++----------- cocas/object_module/__init__.py | 1 + cocas/object_module/rsects_group.py | 54 +++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 20 deletions(-) create mode 100644 cocas/object_module/rsects_group.py diff --git a/cocas/linker/linker.py b/cocas/linker/linker.py index bbec7ef5..38885033 100644 --- a/cocas/linker/linker.py +++ b/cocas/linker/linker.py @@ -2,7 +2,7 @@ from math import inf from typing import Any, Optional -from cocas.object_module import CodeLocation, ObjectModule, ObjectSectionRecord, concat_rsects, Entry, EntryKey, Linkage +from cocas.object_module import CodeLocation, ObjectModule, ObjectSectionRecord, concat_rsects, Entry, EntryKey, Linkage, RsectsGroup, group_rsects from .exceptions import LinkerException from .targets import TargetParams, import_target @@ -35,26 +35,28 @@ def init_bins(asects: list[ObjectSectionRecord], image_size: Optional[int]): return rsect_bins -def place_sects(rsects: list[ObjectSectionRecord], rsect_bins: list, image_size) -> dict[str, int]: - sect_addresses = {'$abs': 0} - for rsect in rsects: - rsect_size = len(rsect.data) +def place_sects(asects: list[ObjectSectionRecord], rsects: list[ObjectSectionRecord], rsect_bins: list, image_size) -> dict[int, int]: + sect_addresses: dict[int, int] = {} + for asect in asects: + sect_addresses[id(asect)] = 0 + + for group in group_rsects(rsects): for i in range(len(rsect_bins)): bin_begin, bin_size = rsect_bins[i] - if bin_size >= rsect_size: - address = (bin_begin + rsect.alignment - 1) // rsect.alignment * rsect.alignment - if address + rsect_size <= bin_begin + bin_size: - if rsect.name in sect_addresses: - raise LinkerException(f'Duplicate sections "{rsect.name}"') - sect_addresses[rsect.name] = address - rsect_bins[i] = (address + rsect_size, bin_size - rsect_size) + if bin_size >= group.size: + address = (bin_begin + group.alignment - 1) // group.alignment * group.alignment + if address + group.size <= bin_begin + bin_size: + rsect_bins[i] = (address + group.size, bin_size - group.size) + for rsect in group.rsects: + sect_addresses[id(rsect)] = address + address += len(rsect.data) break else: - raise LinkerException(f'Section "{rsect.name}" exceeds image size limit {image_size}') + raise LinkerException(f'Section "{group.name}" exceeds image size limit {image_size}') return sect_addresses -def find_referenced_sects(asects: list[ObjectSectionRecord], entry_by_ext: dict[int, tuple[ObjectSectionRecord, Entry]]): +def find_referenced_sects(asects: list[ObjectSectionRecord], entry_by_ext: dict[int, tuple[ObjectSectionRecord, Entry] | None]): used_sects_queue = asects.copy() used_sects = [] i = 0 @@ -131,15 +133,14 @@ def link(objects: list[tuple[Any, ObjectModule]], image_size: Optional[int] = No asects: list[ObjectSectionRecord] = list(itertools.chain.from_iterable([obj.asects for _, obj in objects])) used_sects = find_referenced_sects(asects, entry_by_exts) try: - rsects = concat_rsects(filter(lambda rsect: rsect in used_sects, itertools.chain.from_iterable([obj.rsects for _, obj in objects]))) + rsects = list(filter(lambda rsect: rsect in used_sects, itertools.chain.from_iterable([obj.rsects for _, obj in objects]))) except ValueError as e: raise LinkerException(str(e)) - rsects.sort(key=lambda s: -len(s.data)) asects.sort(key=lambda s: s.address) rsect_bins = init_bins(asects, image_size) - sect_addresses = place_sects(rsects, rsect_bins, image_size) + sect_addresses = place_sects(asects, rsects, rsect_bins, image_size) image = bytearray(2 ** 16) code_locations: dict[int, CodeLocation] = {} @@ -158,7 +159,7 @@ def link(objects: list[tuple[Any, ObjectModule]], image_size: Optional[int] = No # Gathering code_locations from rsects lower_parts: dict[int, int] = {} # Won't be empty if two entries added together, currently targets don't do that for rsect in rsects: - image_begin = sect_addresses[rsect.name] + image_begin = sect_addresses[id(rsect)] image_end = image_begin + len(rsect.data) image[image_begin:image_end] = rsect.data for entry in rsect.relocatable: @@ -182,10 +183,10 @@ def link(objects: list[tuple[Any, ObjectModule]], image_size: Optional[int] = No symbol_value = 0 else: symbol_sect, symbol = entry_by_exts[id(ext_name)] - symbol_value = sect_addresses[symbol_sect.name] + symbol.address + symbol_value = sect_addresses[id(symbol_sect)] + symbol.address for entry in sect.external[ext_name]: - pos = sect_addresses[sect.name] + entry.offset + pos = sect_addresses[id(sect)] + entry.offset lower_limit = 1 << 8 * entry.entry_bytes.start val = int.from_bytes(image[pos:pos + len(entry.entry_bytes)], 'little', signed=False) * lower_limit val += entry.lower_part + lower_parts.get(entry.offset, 0) diff --git a/cocas/object_module/__init__.py b/cocas/object_module/__init__.py index 4d2ed98b..3f99278f 100644 --- a/cocas/object_module/__init__.py +++ b/cocas/object_module/__init__.py @@ -5,3 +5,4 @@ from .location import CodeLocation from .object_module import ObjectModule, ObjectSectionRecord from .entry import Entry, EntryKey, Linkage +from .rsects_group import RsectsGroup, group_rsects diff --git a/cocas/object_module/rsects_group.py b/cocas/object_module/rsects_group.py new file mode 100644 index 00000000..c06a2404 --- /dev/null +++ b/cocas/object_module/rsects_group.py @@ -0,0 +1,54 @@ +from dataclasses import dataclass +from math import lcm +from cocas.object_module import ObjectSectionRecord + +@dataclass(frozen=True) +class RsectsGroup: + "A group of rsects, which must be placed in image one right after another with proper alignment." + name: str + rsects: list[ObjectSectionRecord] + "Rsects of the group" + size: int + "Size of the group" + alignment: int + "Alignment of the group" + + def __init__(self, name: str, rsects: list[ObjectSectionRecord]): + object.__setattr__(self, "rsects", []) + object.__setattr__(self, "name", name) + + if len(rsects) == 0: + object.__setattr__(self, "size", 0) + object.__setattr__(self, "alignment", 1) + return + + self.rsects.append(rsects[0]) + size = len(rsects[0].data) + alignment = rsects[0].alignment + for rsect in rsects[1:]: + alignment = lcm(alignment, rsect.alignment) + aligned_size = (size + rsect.alignment - 1) // rsect.alignment * rsect.alignment + self.rsects[-1].data.extend(bytearray(aligned_size - size)) + self.rsects.append(rsect) + + size = aligned_size + len(rsect.data) + + object.__setattr__(self, "size", size) + object.__setattr__(self, "alignment", alignment) + + +def group_rsects(rsects: list[ObjectSectionRecord]) -> list[RsectsGroup]: + """ + Groups rsects with same name into RsectsGroup. + :param rsects: rsects with possibly different names, unsorted + :returns: list of RsectsGroups sorted by names + """ + ret: list[RsectsGroup] = [] + + grouped: dict[str, list[ObjectSectionRecord]] = {} + for rsect in rsects: + grouped.setdefault(rsect.name, []).append(rsect) + + return list(map(lambda p: RsectsGroup(p[0], p[1]), sorted(grouped.items(), key = lambda p: p[0]))) + + From 2f08836493d05904fe888cfe9e3f98f98c8349d2 Mon Sep 17 00:00:00 2001 From: Proletcultist Date: Mon, 9 Mar 2026 18:49:35 +0700 Subject: [PATCH 40/42] [cocas] Remove concat_rsects --- cocas/linker/linker.py | 2 +- cocas/object_module/__init__.py | 1 - cocas/object_module/concat_rsects.py | 61 ---------------------------- 3 files changed, 1 insertion(+), 63 deletions(-) delete mode 100644 cocas/object_module/concat_rsects.py diff --git a/cocas/linker/linker.py b/cocas/linker/linker.py index 38885033..c85c4588 100644 --- a/cocas/linker/linker.py +++ b/cocas/linker/linker.py @@ -2,7 +2,7 @@ from math import inf from typing import Any, Optional -from cocas.object_module import CodeLocation, ObjectModule, ObjectSectionRecord, concat_rsects, Entry, EntryKey, Linkage, RsectsGroup, group_rsects +from cocas.object_module import CodeLocation, ObjectModule, ObjectSectionRecord, Entry, EntryKey, Linkage, RsectsGroup, group_rsects from .exceptions import LinkerException from .targets import TargetParams, import_target diff --git a/cocas/object_module/__init__.py b/cocas/object_module/__init__.py index 3f99278f..55af784d 100644 --- a/cocas/object_module/__init__.py +++ b/cocas/object_module/__init__.py @@ -1,6 +1,5 @@ """This module contains structures of universal object code and debug information that is used in all other modules""" -from .concat_rsects import concat_rsects from .external_entry import ExternalEntry from .location import CodeLocation from .object_module import ObjectModule, ObjectSectionRecord diff --git a/cocas/object_module/concat_rsects.py b/cocas/object_module/concat_rsects.py deleted file mode 100644 index 9b788d1c..00000000 --- a/cocas/object_module/concat_rsects.py +++ /dev/null @@ -1,61 +0,0 @@ -from copy import copy -from math import lcm -from typing import TYPE_CHECKING, Iterable - -from .entry import Entry - -if TYPE_CHECKING: - from cocas.object_module import ObjectSectionRecord - - -def concat_rsects(rsects: Iterable["ObjectSectionRecord"]) -> list["ObjectSectionRecord"]: - """ - Concatenate rsects that have same name, put one right after another with proper alignment - :param rsects: rsects with possibly different names, unsorted - :throws: ValueError if sections with same name declare same entry (label) - """ - grouped: dict[str, list["ObjectSectionRecord"]] = {} - for rsect in rsects: - grouped.setdefault(rsect.name, []).append(rsect) - ret = [] - for name, sections in grouped.items(): - if len(sections) < 2: - ret.extend(sections) - else: - new = copy(sections[0]) - new.data = copy(sections[0].data) - new.entries = copy(sections[0].entries) - new.code_locations = copy(sections[0].code_locations) - new.external = copy(sections[0].external) - new.relocatable = copy(sections[0].relocatable) - prev_size = len(new.data) - for rsect in sections[1:]: - new.alignment = lcm(new.alignment, rsect.alignment) - prev_size = (prev_size + rsect.alignment - 1) // rsect.alignment * rsect.alignment - new.data.extend(bytearray(prev_size - len(new.data))) - new.data += rsect.data - new.entries.update({key: Entry(entry.address + prev_size) for key, entry in rsect.entries.items()}) - for pos, loc in rsect.code_locations.items(): - new.code_locations[pos + prev_size] = loc - for label, exts in rsect.external.items(): - for i in exts: - t = copy(i) - t.offset += prev_size - new.external[label].append(t) - for entry in rsect.relocatable: - t = copy(entry) - t.offset += prev_size - new.relocatable.append(t) - lower_limit = 1 << 8 * entry.entry_bytes.start - pos = t.offset - val = int.from_bytes(new.data[pos:pos + len(entry.entry_bytes)], 'little', signed=False) * lower_limit - val += entry.lower_part - val += prev_size - val %= (1 << 8 * entry.entry_bytes.stop) - if entry.entry_bytes.start > 0: - entry.lower_part = val % lower_limit - new.data[pos:pos + len(entry.entry_bytes)] = \ - (val // lower_limit).to_bytes(len(entry.entry_bytes), 'little', signed=False) - prev_size += len(rsect.data) - ret.append(new) - return ret From 522522c109708c8f29e44993c3d2a50f185b0a03 Mon Sep 17 00:00:00 2001 From: Andrey Eliseev Date: Mon, 9 Mar 2026 19:55:34 +0700 Subject: [PATCH 41/42] [cocas] Fix not updating entry addresses --- cocas/assembler/targets/abstract_code_segments.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cocas/assembler/targets/abstract_code_segments.py b/cocas/assembler/targets/abstract_code_segments.py index 12e7d035..8aaa231c 100644 --- a/cocas/assembler/targets/abstract_code_segments.py +++ b/cocas/assembler/targets/abstract_code_segments.py @@ -2,7 +2,7 @@ from math import lcm from typing import TYPE_CHECKING -from cocas.object_module import CodeLocation, ObjectSectionRecord +from cocas.object_module import CodeLocation, ObjectSectionRecord, Entry from ..exceptions import AssemblerException, AssemblerExceptionTag @@ -40,6 +40,9 @@ def update_surroundings(diff: int, pos: int, section: "Section", labels: dict[st section.labels[label_name] += diff if label_name in labels: labels[label_name] += diff + for key, entry in section.entries.items(): + if entry.address > pos: + section.entries[key] = Entry(entry.address + diff) old_locations = section.code_locations section.code_locations = dict() for PC, location in old_locations.items(): From d50188dd2361ec1fc4c34c46fa5d90f35c37a4af Mon Sep 17 00:00:00 2001 From: Andrey Eliseev Date: Mon, 9 Mar 2026 20:18:39 +0700 Subject: [PATCH 42/42] [cocas] Move Linkage to the top of entry.py To appease old Python --- cocas/object_module/entry.py | 42 ++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/cocas/object_module/entry.py b/cocas/object_module/entry.py index 701716d4..26ea2b77 100644 --- a/cocas/object_module/entry.py +++ b/cocas/object_module/entry.py @@ -2,14 +2,19 @@ from enum import IntEnum -@dataclass(frozen=True) -class Entry: - "A symbol entry in a section of an object module." - address: int - "The offset from the start of the section this entry is defined at." - - def __str__(self): - return f"{self.address:02x}" +class Linkage(IntEnum): + "Describes the way an entry or external is linked." + FILE_LOCAL = 1 + "The entry is visible in the current object module only." + GLOBAL = 2 + "The entry is visible in all object modules." + WEAK_GLOBAL = 3 + """ + The entry is visible in all object modules. + When applied to an entry, it makes it possible to override with a GLOBAL entry. + When applied to an external, it becomes optional (e.g. doesn't throw an error + when there is no matching entry, leaving the value as is. + """ @dataclass(frozen=True) @@ -32,16 +37,11 @@ def __str__(self): return self.name -class Linkage(IntEnum): - "Describes the way an entry or external is linked." - FILE_LOCAL = 1 - "The entry is visible in the current object module only." - GLOBAL = 2 - "The entry is visible in all object modules." - WEAK_GLOBAL = 3 - """ - The entry is visible in all object modules. - When applied to an entry, it makes it possible to override with a GLOBAL entry. - When applied to an external, it becomes optional (e.g. doesn't throw an error - when there is no matching entry, leaving the value as is. - """ +@dataclass(frozen=True) +class Entry: + "A symbol entry in a section of an object module." + address: int + "The offset from the start of the section this entry is defined at." + + def __str__(self): + return f"{self.address:02x}"