Module refinery.lib.batch.model

Expand source code Browse git
from __future__ import annotations

import enum
import io

from dataclasses import dataclass, field
from typing import Generic, TypeVar, Union

from refinery.lib.batch.const import TILDE
from refinery.lib.structures import FlagAccessMixin

IntOrStr = TypeVar('IntOrStr', int, str)


class Ctrl(str, enum.Enum):
    NewLine             = '\n'  # noqa;
    NewGroup            = '('   # noqa;
    EndGroup            = ')'   # noqa;
    RunOnSuccess        = '&&'  # noqa;
    RunOnFailure        = '||'  # noqa;
    CommandSeparator    = '&'   # noqa;
    Pipe                = '|'   # noqa;
    EndOfFile           = ''    # noqa;
    Label               = ':'   # noqa;
    Equals              = '='   # noqa;
    IsEqualTo           = '=='  # noqa;

    def __str__(self):
        return self.value


class Word(str):
    pass


class Expected(str):
    pass


class Redirect(str, enum.Enum):
    Out = '>'
    OutAppend = '>>'
    In = '<'

    def __str__(self):
        return self.value


@dataclass
class RedirectIO:
    type: Redirect
    source: int
    target: int | str = -1

    @property
    def target_is_file(self) -> bool:
        return isinstance(self.target, str)

    @property
    def outbound(self):
        return self.type in (Redirect.Out, Redirect.OutAppend)

    def __str__(self):
        target = self.target
        string = F'{self.source}{self.type!s}'
        if target is None:
            return string
        return F'{string}{target}'

    def isspace(self):
        return False

    def upper(self):
        return None


Token = Union[str, Ctrl, RedirectIO]


class ArgVarFlags(FlagAccessMixin, enum.IntFlag):
    Empty = 0

    q = 0b0000_00001
    d = 0b0000_00010
    p = 0b0000_00100
    n = 0b0000_01000
    x = 0b0000_10000
    s = 0b0001_00000
    a = 0b0010_00000
    t = 0b0100_00000
    z = 0b1000_00000
    f = d | p | n | x

    StripQuotes = q # noqa
    FullPath    = f # noqa
    DriveLetter = d # noqa
    PathOnly    = p # noqa
    NameOnly    = n # noqa
    Extension   = x # noqa
    ShortName   = s # noqa
    Attributes  = a # noqa
    DateTime    = t # noqa
    FileSize    = z # noqa

    def __str__(self):
        options = self.__class__
        value = self.value
        string = ''
        for flag, char in (
            (options.q, '~'),
            (options.f, 'f'),
        ):
            if value & flag == flag:
                string += char
                value ^= flag
        for flag in options:
            if value & flag == flag:
                assert flag.name
                string += flag.name
        return string

    @classmethod
    def FromToken(cls, t: int):
        if t == TILDE:
            return cls(1)
        return cls[chr(t)]


@dataclass
class ArgVar:
    offset: int | ellipsis = 0
    path: str | None = None
    flags: ArgVarFlags = ArgVarFlags.Empty

    def __str__(self):
        k = self.offset
        if k is (...):
            assert self.path is None
            assert self.flags is ArgVarFlags.Empty
            return '%*'
        p = F'${p}' if (p := self.path) is not None else ''
        return F'%{self.flags!s}{p}{k}'


class AstCondition(str, enum.Enum):
    NoCheck = '&'
    Success = '&&'
    Failure = '||'

    @classmethod
    def Try(cls, value):
        try:
            return cls(value)
        except ValueError:
            return None

    def __str__(self):
        return self.value


@dataclass
class AstNode:
    offset: int


@dataclass
class AstStatement(AstNode):
    ...


@dataclass
class AstLabel(AstStatement):
    line: str = ''
    label: str = ''


@dataclass
class AstCommand(AstNode):
    tokens: list[str | RedirectIO] = field(default_factory=list)


@dataclass
class AstSet(AstCommand):
    name: str = ""
    value: str = ""


@dataclass
class AstPipeline(AstStatement):
    parts: list[AstCommand] = field(default_factory=list)


@dataclass
class AstConditionalStatement(AstNode):
    condition: AstCondition
    statement: AstStatement


@dataclass
class AstSequence(AstStatement):
    head: AstStatement
    tail: list[AstConditionalStatement] = field(default_factory=list)


@dataclass
class AstGroup(AstStatement):
    sequences: list[AstSequence] = field(default_factory=list)


class AstForVariant(str, enum.Enum):
    D = 'D'
    R = 'R'
    L = 'L'
    F = 'F'
    Default = ''
    Folders = D
    Recurse = R
    Numbers = L
    FileSet = F


@dataclass
class AstFor(AstStatement):
    variant: AstForVariant
    variable: str
    body: AstNode
    spec: str | range
    path: str | None = None
    options: str | None = None


class AstIfVariant(str, enum.Enum):
    Defined = 'DEFINED'             # IF DEFINED VARIABLE
    CmdExtVersion = 'CMDEXTVERSION' # IF CMDEXTVERSION NUMBER
    Exist = 'EXIST'                 # IF EXIST PATH
    ErrorLevel = 'ERRORLEVEL'       # IF ERRORLEVEL NUMBER


class AstIfCmp(str, enum.Enum):
    STR = '=='
    EQU = 'EQU'
    NEQ = 'NEQ'
    LSS = 'LSS'
    LEQ = 'LEQ'
    GTR = 'GTR'
    GEQ = 'GEQ'


@dataclass
class AstIf(AstStatement, Generic[IntOrStr]):
    then_do: AstStatement
    else_do: AstStatement | None = None
    variant: AstIfVariant | None = None
    casefold: bool = True
    negated: bool = False
    cmp: AstIfCmp | None = None
    lhs: IntOrStr | None = None
    rhs: IntOrStr | None = None

    @property
    def var_int(self):
        var = self.lhs
        if not isinstance(var, int):
            raise RuntimeError
        return var

    @property
    def var_str(self):
        var = self.lhs
        if not isinstance(var, str):
            raise RuntimeError
        return var


class If(enum.IntFlag):
    Inactive = 0b0000
    Active = 0b0001
    Block = 0b0010
    Then = 0b0100
    Else = 0b1000

    def skip_block(self):
        skip = If.Then not in self
        if If.Else in self:
            skip = not skip
        return skip


class EmulatorException(Exception):
    pass


class EmulatorLongJump(EmulatorException):
    pass


class Goto(EmulatorLongJump):
    def __init__(self, label: str):
        self.label = label


class Call(EmulatorLongJump):
    def __init__(self, label: str, offset: int):
        self.label = label
        self.offset = offset


class Exit(EmulatorLongJump):
    def __init__(self, code: int, exit: bool):
        self.code = code
        self.exit = exit


class UnexpectedEOF(EmulatorException, EOFError):
    pass


class UnexpectedToken(EmulatorException):
    def __init__(self, token, msg: str | None = None) -> None:
        if isinstance(token, int):
            token = chr(token)
        else:
            token = str(token)
        end = msg and F': {msg}' or '.'
        super().__init__(F'The token "{token}" was unexpected{end}')


class UnexpectedFirstToken(UnexpectedToken):
    def __init__(self, token: str | int) -> None:
        super().__init__(token, 'This token may not occur as the first token in a line.')


class InvalidLabel(EmulatorException):
    def __init__(self, label: str):
        self.label = label

    def __str__(self):
        return F'The following label was not found: {self.label}'


class EmulatorCommand:
    ast: AstCommand
    args: list[str]
    verb: str
    redirects: list[RedirectIO]

    def __init__(self, ast_command: AstCommand):
        self.ast = ast_command
        self.redirects = []
        self.args = []
        self.verb = ''
        argstr = io.StringIO()
        for token in ast_command.tokens:
            if isinstance(token, RedirectIO):
                self.redirects.append(token)
                continue
            if token.isspace():
                if self.verb:
                    argstr.write(token)
                continue
            if not self.verb:
                self.verb = token.strip()
                continue
            self.args.append(token)
            argstr.write(token)
        if not self.verb:
            raise ValueError('Empty Command')
        self.argument_string = argstr.getvalue().lstrip()

    def __str__(self):
        return ''.join(str(t) for t in self.ast.tokens).lstrip()

Classes

class Ctrl (*args, **kwds)

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to 'utf-8'. errors defaults to 'strict'.

Expand source code Browse git
class Ctrl(str, enum.Enum):
    NewLine             = '\n'  # noqa;
    NewGroup            = '('   # noqa;
    EndGroup            = ')'   # noqa;
    RunOnSuccess        = '&&'  # noqa;
    RunOnFailure        = '||'  # noqa;
    CommandSeparator    = '&'   # noqa;
    Pipe                = '|'   # noqa;
    EndOfFile           = ''    # noqa;
    Label               = ':'   # noqa;
    Equals              = '='   # noqa;
    IsEqualTo           = '=='  # noqa;

    def __str__(self):
        return self.value

Ancestors

  • builtins.str
  • enum.Enum

Class variables

var NewLine

The type of the None singleton.

var NewGroup

The type of the None singleton.

var EndGroup

The type of the None singleton.

var RunOnSuccess

The type of the None singleton.

var RunOnFailure

The type of the None singleton.

var CommandSeparator

The type of the None singleton.

var Pipe

The type of the None singleton.

var EndOfFile

The type of the None singleton.

var Label

The type of the None singleton.

var Equals

The type of the None singleton.

var IsEqualTo

The type of the None singleton.

class Word (...)

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to 'utf-8'. errors defaults to 'strict'.

Expand source code Browse git
class Word(str):
    pass

Ancestors

  • builtins.str
class Expected (...)

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to 'utf-8'. errors defaults to 'strict'.

Expand source code Browse git
class Expected(str):
    pass

Ancestors

  • builtins.str
class Redirect (*args, **kwds)

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to 'utf-8'. errors defaults to 'strict'.

Expand source code Browse git
class Redirect(str, enum.Enum):
    Out = '>'
    OutAppend = '>>'
    In = '<'

    def __str__(self):
        return self.value

Ancestors

  • builtins.str
  • enum.Enum

Class variables

var Out

The type of the None singleton.

var OutAppend

The type of the None singleton.

var In

The type of the None singleton.

class RedirectIO (type, source, target=-1)

RedirectIO(type: 'Redirect', source: 'int', target: 'int | str' = -1)

Expand source code Browse git
@dataclass
class RedirectIO:
    type: Redirect
    source: int
    target: int | str = -1

    @property
    def target_is_file(self) -> bool:
        return isinstance(self.target, str)

    @property
    def outbound(self):
        return self.type in (Redirect.Out, Redirect.OutAppend)

    def __str__(self):
        target = self.target
        string = F'{self.source}{self.type!s}'
        if target is None:
            return string
        return F'{string}{target}'

    def isspace(self):
        return False

    def upper(self):
        return None

Instance variables

var type

The type of the None singleton.

var source

The type of the None singleton.

var target

The type of the None singleton.

var target_is_file
Expand source code Browse git
@property
def target_is_file(self) -> bool:
    return isinstance(self.target, str)
var outbound
Expand source code Browse git
@property
def outbound(self):
    return self.type in (Redirect.Out, Redirect.OutAppend)

Methods

def isspace(self)
Expand source code Browse git
def isspace(self):
    return False
def upper(self)
Expand source code Browse git
def upper(self):
    return None
class ArgVarFlags (*args, **kwds)

This class can be mixed into an enum.IntFlag for some quality of life improvements. Firstly, you can now access flags as follows:

class Flags(FlagAccessMixin, enum.IntFlag):
    IsBinary = 1
    IsCompressed = 2

flag = Flags(3)

if flag.IsCompressed:
    decompress()

Furthermore, flag values can be enumerated:

>>> list(flag)
[IsBinary, IsCompressed]
>>> flag
IsBinary|IsCompressed

And finally, as visible from the above output, flag values are represented by their name by default.

Expand source code Browse git
class ArgVarFlags(FlagAccessMixin, enum.IntFlag):
    Empty = 0

    q = 0b0000_00001
    d = 0b0000_00010
    p = 0b0000_00100
    n = 0b0000_01000
    x = 0b0000_10000
    s = 0b0001_00000
    a = 0b0010_00000
    t = 0b0100_00000
    z = 0b1000_00000
    f = d | p | n | x

    StripQuotes = q # noqa
    FullPath    = f # noqa
    DriveLetter = d # noqa
    PathOnly    = p # noqa
    NameOnly    = n # noqa
    Extension   = x # noqa
    ShortName   = s # noqa
    Attributes  = a # noqa
    DateTime    = t # noqa
    FileSize    = z # noqa

    def __str__(self):
        options = self.__class__
        value = self.value
        string = ''
        for flag, char in (
            (options.q, '~'),
            (options.f, 'f'),
        ):
            if value & flag == flag:
                string += char
                value ^= flag
        for flag in options:
            if value & flag == flag:
                assert flag.name
                string += flag.name
        return string

    @classmethod
    def FromToken(cls, t: int):
        if t == TILDE:
            return cls(1)
        return cls[chr(t)]

Ancestors

  • FlagAccessMixin
  • enum.IntFlag
  • builtins.int
  • enum.ReprEnum
  • enum.Flag
  • enum.Enum

Class variables

var Empty

The type of the None singleton.

var q

The type of the None singleton.

var d

The type of the None singleton.

var p

The type of the None singleton.

var n

The type of the None singleton.

var x

The type of the None singleton.

var s

The type of the None singleton.

var a

The type of the None singleton.

var t

The type of the None singleton.

var z

The type of the None singleton.

var f

The type of the None singleton.

var StripQuotes

The type of the None singleton.

var FullPath

The type of the None singleton.

var DriveLetter

The type of the None singleton.

var PathOnly

The type of the None singleton.

var NameOnly

The type of the None singleton.

var Extension

The type of the None singleton.

var ShortName

The type of the None singleton.

var Attributes

The type of the None singleton.

var DateTime

The type of the None singleton.

var FileSize

The type of the None singleton.

Static methods

def FromToken(t)
class ArgVar (offset=0, path=None, flags=Empty)

ArgVar(offset: 'int | ellipsis' = 0, path: 'str | None' = None, flags: 'ArgVarFlags' = Empty)

Expand source code Browse git
@dataclass
class ArgVar:
    offset: int | ellipsis = 0
    path: str | None = None
    flags: ArgVarFlags = ArgVarFlags.Empty

    def __str__(self):
        k = self.offset
        if k is (...):
            assert self.path is None
            assert self.flags is ArgVarFlags.Empty
            return '%*'
        p = F'${p}' if (p := self.path) is not None else ''
        return F'%{self.flags!s}{p}{k}'

Instance variables

var offset

The type of the None singleton.

var path

The type of the None singleton.

var flags

The type of the None singleton.

class AstCondition (*args, **kwds)

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to 'utf-8'. errors defaults to 'strict'.

Expand source code Browse git
class AstCondition(str, enum.Enum):
    NoCheck = '&'
    Success = '&&'
    Failure = '||'

    @classmethod
    def Try(cls, value):
        try:
            return cls(value)
        except ValueError:
            return None

    def __str__(self):
        return self.value

Ancestors

  • builtins.str
  • enum.Enum

Class variables

var NoCheck

The type of the None singleton.

var Success

The type of the None singleton.

var Failure

The type of the None singleton.

Static methods

def Try(value)
class AstNode (offset)

AstNode(offset: 'int')

Expand source code Browse git
@dataclass
class AstNode:
    offset: int

Subclasses

Instance variables

var offset

The type of the None singleton.

class AstStatement (offset)

AstStatement(offset: 'int')

Expand source code Browse git
@dataclass
class AstStatement(AstNode):
    ...

Ancestors

Subclasses

Inherited members

class AstLabel (offset, line='', label='')

AstLabel(offset: 'int', line: 'str' = '', label: 'str' = '')

Expand source code Browse git
@dataclass
class AstLabel(AstStatement):
    line: str = ''
    label: str = ''

Ancestors

Instance variables

var line

The type of the None singleton.

var label

The type of the None singleton.

Inherited members

class AstCommand (offset, tokens=<factory>)

AstCommand(offset: 'int', tokens: 'list[str | RedirectIO]' = )

Expand source code Browse git
@dataclass
class AstCommand(AstNode):
    tokens: list[str | RedirectIO] = field(default_factory=list)

Ancestors

Subclasses

Instance variables

var tokens

The type of the None singleton.

Inherited members

class AstSet (offset, tokens=<factory>, name='', value='')

AstSet(offset: 'int', tokens: 'list[str | RedirectIO]' = , name: 'str' = '', value: 'str' = '')

Expand source code Browse git
@dataclass
class AstSet(AstCommand):
    name: str = ""
    value: str = ""

Ancestors

Instance variables

var name

The type of the None singleton.

var value

The type of the None singleton.

Inherited members

class AstPipeline (offset, parts=<factory>)

AstPipeline(offset: 'int', parts: 'list[AstCommand]' = )

Expand source code Browse git
@dataclass
class AstPipeline(AstStatement):
    parts: list[AstCommand] = field(default_factory=list)

Ancestors

Instance variables

var parts

The type of the None singleton.

Inherited members

class AstConditionalStatement (offset, condition, statement)

AstConditionalStatement(offset: 'int', condition: 'AstCondition', statement: 'AstStatement')

Expand source code Browse git
@dataclass
class AstConditionalStatement(AstNode):
    condition: AstCondition
    statement: AstStatement

Ancestors

Instance variables

var condition

The type of the None singleton.

var statement

The type of the None singleton.

Inherited members

class AstSequence (offset, head, tail=<factory>)

AstSequence(offset: 'int', head: 'AstStatement', tail: 'list[AstConditionalStatement]' = )

Expand source code Browse git
@dataclass
class AstSequence(AstStatement):
    head: AstStatement
    tail: list[AstConditionalStatement] = field(default_factory=list)

Ancestors

Instance variables

var head

The type of the None singleton.

var tail

The type of the None singleton.

Inherited members

class AstGroup (offset, sequences=<factory>)

AstGroup(offset: 'int', sequences: 'list[AstSequence]' = )

Expand source code Browse git
@dataclass
class AstGroup(AstStatement):
    sequences: list[AstSequence] = field(default_factory=list)

Ancestors

Instance variables

var sequences

The type of the None singleton.

Inherited members

class AstForVariant (*args, **kwds)

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to 'utf-8'. errors defaults to 'strict'.

Expand source code Browse git
class AstForVariant(str, enum.Enum):
    D = 'D'
    R = 'R'
    L = 'L'
    F = 'F'
    Default = ''
    Folders = D
    Recurse = R
    Numbers = L
    FileSet = F

Ancestors

  • builtins.str
  • enum.Enum

Class variables

var D

The type of the None singleton.

var R

The type of the None singleton.

var L

The type of the None singleton.

var F

The type of the None singleton.

var Default

The type of the None singleton.

var Folders

The type of the None singleton.

var Recurse

The type of the None singleton.

var Numbers

The type of the None singleton.

var FileSet

The type of the None singleton.

class AstFor (offset, variant, variable, body, spec, path=None, options=None)

AstFor(offset: 'int', variant: 'AstForVariant', variable: 'str', body: 'AstNode', spec: 'str | range', path: 'str | None' = None, options: 'str | None' = None)

Expand source code Browse git
@dataclass
class AstFor(AstStatement):
    variant: AstForVariant
    variable: str
    body: AstNode
    spec: str | range
    path: str | None = None
    options: str | None = None

Ancestors

Instance variables

var variant

The type of the None singleton.

var variable

The type of the None singleton.

var body

The type of the None singleton.

var spec

The type of the None singleton.

var path

The type of the None singleton.

var options

The type of the None singleton.

Inherited members

class AstIfVariant (*args, **kwds)

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to 'utf-8'. errors defaults to 'strict'.

Expand source code Browse git
class AstIfVariant(str, enum.Enum):
    Defined = 'DEFINED'             # IF DEFINED VARIABLE
    CmdExtVersion = 'CMDEXTVERSION' # IF CMDEXTVERSION NUMBER
    Exist = 'EXIST'                 # IF EXIST PATH
    ErrorLevel = 'ERRORLEVEL'       # IF ERRORLEVEL NUMBER

Ancestors

  • builtins.str
  • enum.Enum

Class variables

var Defined

The type of the None singleton.

var CmdExtVersion

The type of the None singleton.

var Exist

The type of the None singleton.

var ErrorLevel

The type of the None singleton.

class AstIfCmp (*args, **kwds)

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to 'utf-8'. errors defaults to 'strict'.

Expand source code Browse git
class AstIfCmp(str, enum.Enum):
    STR = '=='
    EQU = 'EQU'
    NEQ = 'NEQ'
    LSS = 'LSS'
    LEQ = 'LEQ'
    GTR = 'GTR'
    GEQ = 'GEQ'

Ancestors

  • builtins.str
  • enum.Enum

Class variables

var STR

The type of the None singleton.

var EQU

The type of the None singleton.

var NEQ

The type of the None singleton.

var LSS

The type of the None singleton.

var LEQ

The type of the None singleton.

var GTR

The type of the None singleton.

var GEQ

The type of the None singleton.

class AstIf (offset, then_do, else_do=None, variant=None, casefold=True, negated=False, cmp=None, lhs=None, rhs=None)

AstIf(offset: 'int', then_do: 'AstStatement', else_do: 'AstStatement | None' = None, variant: 'AstIfVariant | None' = None, casefold: 'bool' = True, negated: 'bool' = False, cmp: 'AstIfCmp | None' = None, lhs: 'IntOrStr | None' = None, rhs: 'IntOrStr | None' = None)

Expand source code Browse git
@dataclass
class AstIf(AstStatement, Generic[IntOrStr]):
    then_do: AstStatement
    else_do: AstStatement | None = None
    variant: AstIfVariant | None = None
    casefold: bool = True
    negated: bool = False
    cmp: AstIfCmp | None = None
    lhs: IntOrStr | None = None
    rhs: IntOrStr | None = None

    @property
    def var_int(self):
        var = self.lhs
        if not isinstance(var, int):
            raise RuntimeError
        return var

    @property
    def var_str(self):
        var = self.lhs
        if not isinstance(var, str):
            raise RuntimeError
        return var

Ancestors

Instance variables

var then_do

The type of the None singleton.

var else_do

The type of the None singleton.

var variant

The type of the None singleton.

var casefold

The type of the None singleton.

var negated

The type of the None singleton.

var cmp

The type of the None singleton.

var lhs

The type of the None singleton.

var rhs

The type of the None singleton.

var var_int
Expand source code Browse git
@property
def var_int(self):
    var = self.lhs
    if not isinstance(var, int):
        raise RuntimeError
    return var
var var_str
Expand source code Browse git
@property
def var_str(self):
    var = self.lhs
    if not isinstance(var, str):
        raise RuntimeError
    return var

Inherited members

class If (*args, **kwds)

Support for integer-based Flags

Expand source code Browse git
class If(enum.IntFlag):
    Inactive = 0b0000
    Active = 0b0001
    Block = 0b0010
    Then = 0b0100
    Else = 0b1000

    def skip_block(self):
        skip = If.Then not in self
        if If.Else in self:
            skip = not skip
        return skip

Ancestors

  • enum.IntFlag
  • builtins.int
  • enum.ReprEnum
  • enum.Flag
  • enum.Enum

Class variables

var Inactive

The type of the None singleton.

var Active

The type of the None singleton.

var Block

The type of the None singleton.

var Then

The type of the None singleton.

var Else

The type of the None singleton.

Methods

def skip_block(self)
Expand source code Browse git
def skip_block(self):
    skip = If.Then not in self
    if If.Else in self:
        skip = not skip
    return skip
class EmulatorException (*args, **kwargs)

Common base class for all non-exit exceptions.

Expand source code Browse git
class EmulatorException(Exception):
    pass

Ancestors

  • builtins.Exception
  • builtins.BaseException

Subclasses

class EmulatorLongJump (*args, **kwargs)

Common base class for all non-exit exceptions.

Expand source code Browse git
class EmulatorLongJump(EmulatorException):
    pass

Ancestors

Subclasses

class Goto (label)

Common base class for all non-exit exceptions.

Expand source code Browse git
class Goto(EmulatorLongJump):
    def __init__(self, label: str):
        self.label = label

Ancestors

class Call (label, offset)

Common base class for all non-exit exceptions.

Expand source code Browse git
class Call(EmulatorLongJump):
    def __init__(self, label: str, offset: int):
        self.label = label
        self.offset = offset

Ancestors

class Exit (code, exit)

Common base class for all non-exit exceptions.

Expand source code Browse git
class Exit(EmulatorLongJump):
    def __init__(self, code: int, exit: bool):
        self.code = code
        self.exit = exit

Ancestors

class UnexpectedEOF (*args, **kwargs)

Read beyond end of file.

Expand source code Browse git
class UnexpectedEOF(EmulatorException, EOFError):
    pass

Ancestors

class UnexpectedToken (token, msg=None)

Common base class for all non-exit exceptions.

Expand source code Browse git
class UnexpectedToken(EmulatorException):
    def __init__(self, token, msg: str | None = None) -> None:
        if isinstance(token, int):
            token = chr(token)
        else:
            token = str(token)
        end = msg and F': {msg}' or '.'
        super().__init__(F'The token "{token}" was unexpected{end}')

Ancestors

Subclasses

class UnexpectedFirstToken (token)

Common base class for all non-exit exceptions.

Expand source code Browse git
class UnexpectedFirstToken(UnexpectedToken):
    def __init__(self, token: str | int) -> None:
        super().__init__(token, 'This token may not occur as the first token in a line.')

Ancestors

class InvalidLabel (label)

Common base class for all non-exit exceptions.

Expand source code Browse git
class InvalidLabel(EmulatorException):
    def __init__(self, label: str):
        self.label = label

    def __str__(self):
        return F'The following label was not found: {self.label}'

Ancestors

class EmulatorCommand (ast_command)
Expand source code Browse git
class EmulatorCommand:
    ast: AstCommand
    args: list[str]
    verb: str
    redirects: list[RedirectIO]

    def __init__(self, ast_command: AstCommand):
        self.ast = ast_command
        self.redirects = []
        self.args = []
        self.verb = ''
        argstr = io.StringIO()
        for token in ast_command.tokens:
            if isinstance(token, RedirectIO):
                self.redirects.append(token)
                continue
            if token.isspace():
                if self.verb:
                    argstr.write(token)
                continue
            if not self.verb:
                self.verb = token.strip()
                continue
            self.args.append(token)
            argstr.write(token)
        if not self.verb:
            raise ValueError('Empty Command')
        self.argument_string = argstr.getvalue().lstrip()

    def __str__(self):
        return ''.join(str(t) for t in self.ast.tokens).lstrip()

Class variables

var ast

The type of the None singleton.

var args

The type of the None singleton.

var verb

The type of the None singleton.

var redirects

The type of the None singleton.