@ -0,0 +1 @@ | |||
__pycache__/ |
@ -0,0 +1,24 @@ | |||
from gbso.insn import * | |||
from gbso.optimize import optimize | |||
from gbso.program import Program | |||
from gbso.regs import R8, R16 | |||
rLCDC = 0xFF40 | |||
rIE = 0xFFFF | |||
IEF_VBLANK = 1 << 0 | |||
prgm = Program( | |||
outputs=set([R8.A]), | |||
insns=[ | |||
LD_RR_NN(R16.HL, rLCDC), | |||
RES_N_HL(7), | |||
RES_N_HL(2), | |||
LD_RR_NN(R16.HL, rIE), | |||
LD_HL_N(IEF_VBLANK), | |||
], | |||
) | |||
prgm_opt = optimize(prgm) | |||
for insn in prgm_opt.insns: | |||
print(insn.pretty()) |
@ -0,0 +1 @@ | |||
__version__ = '0.1.0' |
@ -0,0 +1,32 @@ | |||
from gbso.regs import R8, R16 | |||
class CPU: | |||
carry: int | |||
def __init__(self) -> None: | |||
self.carry = 0 | |||
def get_reg8(self, r: R8) -> int: | |||
pass | |||
def get_reg16(self, rr: R16) -> int: | |||
pass | |||
def set_reg8(self, r: R8, n: int) -> None: | |||
pass | |||
def set_reg16(self, r: R16, nn: int) -> None: | |||
pass | |||
def get_mem8(self, nn: int) -> int: | |||
pass | |||
def get_mem16(self, nn: int) -> int: | |||
pass | |||
def set_mem8(self, nn: int, n: int) -> None: | |||
pass | |||
def set_mem16(self, nn: int, nn1: int) -> None: | |||
pass |
@ -0,0 +1,576 @@ | |||
from abc import ABC, abstractmethod | |||
from dataclasses import dataclass | |||
from gbso.cpu import CPU | |||
from gbso.regs import R16, R8 | |||
class Insn(ABC): | |||
@abstractmethod | |||
def exec(self, cpu: CPU) -> None: | |||
pass | |||
# TODO: Make abstract once all subclasses implement | |||
def pretty(self) -> str: | |||
return "" | |||
@dataclass | |||
class LD_R_R(Insn): | |||
dst: R8 | |||
src: R8 | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.set_reg8(self.dst, cpu.get_reg8(self.src)) | |||
def pretty(self) -> str: | |||
return f"LD {self.dst}, {self.src}" | |||
@dataclass | |||
class LD_R_N8(Insn): | |||
dst: R8 | |||
imm: int | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.set_reg8(self.dst, self.imm) | |||
@dataclass | |||
class LD_R_HL(Insn): | |||
dst: R8 | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.set_reg8(self.dst, cpu.get_mem8(cpu.get_reg16(R16.HL))) | |||
@dataclass | |||
class LD_HL_R(Insn): | |||
src: R8 | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.set_mem8(cpu.get_reg16(R16.HL), cpu.get_reg8(self.src)) | |||
@dataclass | |||
class LD_HL_N(Insn): | |||
imm: int | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.set_mem8(cpu.get_reg16(R16.HL), self.imm) | |||
def pretty(self) -> str: | |||
return f"LD (HL), {hex(self.imm & 0xff)}" | |||
@dataclass | |||
class LD_A_BC(Insn): | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.set_reg8(R8.A, cpu.get_mem8(cpu.get_reg16(R16.BC))) | |||
@dataclass | |||
class LD_A_DE(Insn): | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.set_reg8(R8.A, cpu.get_mem8(cpu.get_reg16(R16.DE))) | |||
@dataclass | |||
class LD_A_NN(Insn): | |||
nn: int | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.set_reg8(R8.A, cpu.get_mem8(self.nn)) | |||
@dataclass | |||
class LD_BC_A(Insn): | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.set_mem8(cpu.get_reg16(R16.BC), cpu.get_reg8(R8.A)) | |||
@dataclass | |||
class LD_DE_A(Insn): | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.set_mem8(cpu.get_reg16(R16.DE), cpu.get_reg8(R8.A)) | |||
@dataclass | |||
class LD_NN_A(Insn): | |||
nn: int | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.set_mem8(self.nn, cpu.get_reg8(R8.A)) | |||
@dataclass | |||
class LD_A_FF_N(Insn): | |||
n: int | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.set_reg8(R8.A, cpu.get_mem8(0xFF00 + self.n)) | |||
@dataclass | |||
class LD_FF_N_A(Insn): | |||
n: int | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.set_mem8(0xFF00 + self.n, cpu.get_reg8(R8.A)) | |||
@dataclass | |||
class LD_A_FF_C(Insn): | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.set_reg8(R8.A, cpu.get_mem8(0xFF00 + cpu.get_reg8(R8.C))) | |||
@dataclass | |||
class LD_FF_C_A(Insn): | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.set_mem8(0xFF00 + cpu.get_reg8(R8.C), cpu.get_reg8(R8.A)) | |||
@dataclass | |||
class LDI_HL_A(Insn): | |||
def exec(self, cpu: CPU) -> None: | |||
hl = cpu.get_reg16(R16.HL) | |||
cpu.set_mem8(hl, cpu.get_reg8(R8.A)) | |||
cpu.set_reg16(R16.HL, hl + 1) | |||
@dataclass | |||
class LDI_A_HL(Insn): | |||
def exec(self, cpu: CPU) -> None: | |||
hl = cpu.get_reg16(R16.HL) | |||
cpu.set_reg8(R8.A, cpu.get_mem8(hl)) | |||
cpu.set_reg16(R16.HL, hl + 1) | |||
@dataclass | |||
class LDD_HL_A(Insn): | |||
def exec(self, cpu: CPU) -> None: | |||
hl = cpu.get_reg16(R16.HL) | |||
cpu.set_mem8(hl, cpu.get_reg8(R8.A)) | |||
cpu.set_reg16(R16.HL, hl - 1) | |||
@dataclass | |||
class LDD_A_HL(Insn): | |||
def exec(self, cpu: CPU) -> None: | |||
hl = cpu.get_reg16(R16.HL) | |||
cpu.set_reg8(R8.A, cpu.get_mem8(hl)) | |||
cpu.set_reg16(R16.HL, hl - 1) | |||
@dataclass | |||
class LD_RR_NN(Insn): | |||
rr: R16 | |||
nn: int | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.set_reg16(self.rr, self.nn) | |||
def pretty(self) -> str: | |||
return f"LD {self.rr.value}, {hex(self.nn)}" | |||
@dataclass | |||
class LD_NN_SP(Insn): | |||
nn: int | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.set_mem16(self.nn, cpu.get_reg16(R16.SP)) | |||
@dataclass | |||
class LD_SP_HL(Insn): | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.set_reg16(R16.SP, cpu.get_reg16(R16.HL)) | |||
@dataclass | |||
class PUSH_RR(Insn): | |||
rr: R16 | |||
def exec(self, cpu: CPU) -> None: | |||
sp = cpu.get_reg16(R16.SP) | |||
cpu.set_reg16(R16.SP, sp - 2) | |||
cpu.set_mem16(sp - 2, cpu.get_reg16(self.rr)) | |||
@dataclass | |||
class POP_RR(Insn): | |||
rr: R16 | |||
def exec(self, cpu: CPU) -> None: | |||
sp = cpu.get_reg16(R16.SP) | |||
cpu.set_reg16(self.rr, cpu.get_mem16(sp)) | |||
cpu.set_reg16(R16.SP, sp + 2) | |||
@dataclass | |||
class ADD_A_R(Insn): | |||
r: R8 | |||
def exec(self, cpu: CPU) -> None: | |||
a = cpu.get_reg8(R8.A) + cpu.get_reg8(self.r) | |||
cpu.carry = 1 if a > 0xFF else 0 | |||
cpu.set_reg8(R8.A, a) | |||
@dataclass | |||
class ADD_A_N(Insn): | |||
n: int | |||
def exec(self, cpu: CPU) -> None: | |||
a = cpu.get_reg8(R8.A) + self.n | |||
cpu.carry = 1 if a > 0xFF else 0 | |||
cpu.set_reg8(R8.A, a) | |||
@dataclass | |||
class ADD_A_HL(Insn): | |||
def exec(self, cpu: CPU) -> None: | |||
a = cpu.get_reg8(R8.A) + cpu.get_mem8(cpu.get_reg16(R16.HL)) | |||
cpu.carry = 1 if a > 0xFF else 0 | |||
cpu.set_reg8(R8.A, a) | |||
@dataclass | |||
class ADC_A_R(Insn): | |||
r: R8 | |||
def exec(self, cpu: CPU) -> None: | |||
a = cpu.get_reg8(R8.A) + cpu.get_reg8(self.r) + cpu.carry | |||
cpu.carry = 1 if a > 0xFF else 0 | |||
cpu.set_reg8(R8.A, a) | |||
@dataclass | |||
class ADC_A_N(Insn): | |||
n: int | |||
def exec(self, cpu: CPU) -> None: | |||
a = cpu.get_reg8(R8.A) + self.n + cpu.carry | |||
cpu.carry = 1 if a > 0xFF else 0 | |||
cpu.set_reg8(R8.A, a) | |||
@dataclass | |||
class ADC_A_HL(Insn): | |||
def exec(self, cpu: CPU) -> None: | |||
a = cpu.get_reg8(R8.A) + cpu.get_mem8(cpu.get_reg16(R16.HL)) + cpu.carry | |||
cpu.carry = 1 if a > 0xFF else 0 | |||
cpu.set_reg8(R8.A, a) | |||
@dataclass | |||
class SUB_A_R(Insn): | |||
r: R8 | |||
def exec(self, cpu: CPU) -> None: | |||
a = cpu.get_reg8(R8.A) - cpu.get_reg8(self.r) | |||
cpu.carry = 1 if a < 0 else 0 | |||
cpu.set_reg8(R8.A, a) | |||
@dataclass | |||
class SUB_A_N(Insn): | |||
n: int | |||
def exec(self, cpu: CPU) -> None: | |||
a = cpu.get_reg8(R8.A) - self.n | |||
cpu.carry = 1 if a < 0 else 0 | |||
cpu.set_reg8(R8.A, a) | |||
@dataclass | |||
class SUB_A_HL(Insn): | |||
def exec(self, cpu: CPU) -> None: | |||
a = cpu.get_reg8(R8.A) - cpu.get_mem8(cpu.get_reg16(R16.HL)) | |||
cpu.carry = 1 if a < 0 else 0 | |||
cpu.set_reg8(R8.A, a) | |||
@dataclass | |||
class SBC_A_R(Insn): | |||
r: R8 | |||
def exec(self, cpu: CPU) -> None: | |||
a = cpu.get_reg8(R8.A) - cpu.get_reg8(self.r) - cpu.carry | |||
cpu.carry = 1 if a < 0 else 0 | |||
cpu.set_reg8(R8.A, a) | |||
@dataclass | |||
class SBC_A_N(Insn): | |||
n: int | |||
def exec(self, cpu: CPU) -> None: | |||
a = cpu.get_reg8(R8.A) - self.n - cpu.carry | |||
cpu.carry = 1 if a < 0 else 0 | |||
cpu.set_reg8(R8.A, a) | |||
@dataclass | |||
class SBC_A_HL(Insn): | |||
def exec(self, cpu: CPU) -> None: | |||
a = cpu.get_reg8(R8.A) - cpu.get_mem8(cpu.get_reg16(R16.HL)) - cpu.carry | |||
cpu.carry = 1 if a < 0 else 0 | |||
cpu.set_reg8(R8.A, a) | |||
@dataclass | |||
class AND_A_R(Insn): | |||
r: R8 | |||
def exec(self, cpu: CPU) -> None: | |||
a = cpu.get_reg8(R8.A) & cpu.get_reg8(self.r) | |||
cpu.set_reg8(R8.A, a) | |||
cpu.carry = 0 | |||
@dataclass | |||
class AND_A_N(Insn): | |||
n: int | |||
def exec(self, cpu: CPU) -> None: | |||
a = cpu.get_reg8(R8.A) & self.n | |||
cpu.set_reg8(R8.A, a) | |||
cpu.carry = 0 | |||
@dataclass | |||
class AND_A_HL(Insn): | |||
def exec(self, cpu: CPU) -> None: | |||
a = cpu.get_reg8(R8.A) & cpu.get_mem8(cpu.get_reg16(R16.HL)) | |||
cpu.set_reg8(R8.A, a) | |||
cpu.carry = 0 | |||
@dataclass | |||
class CP_A_R(Insn): | |||
r: R8 | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.carry = 1 if cpu.get_reg8(R8.A) < cpu.get_reg8(self.r) else 0 | |||
@dataclass | |||
class CP_A_N(Insn): | |||
n: int | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.carry = 1 if cpu.get_reg8(R8.A) < self.n else 0 | |||
@dataclass | |||
class CP_A_HL(Insn): | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.carry = 1 if cpu.get_reg8(R8.A) < cpu.get_mem8(cpu.get_reg16(R16.HL)) else 0 | |||
@dataclass | |||
class INC_R(Insn): | |||
r: R8 | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.set_reg8(self.r, cpu.get_reg8(self.r) + 1) | |||
@dataclass | |||
class INC_HL(Insn): | |||
r: R8 | |||
def exec(self, cpu: CPU) -> None: | |||
hl = cpu.get_reg16(R16.HL) | |||
cpu.set_mem8(hl, cpu.get_mem8(hl) + 1) | |||
@dataclass | |||
class DEC_R(Insn): | |||
r: R8 | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.set_reg8(self.r, cpu.get_reg8(self.r) - 1) | |||
@dataclass | |||
class DEC_HL(Insn): | |||
r: R8 | |||
def exec(self, cpu: CPU) -> None: | |||
hl = cpu.get_reg16(R16.HL) | |||
cpu.set_mem8(hl, cpu.get_mem8(hl) - 1) | |||
@dataclass | |||
class CPL(Insn): | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.set_reg8(R8.A, cpu.get_reg8(R8.A) ^ 0xFF) | |||
@dataclass | |||
class ADD_HL_RR(Insn): | |||
rr: R16 | |||
def exec(self, cpu: CPU) -> None: | |||
hl = cpu.get_reg16(R16.HL) + cpu.get_reg16(self.rr) | |||
cpu.carry = 1 if hl > 0xFFFF else 0 | |||
cpu.set_reg16(R16.HL, hl) | |||
@dataclass | |||
class INC_RR(Insn): | |||
rr: R16 | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.set_reg16(self.rr, cpu.get_reg16(self.rr) + 1) | |||
def pretty(self) -> str: | |||
return f"INC {self.rr.value}" | |||
@dataclass | |||
class DEC_RR(Insn): | |||
rr: R16 | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.set_reg16(self.rr, cpu.get_reg16(self.rr) - 1) | |||
def pretty(self) -> str: | |||
return f"DEC {self.rr.value}" | |||
@dataclass | |||
class ADD_SP_DD(Insn): | |||
dd: int | |||
def exec(self, cpu: CPU) -> None: | |||
sp = cpu.get_reg16(R16.SP) + self.dd | |||
cpu.carry = 1 if sp > 0xFFFF or sp < 0 else 0 | |||
cpu.set_reg16(R16.SP, sp) | |||
@dataclass | |||
class LD_HL_SP_DD(Insn): | |||
dd: int | |||
def exec(self, cpu: CPU) -> None: | |||
sp = cpu.get_reg16(R16.SP) + self.dd | |||
cpu.carry = 1 if sp > 0xFFFF or sp < 0 else 0 | |||
cpu.set_reg16(R16.HL, sp) | |||
# TODO: Rotate and shift instructions | |||
@dataclass | |||
class RLCA(Insn): | |||
def exec(self, cpu: CPU) -> None: | |||
a = cpu.get_reg8(R8.A) | |||
cpu.carry = (a >> 7) & 1 | |||
cpu.set_reg8(R8.A, ((a << 1) & 0xFF) | cpu.carry) | |||
def pretty(self) -> str: | |||
return "RLCA" | |||
@dataclass | |||
class RLA(Insn): | |||
def exec(self, cpu: CPU) -> None: | |||
a = cpu.get_reg8(R8.A) | |||
next_carry = (a >> 7) & 1 | |||
cpu.set_reg8(R8.A, ((a << 1) & 0xFF) | cpu.carry) | |||
cpu.carry = next_carry | |||
def pretty(self) -> str: | |||
return "RLA" | |||
@dataclass | |||
class RRCA(Insn): | |||
def exec(self, cpu: CPU) -> None: | |||
a = cpu.get_reg8(R8.A) | |||
cpu.carry = a & 1 | |||
cpu.set_reg8(R8.A, (a >> 1) | (cpu.carry << 7)) | |||
def pretty(self) -> str: | |||
return "RRCA" | |||
@dataclass | |||
class RRA(Insn): | |||
def exec(self, cpu: CPU) -> None: | |||
a = cpu.get_reg8(R8.A) | |||
next_carry = a & 1 | |||
cpu.set_reg8(R8.A, (a >> 1) | (cpu.carry << 7)) | |||
cpu.carry = next_carry | |||
def pretty(self) -> str: | |||
return "RRA" | |||
@dataclass | |||
class SET_N_R(Insn): | |||
n: int | |||
r: R8 | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.set_reg8(self.r, cpu.get_reg8(self.r) | (1 << self.n)) | |||
def pretty(self) -> str: | |||
return f"SET {self.n}, (HL)" | |||
@dataclass | |||
class SET_N_HL(Insn): | |||
n: int | |||
def exec(self, cpu: CPU) -> None: | |||
hl = cpu.get_reg16(R16.HL) | |||
cpu.set_mem8(hl, cpu.get_mem8(hl) | (1 << self.n)) | |||
def pretty(self) -> str: | |||
return f"SET {self.n}, (HL)" | |||
@dataclass | |||
class RES_N_R(Insn): | |||
n: int | |||
r: R8 | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.set_reg8(self.r, cpu.get_reg8(self.r) & ~(1 << self.n)) | |||
def pretty(self) -> str: | |||
return f"RES {self.n}, (HL)" | |||
@dataclass | |||
class RES_N_HL(Insn): | |||
n: int | |||
def exec(self, cpu: CPU) -> None: | |||
hl = cpu.get_reg16(R16.HL) | |||
cpu.set_mem8(hl, cpu.get_mem8(hl) & ~(1 << self.n)) | |||
def pretty(self) -> str: | |||
return f"RES {self.n}, (HL)" | |||
@dataclass | |||
class CCF(Insn): | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.carry = cpu.carry ^ 1 | |||
def pretty(self) -> str: | |||
return "CCF" | |||
@dataclass | |||
class SCF(Insn): | |||
def exec(self, cpu: CPU) -> None: | |||
cpu.carry = 1 | |||
def pretty(self) -> str: | |||
return "SCF" |
@ -0,0 +1,5 @@ | |||
from gbso.program import Program | |||
def optimize(prgm: Program) -> Program: | |||
return prgm |
@ -0,0 +1,19 @@ | |||
from dataclasses import dataclass | |||
from typing import List, Set | |||
from gbso.cpu import CPU | |||
from gbso.insn import Insn | |||
from gbso.regs import R8 | |||
@dataclass | |||
class Program: | |||
outputs: Set[R8] | |||
insns: List[Insn] | |||
# TODO: Memory outputs | |||
# TODO: Initialization of registers/memory | |||
def execute(self, cpu: CPU) -> None: | |||
for insn in self.insns: | |||
insn.exec(cpu) |
@ -0,0 +1,19 @@ | |||
from enum import Enum | |||
class R8(Enum): | |||
A = "A" | |||
B = "B" | |||
C = "C" | |||
D = "D" | |||
E = "E" | |||
H = "H" | |||
L = "L" | |||
class R16(Enum): | |||
AF = "AF" | |||
BC = "BC" | |||
DE = "DE" | |||
HL = "HL" | |||
SP = "SP" |
@ -0,0 +1,231 @@ | |||
[[package]] | |||
name = "atomicwrites" | |||
version = "1.4.0" | |||
description = "Atomic file writes." | |||
category = "dev" | |||
optional = false | |||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" | |||
[[package]] | |||
name = "attrs" | |||
version = "21.2.0" | |||
description = "Classes Without Boilerplate" | |||
category = "dev" | |||
optional = false | |||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" | |||
[package.extras] | |||
dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit"] | |||
docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] | |||
tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface"] | |||
tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"] | |||
[[package]] | |||
name = "colorama" | |||
version = "0.4.4" | |||
description = "Cross-platform colored terminal text." | |||
category = "dev" | |||
optional = false | |||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" | |||
[[package]] | |||
name = "more-itertools" | |||
version = "8.8.0" | |||
description = "More routines for operating on iterables, beyond itertools" | |||
category = "dev" | |||
optional = false | |||
python-versions = ">=3.5" | |||
[[package]] | |||
name = "mypy" | |||
version = "0.910" | |||
description = "Optional static typing for Python" | |||
category = "dev" | |||
optional = false | |||
python-versions = ">=3.5" | |||
[package.dependencies] | |||
mypy-extensions = ">=0.4.3,<0.5.0" | |||
toml = "*" | |||
typing-extensions = ">=3.7.4" | |||
[package.extras] | |||
dmypy = ["psutil (>=4.0)"] | |||
python2 = ["typed-ast (>=1.4.0,<1.5.0)"] | |||
[[package]] | |||
name = "mypy-extensions" | |||
version = "0.4.3" | |||
description = "Experimental type system extensions for programs checked with the mypy typechecker." | |||
category = "dev" | |||
optional = false | |||
python-versions = "*" | |||
[[package]] | |||
name = "packaging" | |||
version = "21.0" | |||
description = "Core utilities for Python packages" | |||
category = "dev" | |||
optional = false | |||
python-versions = ">=3.6" | |||
[package.dependencies] | |||
pyparsing = ">=2.0.2" | |||
[[package]] | |||
name = "pluggy" | |||
version = "0.13.1" | |||
description = "plugin and hook calling mechanisms for python" | |||
category = "dev" | |||
optional = false | |||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" | |||
[package.extras] | |||
dev = ["pre-commit", "tox"] | |||
[[package]] | |||
name = "py" | |||
version = "1.10.0" | |||
description = "library with cross-python path, ini-parsing, io, code, log facilities" | |||
category = "dev" | |||
optional = false | |||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" | |||
[[package]] | |||
name = "pyparsing" | |||
version = "2.4.7" | |||
description = "Python parsing module" | |||
category = "dev" | |||
optional = false | |||
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" | |||
[[package]] | |||
name = "pytest" | |||
version = "5.4.3" | |||
description = "pytest: simple powerful testing with Python" | |||
category = "dev" | |||
optional = false | |||
python-versions = ">=3.5" | |||
[package.dependencies] | |||
atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} | |||
attrs = ">=17.4.0" | |||
colorama = {version = "*", markers = "sys_platform == \"win32\""} | |||
more-itertools = ">=4.0.0" | |||
packaging = "*" | |||
pluggy = ">=0.12,<1.0" | |||
py = ">=1.5.0" | |||
wcwidth = "*" | |||
[package.extras] | |||
checkqa-mypy = ["mypy (==v0.761)"] | |||
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] | |||
[[package]] | |||
name = "toml" | |||
version = "0.10.2" | |||
description = "Python Library for Tom's Obvious, Minimal Language" | |||
category = "dev" | |||
optional = false | |||
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" | |||
[[package]] | |||
name = "typing-extensions" | |||
version = "3.10.0.0" | |||
description = "Backported and Experimental Type Hints for Python 3.5+" | |||
category = "dev" | |||
optional = false | |||
python-versions = "*" | |||
[[package]] | |||
name = "wcwidth" | |||
version = "0.2.5" | |||
description = "Measures the displayed width of unicode strings in a terminal" | |||
category = "dev" | |||
optional = false | |||
python-versions = "*" | |||
[metadata] | |||
lock-version = "1.1" | |||
python-versions = "^3.9" | |||
content-hash = "6d8d4901fcb66543d7749dfe5a31f6f4fb5e2aa3bda2e58442158dd74d7be49e" | |||
[metadata.files] | |||
atomicwrites = [ | |||
{file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, | |||
{file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, | |||
] | |||
attrs = [ | |||
{file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"}, | |||
{file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"}, | |||
] | |||
colorama = [ | |||
{file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, | |||
{file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, | |||
] | |||
more-itertools = [ | |||
{file = "more-itertools-8.8.0.tar.gz", hash = "sha256:83f0308e05477c68f56ea3a888172c78ed5d5b3c282addb67508e7ba6c8f813a"}, | |||
{file = "more_itertools-8.8.0-py3-none-any.whl", hash = "sha256:2cf89ec599962f2ddc4d568a05defc40e0a587fbc10d5989713638864c36be4d"}, | |||
] | |||
mypy = [ | |||
{file = "mypy-0.910-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:a155d80ea6cee511a3694b108c4494a39f42de11ee4e61e72bc424c490e46457"}, | |||
{file = "mypy-0.910-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:b94e4b785e304a04ea0828759172a15add27088520dc7e49ceade7834275bedb"}, | |||
{file = "mypy-0.910-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:088cd9c7904b4ad80bec811053272986611b84221835e079be5bcad029e79dd9"}, | |||
{file = "mypy-0.910-cp35-cp35m-win_amd64.whl", hash = "sha256:adaeee09bfde366d2c13fe6093a7df5df83c9a2ba98638c7d76b010694db760e"}, | |||
{file = "mypy-0.910-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:ecd2c3fe726758037234c93df7e98deb257fd15c24c9180dacf1ef829da5f921"}, | |||
{file = "mypy-0.910-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:d9dd839eb0dc1bbe866a288ba3c1afc33a202015d2ad83b31e875b5905a079b6"}, | |||
{file = "mypy-0.910-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:3e382b29f8e0ccf19a2df2b29a167591245df90c0b5a2542249873b5c1d78212"}, | |||
{file = "mypy-0.910-cp36-cp36m-win_amd64.whl", hash = "sha256:53fd2eb27a8ee2892614370896956af2ff61254c275aaee4c230ae771cadd885"}, | |||
{file = "mypy-0.910-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b6fb13123aeef4a3abbcfd7e71773ff3ff1526a7d3dc538f3929a49b42be03f0"}, | |||
{file = "mypy-0.910-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e4dab234478e3bd3ce83bac4193b2ecd9cf94e720ddd95ce69840273bf44f6de"}, | |||
{file = "mypy-0.910-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:7df1ead20c81371ccd6091fa3e2878559b5c4d4caadaf1a484cf88d93ca06703"}, | |||
{file = "mypy-0.910-cp37-cp37m-win_amd64.whl", hash = "sha256:0aadfb2d3935988ec3815952e44058a3100499f5be5b28c34ac9d79f002a4a9a"}, | |||
{file = "mypy-0.910-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ec4e0cd079db280b6bdabdc807047ff3e199f334050db5cbb91ba3e959a67504"}, | |||
{file = "mypy-0.910-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:119bed3832d961f3a880787bf621634ba042cb8dc850a7429f643508eeac97b9"}, | |||
{file = "mypy-0.910-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:866c41f28cee548475f146aa4d39a51cf3b6a84246969f3759cb3e9c742fc072"}, | |||
{file = "mypy-0.910-cp38-cp38-win_amd64.whl", hash = "sha256:ceb6e0a6e27fb364fb3853389607cf7eb3a126ad335790fa1e14ed02fba50811"}, | |||
{file = "mypy-0.910-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1a85e280d4d217150ce8cb1a6dddffd14e753a4e0c3cf90baabb32cefa41b59e"}, | |||
{file = "mypy-0.910-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:42c266ced41b65ed40a282c575705325fa7991af370036d3f134518336636f5b"}, | |||
{file = "mypy-0.910-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:3c4b8ca36877fc75339253721f69603a9c7fdb5d4d5a95a1a1b899d8b86a4de2"}, | |||
{file = "mypy-0.910-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:c0df2d30ed496a08de5daed2a9ea807d07c21ae0ab23acf541ab88c24b26ab97"}, | |||
{file = "mypy-0.910-cp39-cp39-win_amd64.whl", hash = "sha256:c6c2602dffb74867498f86e6129fd52a2770c48b7cd3ece77ada4fa38f94eba8"}, | |||
{file = "mypy-0.910-py3-none-any.whl", hash = "sha256:ef565033fa5a958e62796867b1df10c40263ea9ded87164d67572834e57a174d"}, | |||
{file = "mypy-0.910.tar.gz", hash = "sha256:704098302473cb31a218f1775a873b376b30b4c18229421e9e9dc8916fd16150"}, | |||
] | |||
mypy-extensions = [ | |||
{file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, | |||
{file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, | |||
] | |||
packaging = [ | |||
{file = "packaging-21.0-py3-none-any.whl", hash = "sha256:c86254f9220d55e31cc94d69bade760f0847da8000def4dfe1c6b872fd14ff14"}, | |||
{file = "packaging-21.0.tar.gz", hash = "sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7"}, | |||
] | |||
pluggy = [ | |||
{file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, | |||
{file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, | |||
] | |||
py = [ | |||
{file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"}, | |||
{file = "py-1.10.0.tar.gz", hash = "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3"}, | |||
] | |||
pyparsing = [ | |||
{file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, | |||
{file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, | |||
] | |||
pytest = [ | |||
{file = "pytest-5.4.3-py3-none-any.whl", hash = "sha256:5c0db86b698e8f170ba4582a492248919255fcd4c79b1ee64ace34301fb589a1"}, | |||
{file = "pytest-5.4.3.tar.gz", hash = "sha256:7979331bfcba207414f5e1263b5a0f8f521d0f457318836a7355531ed1a4c7d8"}, | |||
] | |||
toml = [ | |||
{file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, | |||
{file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, | |||
] | |||
typing-extensions = [ | |||
{file = "typing_extensions-3.10.0.0-py2-none-any.whl", hash = "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497"}, | |||
{file = "typing_extensions-3.10.0.0-py3-none-any.whl", hash = "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84"}, | |||
{file = "typing_extensions-3.10.0.0.tar.gz", hash = "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342"}, | |||
] | |||
wcwidth = [ | |||
{file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, | |||
{file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, | |||
] |
@ -0,0 +1,16 @@ | |||
[tool.poetry] | |||
name = "gbso" | |||
version = "0.1.0" | |||
description = "" | |||
authors = ["Forest Belton <65484+forestbelton@users.noreply.github.com>"] | |||
[tool.poetry.dependencies] | |||
python = "^3.9" | |||
[tool.poetry.dev-dependencies] | |||
pytest = "^5.2" | |||
mypy = "^0.910" | |||
[build-system] | |||
requires = ["poetry-core>=1.0.0"] | |||
build-backend = "poetry.core.masonry.api" |
@ -0,0 +1,5 @@ | |||
from gbso import __version__ | |||
def test_version(): | |||
assert __version__ == '0.1.0' |