Skip to main content

Shared C23 frontend and AST optimizer for the uc80/uc386 family of retro C compilers

Project description

uc_core

Shared C23 frontend and AST-level optimizer for the uc80 (Z80/CP/M) and uc386 (x86-32/MS-DOS) retro C compilers.

What's in here

  • Lexer / parser — C23 source to AST
  • Preprocessor — C23 preprocessor with target-configurable predefined macros
  • AST — node definitions shared across backends
  • AST optimizer — target-independent expression simplification, constant folding, strength reduction, dead-code elimination at the AST level
  • Backend protocol — the contract a target backend must implement

Targets using uc_core

  • uc80 — Z80 / CP/M
  • uc386 — x86-32 / MS-DOS

Install

pip install uc_core

Or from source:

pip install -e .

Usage from a backend

from uc_core.frontend import parse
from uc_core.preprocessor import Preprocessor
from uc_core.ast_optimizer import ASTOptimizer
from uc_core.backend import CodeGenerator  # Protocol

# Target-specific predefined macros
predefines = {
    "__UC80__": "1",
    "__Z80__": "1",
    "__CPM__": "1",
}

pp = Preprocessor(include_paths=["lib/include"], target_predefines=predefines)
source = pp.preprocess(open("hello.c").read(), "hello.c")
ast = parse(source, "hello.c")            # strict C23
# ast = parse(source, "hello.c", kr_prepass=True)  # pre-ANSI sources
ast = ASTOptimizer(opt_level=3).optimize(ast)

# Backend is provided by the target package (uc80, uc386, ...)
# It must implement uc_core.backend.CodeGenerator

The front-end is plox-driven: uc_core/frontend.py runs the lexer

  • LR(1) parser produced from plox/examples/c23.plox and lowers the parse tree into uc_core/ast.py dataclasses. The pre-built tables ship as uc_core/data/c23.json.

K&R / implicit-int compatibility (kr_prepass)

The grammar is strict C23, which has no implicit-int and no K&R old-style parameter lists. parse(..., kr_prepass=True) enables a source-level recovery: the strict parse is attempted first, and only if it fails are the two pre-ANSI shapes rewritten to equivalent ANSI and the parse retried —

main() {  }                 ->  int main() {  }
f(a, b) int a; char *b; {  } ->  int f(int a, char *b) {  }

The same opt-in also lowers the GNU computed-goto / labels-as-values extension (&&label, goto *expr) into a switch dispatch over an integer id-encoding of each function's address-taken labels — affine label arithmetic (&&a - &&b, threaded code) stays consistent, and the result uses only switch/goto/casts:

void *t[] = {&&a, &&b}; goto *t[i];
  ->  void *t[]={(void*)0,(void*)1};
      switch((long)(t[i])){case 0: goto a; case 1: goto b; default:;}

Off by default, so modern code is parsed exactly once and never reaches the rewriter (zero cost). Backends expose it as they see fit (e.g. uc386 --kr); it is intended for legacy/pre-ANSI and GNU-C codebases such as the gcc-c-torture corpus.

Related Projects

  • 80un - Unpacker for CP/M compression and archive formats (LBR, ARC, squeeze, crunch, CrLZH)
  • cpmdroid - Z80/CP/M emulator for Android with RomWBW HBIOS compatibility and VT100 terminal
  • cpmemu - CP/M 2.2 emulator with Z80/8080 CPU emulation and BDOS/BIOS translation to Unix filesystem
  • ioscpm - Z80/CP/M emulator for iOS and macOS with RomWBW HBIOS compatibility
  • learn-ada-z80 - Ada programming examples for the uada80 compiler targeting Z80/CP/M
  • mbasic - Modern MBASIC 5.21 Interpreter & Compilers
  • mbasic2025 - MBASIC 5.21 source code reconstruction - byte-for-byte match with original binary
  • mbasicc - C++ implementation of MBASIC 5.21
  • mbasicc_web - WebAssembly MBASIC 5.21
  • mpm2 - MP/M II multi-user CP/M emulator with SSH terminal access and SFTP file transfer
  • romwbw_emu - Hardware-level Z80 emulator for RomWBW with 512KB ROM + 512KB RAM banking and HBIOS support
  • scelbal - SCELBAL BASIC interpreter - 8008 to 8080 translation
  • uada80 - Ada compiler targeting Z80 processor and CP/M 2.2 operating system
  • uc386 - C23 compiler targeting Intel 386 (x86-32) and MS-DOS; consumer of uc_core
  • uc80 - C23 compiler targeting Z80 processor and CP/M operating system; consumer of uc_core
  • ucow - Unix/Linux Cowgol to Z80 compiler
  • um80_and_friends - Microsoft MACRO-80 compatible toolchain for Linux: assembler, linker, librarian, disassembler
  • upeepz80 - Z80 peephole optimizer
  • uplm80 - PL/M-80 compiler targeting Intel 8080 and Zilog Z80 assembly language
  • uplox - Parser/lexer-table generator that produces uc_core's C23 frontend (from examples/c23.uplox)
  • z80cpmw - Z80 CP/M emulator for Windows (RomWBW)

License

GPL-3.0-or-later. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

uc_core-0.4.0.tar.gz (254.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

uc_core-0.4.0-py3-none-any.whl (256.7 kB view details)

Uploaded Python 3

File details

Details for the file uc_core-0.4.0.tar.gz.

File metadata

  • Download URL: uc_core-0.4.0.tar.gz
  • Upload date:
  • Size: 254.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for uc_core-0.4.0.tar.gz
Algorithm Hash digest
SHA256 1fbb43e675fc8f6494c377aed375afc03cb0dc2101668a599b91440902e092e9
MD5 4b2a279ec08bc45e511b418f8fb4d6ad
BLAKE2b-256 8246f0d33afac2802da1db1e31b74aa5c1c3cba8352ec3c30405fe0731ff413d

See more details on using hashes here.

Provenance

The following attestation bundles were made for uc_core-0.4.0.tar.gz:

Publisher: publish.yml on avwohl/uc_core

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file uc_core-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: uc_core-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 256.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for uc_core-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bea1121559a1da516deee9eb8974322d362da074f9cef1d690b7dabc9c8c7fc9
MD5 7f17477fb24beab2aed2ab9f11d79e40
BLAKE2b-256 09af08ab8e98cf66370d2a41a377da484208934d7740bc3d921358942a25d266

See more details on using hashes here.

Provenance

The following attestation bundles were made for uc_core-0.4.0-py3-none-any.whl:

Publisher: publish.yml on avwohl/uc_core

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page