Skip to content

Commit

Permalink
[cocas] Move exception class declarations into modules
Browse files Browse the repository at this point in the history
  • Loading branch information
cjvth committed Feb 8, 2024
1 parent 869ccae commit d9defbc
Show file tree
Hide file tree
Showing 21 changed files with 125 additions and 99 deletions.
1 change: 1 addition & 0 deletions cocas/assembler/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from .assembler import assemble_files, assemble_module
from .ast_builder import build_ast
from .exceptions import CdmAssemblerException
from .macro_processor import process_macros
from .object_generator import generate_object_module
from .targets import import_target, list_assembler_targets
10 changes: 5 additions & 5 deletions cocas/assembler/ast_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

from antlr4 import CommonTokenStream, InputStream

from cocas.error import AntlrErrorListener, CdmException, CdmExceptionTag
from cocas.object_module import CodeLocation

from .ast_nodes import (
Expand All @@ -25,6 +24,7 @@
UntilLoopNode,
WhileLoopNode,
)
from .exceptions import AntlrErrorListener, CdmAssemblerException, CdmExceptionTag
from .generated import AsmLexer, AsmParser, AsmParserVisitor


Expand Down Expand Up @@ -126,8 +126,8 @@ def visitConnective_condition(self, ctx: AsmParser.Connective_conditionContext):
cond = self.visitCondition(ctx.condition())
cond.conjunction = ctx.conjunction().getText()
if cond.conjunction != 'and' and cond.conjunction != 'or':
raise CdmException(CdmExceptionTag.ASM, self.source_path, ctx.start.line - self.line_offset,
'Expected "and" or "or" in compound condition')
raise CdmAssemblerException(CdmExceptionTag.ASM, self.source_path, ctx.start.line - self.line_offset,
'Expected "and" or "or" in compound condition')
return cond

def visitCondition(self, ctx: AsmParser.ConditionContext):
Expand Down Expand Up @@ -218,8 +218,8 @@ def visitStandaloneLabel(self, ctx: AsmParser.StandaloneLabelContext) -> LabelDe
label_decl = self.visitLabel_declaration(ctx.label_declaration())
label_decl.external = ctx.Ext() is not None
if label_decl.entry and label_decl.external:
raise CdmException(CdmExceptionTag.ASM, self.source_path, ctx.start.line - self.line_offset,
f'Label {label_decl.label.name} cannot be both external and entry')
raise CdmAssemblerException(CdmExceptionTag.ASM, self.source_path, ctx.start.line - self.line_offset,
f'Label {label_decl.label.name} cannot be both external and entry')
return label_decl

def visitLabel_declaration(self, ctx: AsmParser.Label_declarationContext) -> LabelDeclarationNode:
Expand Down
5 changes: 3 additions & 2 deletions cocas/assembler/code_block.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from dataclasses import dataclass
from typing import Any, Callable, Type

from cocas.error import CdmException, CdmExceptionTag, CdmTempException
from cocas.object_module import CodeLocation, ObjectSectionRecord

from .ast_nodes import (
Expand All @@ -17,6 +16,7 @@
UntilLoopNode,
WhileLoopNode,
)
from .exceptions import CdmAssemblerException, CdmExceptionTag, CdmTempException
from .targets import ICodeSegment, TargetInstructionsInterface


Expand All @@ -39,7 +39,8 @@ def __init__(self, address: int, lines: list, target_instructions: Type[TargetIn
target_instructions.finish(temp_storage)
except CdmTempException as e:
# if it isn't ok, must be at least one line
raise CdmException(CdmExceptionTag.ASM, lines[-1].location.file, lines[-1].location.line, e.message)
raise CdmAssemblerException(CdmExceptionTag.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
Expand Down
29 changes: 3 additions & 26 deletions cocas/error.py → cocas/assembler/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
from enum import Enum
from typing import Union

from antlr4.error.ErrorListener import ErrorListener
from colorama import Fore, Style

from cocas.assembler.generated import AsmParser


class CdmExceptionTag(Enum):
MACRO = "Macro"
ASM = "Assembler"
OBJ = "Object files"
LINK = "Linker"


# this exception should be used when we don't know code location now,
Expand All @@ -23,32 +19,13 @@ def __init__(self, message: str):
self.message = message


class CdmLinkException(Exception):
def __init__(self, message: str):
self.message = message


class CdmException(Exception):
def __init__(self, tag: Union[str, CdmExceptionTag], file: str, line: int, description: str):
if isinstance(tag, CdmExceptionTag):
tag = tag.value
class CdmAssemblerException(Exception):
def __init__(self, tag: CdmExceptionTag, file: str, line: int, description: str):
self.tag = tag
self.file = file
self.line = line
self.description = description

def log(self):
print(
f'[{self.tag}] {Fore.RED}ERROR{Fore.RESET} at line {Style.BRIGHT}{self.line}{Style.RESET_ALL} of '
f'{Style.BRIGHT}{self.file}{Style.RESET_ALL}')
print(f'{self.description}')


def log_error(tag: str, message: str):
print(
f'[{tag}] {Fore.RED}ERROR{Fore.RESET}')
print(message)


class AntlrErrorListener(ErrorListener):
def __init__(self, tag, file):
Expand All @@ -59,4 +36,4 @@ def syntaxError(self, recognizer, offending_symbol, line, column, msg, e):
if isinstance(recognizer, AsmParser):
line = line - recognizer.current_offset
self.file = recognizer.current_file
raise CdmException(self.tag, self.file, line, msg)
raise CdmAssemblerException(self.tag, self.file, line, msg)
6 changes: 3 additions & 3 deletions cocas/assembler/macro_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
from antlr4 import CommonTokenStream, FileStream, InputStream
from antlr4.TokenStreamRewriter import TokenStreamRewriter

from cocas.error import AntlrErrorListener, CdmException, CdmExceptionTag, CdmTempException
from cocas.object_module import CodeLocation

from .exceptions import AntlrErrorListener, CdmAssemblerException, CdmExceptionTag, CdmTempException
from .generated import MacroLexer, MacroParser, MacroVisitor


Expand Down Expand Up @@ -182,7 +182,7 @@ def visitMlb(self, ctx: MacroParser.MlbContext):
try:
self.add_macro(self.visitMlb_macro(child))
except CdmTempException as e:
raise CdmException(CdmExceptionTag.MACRO, self.filepath, child.start.line, e.message)
raise CdmAssemblerException(CdmExceptionTag.MACRO, self.filepath, child.start.line, e.message)
return self.macros

def visitProgram(self, ctx: MacroParser.ProgramContext):
Expand All @@ -205,7 +205,7 @@ def visitProgram(self, ctx: MacroParser.ProgramContext):
self.rewriter.insertBeforeToken(child.start, expanded_text)
self.rewriter.delete(self.rewriter.DEFAULT_PROGRAM_NAME, child.start, child.stop)
except CdmTempException as e:
raise CdmException(CdmExceptionTag.MACRO, self.filepath, child.start.line, e.message)
raise CdmAssemblerException(CdmExceptionTag.MACRO, self.filepath, child.start.line, e.message)

def visitMacro(self, ctx: MacroParser.MacroContext):
header = ctx.macro_header()
Expand Down
2 changes: 1 addition & 1 deletion cocas/assembler/object_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
from typing import Type

from cocas.assembler.targets import IVaryingLengthSegment
from cocas.error import CdmExceptionTag
from cocas.object_module import CodeLocation, ObjectModule

from .ast_nodes import InstructionNode, LabelDeclarationNode, ProgramNode, TemplateSectionNode
from .code_block import Section
from .exceptions import CdmExceptionTag
from .targets import TargetInstructionsInterface

TAG = CdmExceptionTag.ASM
Expand Down
5 changes: 3 additions & 2 deletions cocas/assembler/targets/abstract_code_segments.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
from math import lcm
from typing import TYPE_CHECKING

from cocas.error import CdmException, CdmExceptionTag
from cocas.object_module import CodeLocation

from ..exceptions import CdmAssemblerException, CdmExceptionTag

if TYPE_CHECKING:
from cocas.object_module import ObjectSectionRecord

Expand Down Expand Up @@ -97,4 +98,4 @@ def fill(self, object_record: "ObjectSectionRecord", section: "Section", labels:


def _error(segment: ICodeSegment, message: str):
raise CdmException(CdmExceptionTag.ASM, segment.location.file, segment.location.line, message)
raise CdmAssemblerException(CdmExceptionTag.ASM, segment.location.file, segment.location.line, message)
4 changes: 2 additions & 2 deletions cocas/assembler/targets/cdm16/code_segments.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

import bitstruct

from cocas.error import CdmException, CdmExceptionTag
from cocas.object_module import CodeLocation, ExternalEntry

from ...ast_nodes import LabelNode, RegisterNode, RelocatableExpressionNode, TemplateFieldNode
from ...exceptions import CdmAssemblerException, CdmExceptionTag
from .. import IAlignedSegment, IAlignmentPaddingSegment, ICodeSegment, IVaryingLengthSegment

if TYPE_CHECKING:
Expand All @@ -22,7 +22,7 @@ def pack(fmt, *args):


def _error(segment: ICodeSegment, message: str):
raise CdmException(CdmExceptionTag.ASM, segment.location.file, segment.location.line, message)
raise CdmAssemblerException(CdmExceptionTag.ASM, segment.location.file, segment.location.line, message)


class CodeSegment(ICodeSegment, ABC):
Expand Down
13 changes: 6 additions & 7 deletions cocas/assembler/targets/cdm16/target_instructions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
from dataclasses import dataclass
from typing import Callable, Union, get_args, get_origin

from cocas.error import CdmException, CdmExceptionTag, CdmTempException

from ...ast_nodes import InstructionNode, LabelNode, RegisterNode, RelocatableExpressionNode
from ...exceptions import CdmAssemblerException, CdmExceptionTag, CdmTempException
from .. import ICodeSegment, TargetInstructionsInterface
from .code_segments import (
AlignmentPaddingSegment,
Expand Down Expand Up @@ -57,10 +56,10 @@ def assemble_instruction(line: InstructionNode, temp_storage: dict) -> list[ICod
return h.handler(line, temp_storage, h.instructions[line.mnemonic])
if line.mnemonic.startswith('b'):
return TargetInstructions.branch(line)
raise CdmException(CdmExceptionTag.ASM, line.location.file, line.location.line,
f'Unknown instruction "{line.mnemonic}"')
raise CdmAssemblerException(CdmExceptionTag.ASM, line.location.file, line.location.line,
f'Unknown instruction "{line.mnemonic}"')
except CdmTempException as e:
raise CdmException(CdmExceptionTag.ASM, line.location.file, line.location.line, e.message)
raise CdmAssemblerException(CdmExceptionTag.ASM, line.location.file, line.location.line, e.message)

@staticmethod
def finish(temp_storage: dict):
Expand Down Expand Up @@ -185,8 +184,8 @@ def branch(line: InstructionNode, inverse=False) -> list[ICodeSegment]:
branch_code = pair.inv_code if not inverse else pair.code
break
else:
raise CdmException(CdmExceptionTag.ASM, line.location.file, line.location.line,
f'Invalid branch condition: {cond}')
raise CdmAssemblerException(CdmExceptionTag.ASM, line.location.file, line.location.line,
f'Invalid branch condition: {cond}')
assert_count_args(line.arguments, RelocatableExpressionNode)
return [Branch(line.location, branch_code, line.arguments[0])]

Expand Down
4 changes: 2 additions & 2 deletions cocas/assembler/targets/cdm8/code_segments.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
from dataclasses import dataclass, field
from typing import TYPE_CHECKING

from cocas.error import CdmException, CdmExceptionTag
from cocas.object_module import CodeLocation, ExternalEntry

from ...ast_nodes import LabelNode, RelocatableExpressionNode, TemplateFieldNode
from ...exceptions import CdmAssemblerException, CdmExceptionTag
from .. import IAlignmentPaddingSegment, ICodeSegment

if TYPE_CHECKING:
Expand All @@ -14,7 +14,7 @@


def _error(segment: ICodeSegment, message: str):
raise CdmException(CdmExceptionTag.ASM, segment.location.file, segment.location.line, message)
raise CdmAssemblerException(CdmExceptionTag.ASM, segment.location.file, segment.location.line, message)


# noinspection DuplicatedCode
Expand Down
13 changes: 6 additions & 7 deletions cocas/assembler/targets/cdm8/target_instructions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@

from bitstruct import pack

from cocas.error import CdmException, CdmExceptionTag, CdmTempException

from ...ast_nodes import InstructionNode, LabelNode, RegisterNode, RelocatableExpressionNode
from ...exceptions import CdmAssemblerException, CdmExceptionTag, CdmTempException
from .. import ICodeSegment, TargetInstructionsInterface
from .code_segments import AlignmentPaddingSegment, BytesSegment, ExpressionSegment

Expand Down Expand Up @@ -49,10 +48,10 @@ def assemble_instruction(line: InstructionNode, temp_storage: dict) -> list[ICod
return h.handler(line, temp_storage, h.instructions[line.mnemonic])
if line.mnemonic.startswith('b'):
return TargetInstructions.branch(line)
raise CdmException(CdmExceptionTag.ASM, line.location.file, line.location.line,
f'Unknown instruction "{line.mnemonic}"')
raise CdmAssemblerException(CdmExceptionTag.ASM, line.location.file, line.location.line,
f'Unknown instruction "{line.mnemonic}"')
except CdmTempException as e:
raise CdmException(CdmExceptionTag.ASM, line.location.file, line.location.line, e.message)
raise CdmAssemblerException(CdmExceptionTag.ASM, line.location.file, line.location.line, e.message)

@staticmethod
def finish(temp_storage: dict):
Expand Down Expand Up @@ -156,8 +155,8 @@ def branch(line: InstructionNode, inverse=False) -> list[ICodeSegment]:
branch_code = pair.inv_code if not inverse else pair.code
break
else:
raise CdmException(CdmExceptionTag.ASM, line.location.file, line.location.line,
f'Invalid branch condition: {cond}')
raise CdmAssemblerException(CdmExceptionTag.ASM, line.location.file, line.location.line,
f'Invalid branch condition: {cond}')
assert_count_args(line.arguments, RelocatableExpressionNode)
return [BytesSegment(pack('u4u4', 0xE, branch_code), line.location),
ExpressionSegment(line.arguments[0], line.location)]
Expand Down
8 changes: 4 additions & 4 deletions cocas/assembler/targets/cdm8e/code_segments.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
from dataclasses import dataclass, field
from typing import TYPE_CHECKING

from cocas.error import CdmException, CdmExceptionTag
from cocas.object_module import CodeLocation, ExternalEntry

from ...ast_nodes import LabelNode, RelocatableExpressionNode, TemplateFieldNode
from ...exceptions import CdmAssemblerException, CdmExceptionTag
from .. import ICodeSegment, IVaryingLengthSegment
from .simple_instructions import simple_instructions

Expand Down Expand Up @@ -178,10 +178,10 @@ def update_varying_length(self, pos: int, section: "Section", labels: dict[str,
if label_name in labels:
labels[label_name] += shift_length
return shift_length
except CdmException as e:
except CdmAssemblerException as e:
raise e
except Exception as e:
raise CdmException(TAG, self.location.file, self.location.line, str(e))
raise CdmAssemblerException(TAG, self.location.file, self.location.line, str(e))

def fill(self, object_record: "ObjectSectionRecord", section: "Section", labels: dict[str, int],
templates: dict[str, dict[str, int]]):
Expand All @@ -201,7 +201,7 @@ def fill(self, object_record: "ObjectSectionRecord", section: "Section", labels:


def _error(segment: ICodeSegment, message: str):
raise CdmException(TAG, segment.location.file, segment.location.line, message)
raise CdmAssemblerException(TAG, segment.location.file, segment.location.line, message)


def eval_rel_expr_seg(seg: RelocatableExpressionSegment, s: "Section",
Expand Down
5 changes: 2 additions & 3 deletions cocas/assembler/targets/cdm8e/target_instructions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

import bitstruct

from cocas.error import CdmException, CdmExceptionTag, CdmTempException

from ...ast_nodes import InstructionNode, LabelNode, RegisterNode, RelocatableExpressionNode
from ...exceptions import CdmAssemblerException, CdmExceptionTag, CdmTempException
from .. import ICodeSegment, TargetInstructionsInterface
from .code_segments import (
BytesSegment,
Expand Down Expand Up @@ -54,7 +53,7 @@ def assemble_instruction(line: InstructionNode, temp_storage) \
segment.location = line.location
return segments
except CdmTempException as e:
raise CdmException(CdmExceptionTag.ASM, line.location.file, line.location.line, e.message)
raise CdmAssemblerException(CdmExceptionTag.ASM, line.location.file, line.location.line, e.message)

@staticmethod
def finish(temp_storage: dict):
Expand Down
35 changes: 35 additions & 0 deletions cocas/exception_handlers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from colorama import Fore, Style

from cocas.assembler import CdmAssemblerException
from cocas.linker import CdmLinkException
from cocas.object_file import CdmObjectFileException


def log_exception(tag: str, message: str):
print(f'[{tag}] {Fore.RED}ERROR{Fore.RESET}')
print(message)


def log_os_error(e: OSError):
message = e.strerror
if e.filename is not None:
message += f': {Style.BRIGHT}{e.filename}{Style.NORMAL}'
log_exception("Main", message)
exit(1)


def log_asm_exception(e: CdmAssemblerException):
print(f'[{e.tag.value}] {Fore.RED}ERROR{Fore.RESET} at line {Style.BRIGHT}{e.line}{Style.RESET_ALL} of '
f'{Style.BRIGHT}{e.file}{Style.RESET_ALL}')
print(f'{e.description}')


def log_object_file_exception(e: CdmObjectFileException):
print(f'[Object file] {Fore.RED}ERROR{Fore.RESET} at line {Style.BRIGHT}{e.line}{Style.RESET_ALL} of '
f'{Style.BRIGHT}{e.file}{Style.RESET_ALL}')
print(f'{e.description}')


def log_link_exception(_: CdmLinkException):
# todo: find this code from previous revisions
pass
1 change: 1 addition & 0 deletions cocas/linker/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from .debug_export import debug_export, write_debug_export
from .exceptions import CdmLinkException
from .image import write_image
from .linker import link
Loading

0 comments on commit d9defbc

Please sign in to comment.