|
1 | 1 | import os |
2 | 2 | import sys |
| 3 | +import ast |
3 | 4 | import logging |
4 | 5 | import argparse |
5 | 6 | import textwrap |
@@ -142,16 +143,16 @@ def add_applet_arg(parser, mode, required=False): |
142 | 143 | "tests", metavar="TEST", nargs="*", |
143 | 144 | help="test cases to run") |
144 | 145 |
|
145 | | - if mode in ("build", "run", "run-repl"): |
| 146 | + if mode in ("build", "run", "run-repl", "run-script"): |
146 | 147 | access_args = DirectArguments(applet_name=applet_name, |
147 | 148 | default_port="AB", |
148 | 149 | pin_count=16) |
149 | | - if mode in ("run", "run-repl"): |
| 150 | + if mode in ("run", "run-repl", "run-script"): |
150 | 151 | g_applet_build = p_applet.add_argument_group("build arguments") |
151 | 152 | applet.add_build_arguments(g_applet_build, access_args) |
152 | 153 | g_applet_run = p_applet.add_argument_group("run arguments") |
153 | 154 | applet.add_run_arguments(g_applet_run, access_args) |
154 | | - if mode != "run-repl": |
| 155 | + if mode not in ( "run-repl", "run-script" ): |
155 | 156 | # FIXME: this makes it impossible to add subparsers in applets |
156 | 157 | # g_applet_interact = p_applet.add_argument_group("interact arguments") |
157 | 158 | # applet.add_interact_arguments(g_applet_interact) |
@@ -245,6 +246,15 @@ def add_run_args(parser): |
245 | 246 | add_run_args(p_run_repl) |
246 | 247 | add_applet_arg(p_run_repl, mode="run-repl") |
247 | 248 |
|
| 249 | + p_run_script = subparsers.add_parser( |
| 250 | + "run-script", formatter_class=TextHelpFormatter, |
| 251 | + help="run an applet and execute a script against its low-level interface") |
| 252 | + add_run_args(p_run_script) |
| 253 | + p_run_script.add_argument( |
| 254 | + "script", metavar="SCRIPT", type=argparse.FileType("r"), |
| 255 | + help="the script to run") |
| 256 | + add_applet_arg(p_run_script, mode="run-script") |
| 257 | + |
248 | 258 | p_run_prebuilt = subparsers.add_parser( |
249 | 259 | "run-prebuilt", formatter_class=TextHelpFormatter, |
250 | 260 | help="(advanced) load a prebuilt applet bitstream and run applet code") |
@@ -495,12 +505,12 @@ async def _main(): |
495 | 505 | print("{}\t{:.2}\t{:.2}" |
496 | 506 | .format(port, vio, vlimit)) |
497 | 507 |
|
498 | | - if args.action in ("run", "run-repl", "run-prebuilt"): |
| 508 | + if args.action in ("run", "run-repl", "run-script", "run-prebuilt"): |
499 | 509 | target, applet = _applet(device.revision, args) |
500 | 510 | device.demultiplexer = DirectDemultiplexer(device, target.multiplexer.pipe_count) |
501 | 511 | plan = target.build_plan() |
502 | 512 |
|
503 | | - if args.action in ("run", "run-repl"): |
| 513 | + if args.action in ("run", "run-repl", "run-script"): |
504 | 514 | await device.download_target(plan, rebuild=args.rebuild) |
505 | 515 | if args.action == "run-prebuilt": |
506 | 516 | bitstream_file = args.bitstream or open("{}.bin".format(args.applet), "rb") |
@@ -589,6 +599,12 @@ async def run_applet(): |
589 | 599 | logger.info("dropping to REPL; use 'help(iface)' to see available APIs") |
590 | 600 | await AsyncInteractiveConsole(locals={"iface":iface}, |
591 | 601 | run_callback=device.demultiplexer.flush).interact() |
| 602 | + |
| 603 | + if args.action == "run-script": |
| 604 | + c = compile(args.script.read(), filename=args.script.name, mode="exec", |
| 605 | + flags=ast.PyCF_ALLOW_TOP_LEVEL_AWAIT) |
| 606 | + await eval(c, {"iface":iface, "device":device}) |
| 607 | + |
592 | 608 | except GlasgowAppletError as e: |
593 | 609 | applet.logger.error(str(e)) |
594 | 610 | except asyncio.CancelledError: |
|
0 commit comments