Franck Pommereau

added formats in exam substitutions

......@@ -39,49 +39,54 @@ runparser.add_argument("bios", metavar="INFILE", type=argparse.FileType(),
tester = sub.add_parser("test", help="run a test script")
tester.add_argument("script", type=str, help="test script")
args = parser.parse_args()
colorama.init(strip=not (args.colors or sys.stdout.isatty()))
def main():
args = parser.parse_args()
if args.command == "asm" :
from .asm import cli
if args.tgt is None :
args.tgt = pathlib.Path(args.src.name).with_suffix(".rom").open("w")
err = cli(args.src, args.tgt)
for line, errors in err.items() :
for i, l in enumerate(reversed(list(line.backtrace()))) :
col = f"{F.RED}" if i == 0 else f"{F.RED}{S.DIM}"
if i == 0 :
pos = f"{col}{l.path}:{l.lno}:{S.RESET_ALL}"
else :
pos = f" {F.WHITE}>{S.RESET_ALL} {col}{l.path}:{l.lno}:{S.RESET_ALL}"
sys.stderr.write(f"{pos} {F.LIGHTBLACK_EX}{l.raw}{S.RESET_ALL}\n")
for msg in errors :
txt = re.sub("('[^']+')", r"{}\1{}", msg).format(F.MAGENTA, S.RESET_ALL)
sys.stderr.write(f"{F.RED}error:{S.RESET_ALL} {txt}\n")
sys.exit(1)
elif args.command == "dis" :
from .dis import cli
err = cli(args.bios)
if err is not None :
addr, word, msg = err
sys.stderr.write(f"{F.RED}[{addr}]{S.RESET_ALL} {msg}:"
f" {F.LIGHTBLACK_EX}{word}{S.RESET_ALL}\n")
sys.exit(1)
elif args.command == "run" :
from .run import cli
bios = []
for addr, word in enumerate(args.bios.read().split()) :
try :
bios.append(int(word, 16))
except :
print_errors({f"{addr:04X}" : (word, ["invalid BIOS content"])})
ret = cli(bios, interactive=args.interactive, script=args.script,
watch=args.watch, max_cycles=args.max_cycles, clock=args.clock)
if ret is not None :
sys.exit(ret)
elif args.command == "test" :
from .test import cli
cli(args.script)
else :
parser.print_help()
colorama.init(strip=not (args.colors or sys.stdout.isatty()))
if args.command == "asm" :
from .asm import cli
if args.tgt is None :
args.tgt = pathlib.Path(args.src.name).with_suffix(".rom").open("w")
err = cli(args.src, args.tgt)
for line, errors in err.items() :
for i, l in enumerate(reversed(list(line.backtrace()))) :
col = f"{F.RED}" if i == 0 else f"{F.RED}{S.DIM}"
if i == 0 :
pos = f"{col}{l.path}:{l.lno}:{S.RESET_ALL}"
else :
pos = f" {F.WHITE}>{S.RESET_ALL} {col}{l.path}:{l.lno}:{S.RESET_ALL}"
sys.stderr.write(f"{pos} {F.LIGHTBLACK_EX}{l.raw}{S.RESET_ALL}\n")
for msg in errors :
txt = re.sub("('[^']+')", r"{}\1{}", msg).format(F.MAGENTA, S.RESET_ALL)
sys.stderr.write(f"{F.RED}error:{S.RESET_ALL} {txt}\n")
sys.exit(1)
elif args.command == "dis" :
from .dis import cli
err = cli(args.bios)
if err is not None :
addr, word, msg = err
sys.stderr.write(f"{F.RED}[{addr}]{S.RESET_ALL} {msg}:"
f" {F.LIGHTBLACK_EX}{word}{S.RESET_ALL}\n")
sys.exit(1)
elif args.command == "run" :
from .run import cli
bios = []
for addr, word in enumerate(args.bios.read().split()) :
try :
bios.append(int(word, 16))
except :
print_errors({f"{addr:04X}" : (word, ["invalid BIOS content"])})
ret = cli(bios, interactive=args.interactive, script=args.script,
watch=args.watch, max_cycles=args.max_cycles, clock=args.clock)
if ret is not None :
sys.exit(ret)
elif args.command == "test" :
from .test import cli
cli(args.script)
else :
parser.print_help()
if __name__ == "__main__":
main()
......
......@@ -76,7 +76,7 @@ class Func:
class Source:
_pyrun = re.compile(r"\s*\#\s*\>\>\>\s*(.+)$")
_subst = re.compile(r"\{\{(.+)\}\}")
_subst = re.compile(r"\{\{(.+?)(:[^:]+)?\}\}")
_meta = {"func": re.compile(r"^\s*\#\s*(\w+)\s+([\w\s,]*)=>(.+)$"),
"expr": re.compile(r"^\s*\#\s*(\w+)\s*=\s*(.+)$"),
"text": re.compile(r"^\s*\#\s*(\w+)\s*:\s*(.+)$"),
......@@ -104,13 +104,14 @@ class Source:
elif match := self._subst.search(line):
new = Func.eval(match.group(1),
src=line, lno=lno, **self.meta)
fmt = "{%s}" % (match.group(2) or ":X").strip()
if isinstance(new, str):
pass
elif isinstance(new, Iterable):
new = " ".join(f"{n:X}" if isinstance(n, int)
new = " ".join(fmt.format(n) if isinstance(n, int)
else str(n) for n in new)
elif isinstance(new, int):
new = f"{new:X}"
new = fmt.format(new)
else:
new = str(new)
line = line.replace(match.group(0), new)
......
/* Generated by Cython 3.0.9 */
/* Generated by Cython 3.0.10 */
/* BEGIN: Cython Metadata
{
......@@ -37,10 +37,10 @@ END: Cython Metadata */
#else
#define __PYX_EXTRA_ABI_MODULE_NAME ""
#endif
#define CYTHON_ABI "3_0_9" __PYX_EXTRA_ABI_MODULE_NAME
#define CYTHON_ABI "3_0_10" __PYX_EXTRA_ABI_MODULE_NAME
#define __PYX_ABI_MODULE_NAME "_cython_" CYTHON_ABI
#define __PYX_TYPE_MODULE_PREFIX __PYX_ABI_MODULE_NAME "."
#define CYTHON_HEX_VERSION 0x030009F0
#define CYTHON_HEX_VERSION 0x03000AF0
#define CYTHON_FUTURE_DIVISION 1
#include <stddef.h>
#ifndef offsetof
......@@ -132,6 +132,8 @@ END: Cython Metadata */
#ifndef CYTHON_UPDATE_DESCRIPTOR_DOC
#define CYTHON_UPDATE_DESCRIPTOR_DOC 0
#endif
#undef CYTHON_USE_FREELISTS
#define CYTHON_USE_FREELISTS 0
#elif defined(PYPY_VERSION)
#define CYTHON_COMPILING_IN_PYPY 1
#define CYTHON_COMPILING_IN_CPYTHON 0
......@@ -193,6 +195,8 @@ END: Cython Metadata */
#ifndef CYTHON_UPDATE_DESCRIPTOR_DOC
#define CYTHON_UPDATE_DESCRIPTOR_DOC 0
#endif
#undef CYTHON_USE_FREELISTS
#define CYTHON_USE_FREELISTS 0
#elif defined(CYTHON_LIMITED_API)
#ifdef Py_LIMITED_API
#undef __PYX_LIMITED_VERSION_HEX
......@@ -254,6 +258,8 @@ END: Cython Metadata */
#ifndef CYTHON_UPDATE_DESCRIPTOR_DOC
#define CYTHON_UPDATE_DESCRIPTOR_DOC 0
#endif
#undef CYTHON_USE_FREELISTS
#define CYTHON_USE_FREELISTS 0
#elif defined(Py_GIL_DISABLED) || defined(Py_NOGIL)
#define CYTHON_COMPILING_IN_PYPY 0
#define CYTHON_COMPILING_IN_CPYTHON 0
......@@ -263,11 +269,17 @@ END: Cython Metadata */
#ifndef CYTHON_USE_TYPE_SLOTS
#define CYTHON_USE_TYPE_SLOTS 1
#endif
#ifndef CYTHON_USE_TYPE_SPECS
#define CYTHON_USE_TYPE_SPECS 0
#endif
#undef CYTHON_USE_PYTYPE_LOOKUP
#define CYTHON_USE_PYTYPE_LOOKUP 0
#ifndef CYTHON_USE_ASYNC_SLOTS
#define CYTHON_USE_ASYNC_SLOTS 1
#endif
#ifndef CYTHON_USE_PYLONG_INTERNALS
#define CYTHON_USE_PYLONG_INTERNALS 0
#endif
#undef CYTHON_USE_PYLIST_INTERNALS
#define CYTHON_USE_PYLIST_INTERNALS 0
#ifndef CYTHON_USE_UNICODE_INTERNALS
......@@ -275,8 +287,6 @@ END: Cython Metadata */
#endif
#undef CYTHON_USE_UNICODE_WRITER
#define CYTHON_USE_UNICODE_WRITER 0
#undef CYTHON_USE_PYLONG_INTERNALS
#define CYTHON_USE_PYLONG_INTERNALS 0
#ifndef CYTHON_AVOID_BORROWED_REFS
#define CYTHON_AVOID_BORROWED_REFS 0
#endif
......@@ -288,11 +298,22 @@ END: Cython Metadata */
#endif
#undef CYTHON_FAST_THREAD_STATE
#define CYTHON_FAST_THREAD_STATE 0
#undef CYTHON_FAST_GIL
#define CYTHON_FAST_GIL 0
#ifndef CYTHON_METH_FASTCALL
#define CYTHON_METH_FASTCALL 1
#endif
#undef CYTHON_FAST_PYCALL
#define CYTHON_FAST_PYCALL 0
#ifndef CYTHON_PEP487_INIT_SUBCLASS
#define CYTHON_PEP487_INIT_SUBCLASS 1
#endif
#ifndef CYTHON_PEP489_MULTI_PHASE_INIT
#define CYTHON_PEP489_MULTI_PHASE_INIT 1
#endif
#ifndef CYTHON_USE_MODULE_STATE
#define CYTHON_USE_MODULE_STATE 0
#endif
#ifndef CYTHON_USE_TP_FINALIZE
#define CYTHON_USE_TP_FINALIZE 1
#endif
......@@ -300,6 +321,12 @@ END: Cython Metadata */
#define CYTHON_USE_DICT_VERSIONS 0
#undef CYTHON_USE_EXC_INFO_STACK
#define CYTHON_USE_EXC_INFO_STACK 0
#ifndef CYTHON_UPDATE_DESCRIPTOR_DOC
#define CYTHON_UPDATE_DESCRIPTOR_DOC 1
#endif
#ifndef CYTHON_USE_FREELISTS
#define CYTHON_USE_FREELISTS 0
#endif
#else
#define CYTHON_COMPILING_IN_PYPY 0
#define CYTHON_COMPILING_IN_CPYTHON 1
......@@ -390,6 +417,9 @@ END: Cython Metadata */
#ifndef CYTHON_UPDATE_DESCRIPTOR_DOC
#define CYTHON_UPDATE_DESCRIPTOR_DOC 1
#endif
#ifndef CYTHON_USE_FREELISTS
#define CYTHON_USE_FREELISTS 1
#endif
#endif
#if !defined(CYTHON_FAST_PYCCALL)
#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1)
......@@ -36212,8 +36242,10 @@ static PyTypeObject __pyx_type_3ttc_3vat_TTC = {
};
#endif
#if CYTHON_USE_FREELISTS
static struct __pyx_obj_3ttc_3vat___pyx_scope_struct____iter__ *__pyx_freelist_3ttc_3vat___pyx_scope_struct____iter__[8];
static int __pyx_freecount_3ttc_3vat___pyx_scope_struct____iter__ = 0;
#endif
static PyObject *__pyx_tp_new_3ttc_3vat___pyx_scope_struct____iter__(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
PyObject *o;
......@@ -36221,7 +36253,7 @@ static PyObject *__pyx_tp_new_3ttc_3vat___pyx_scope_struct____iter__(PyTypeObjec
allocfunc alloc_func = (allocfunc)PyType_GetSlot(t, Py_tp_alloc);
o = alloc_func(t, 0);
#else
#if CYTHON_COMPILING_IN_CPYTHON
#if CYTHON_USE_FREELISTS
if (likely((int)(__pyx_freecount_3ttc_3vat___pyx_scope_struct____iter__ > 0) & (int)(t->tp_basicsize == sizeof(struct __pyx_obj_3ttc_3vat___pyx_scope_struct____iter__)))) {
o = (PyObject*)__pyx_freelist_3ttc_3vat___pyx_scope_struct____iter__[--__pyx_freecount_3ttc_3vat___pyx_scope_struct____iter__];
memset(o, 0, sizeof(struct __pyx_obj_3ttc_3vat___pyx_scope_struct____iter__));
......@@ -36248,7 +36280,7 @@ static void __pyx_tp_dealloc_3ttc_3vat___pyx_scope_struct____iter__(PyObject *o)
#endif
PyObject_GC_UnTrack(o);
Py_CLEAR(p->__pyx_v_self);
#if CYTHON_COMPILING_IN_CPYTHON
#if CYTHON_USE_FREELISTS
if (((int)(__pyx_freecount_3ttc_3vat___pyx_scope_struct____iter__ < 8) & (int)(Py_TYPE(o)->tp_basicsize == sizeof(struct __pyx_obj_3ttc_3vat___pyx_scope_struct____iter__)))) {
__pyx_freelist_3ttc_3vat___pyx_scope_struct____iter__[__pyx_freecount_3ttc_3vat___pyx_scope_struct____iter__++] = ((struct __pyx_obj_3ttc_3vat___pyx_scope_struct____iter__ *)o);
} else
......