Skip to content

Home

Authors
Joe Starr, Ph.D. image

Joe Starr, Ph.D.

I specialize in computational knot theory. I’m also a professional embedded software engineer.

DOI - 10.5281/zenodo.18962752 License: GPL v3

White Logo image ./assets/logo.svg

Note to Reader

The following document as well as the Documentation and Code Comments pages are intended for developers. A user who doesn't intend to contribute to development might find the User Guide page more helpful.

If you discover an issue with this repository or have a question, please feel free to open an issue. I've included templates for the following issues:

  • πŸ–‹οΈ Spelling and Grammar: Found some language that is incorrect?
  • 🀷 Clarity: Found a section that just makes no sense?
  • ❓ Question: Do you have a general question?
  • 🐞 Bug: Found an error in the code?
  • πŸš€ Enhancement: Have a suggestion for improving the toolchain?

Open Issue!

πŸ“ƒ Cite Me

BibTeX and APA on the right sidebar of GitHub.

βš–οΈ License

GNU GPL v3

Planning and Administration

Tasks

Tasks are tracked as GitHub issues, each Enhancement and Bug generating the following collection of issues and child issues:

  • A primary issue describing the goal:
  • A documentation child issue.
  • An implementation child issue.
  • A validation child issue.

Version control

The toolchain shall be kept under Git versioning. Development shall take place on branches with main on GitHub as a source of truth. GitHub pull requests shall serve as the arbiter for inclusion on main with the following quality gates:

  • Compiling of source code.
  • Running and passing the unit test suite.
  • Running and passing linting and style enforcers.
  • Successful generation of documentation.

Release Tagging

The project shall be tagged when an Enhancement or Bug issue is merged into main. The tag shall follow semantic versioning for labels.

vMAJOR.MINOR.PATCH

Project Structure

πŸ“ .
β”œβ”€β”€ πŸ“ docs
β”‚   └── πŸ“„ README.md
β”œβ”€β”€ πŸ“ libraries
β”‚   β”œβ”€β”€ πŸ“ <libraries> 
β”‚   β”œβ”€β”€ πŸ› οΈ CMakeLists.txt 
β”‚   └── πŸ“„ Findlizard  
β”œβ”€β”€ πŸ“ languages 
β”‚   └── <language definitions>  
β”œβ”€β”€ πŸ“ source
β”‚   └── πŸ“ <library> 
β”‚       β”œβ”€β”€ πŸ“ test
β”‚       β”‚   β”œβ”€β”€ πŸ‡¨test_<>.c 
β”‚       β”‚   └── πŸ› οΈ CMakeLists.txt 
β”‚       β”œβ”€β”€ πŸ“src
β”‚       β”‚   β”œβ”€β”€ πŸ‡¨<>.c 
β”‚       β”‚   └── πŸ‡­<>.h
β”‚       β”œβ”€β”€ πŸ“ docs
β”‚       β”‚   β”œβ”€β”€ πŸ“ media
β”‚       β”‚   β”œβ”€β”€ πŸ“„ index.md 
β”‚       β”‚   └── πŸ“„ unit-description.md 
β”‚       β”œβ”€β”€ πŸ› οΈ CMakeLists.txt 
β”‚       └── πŸ“„ mkdocs.yml
β”œβ”€β”€ πŸ“ wrappers 
β”‚   └── πŸ“ <wrapper> 
β”‚       β”œβ”€β”€ πŸ“ test
β”‚       β”‚   β”œβ”€β”€ πŸ‡¨test_<>.c 
β”‚       β”‚   └── πŸ› οΈ CMakeLists.txt 
β”‚       β”œβ”€β”€ πŸ“src
β”‚       β”‚   β”œβ”€β”€ πŸ‡¨<>.c 
β”‚       β”‚   └── πŸ‡­<>.h
β”‚       β”œβ”€β”€ πŸ“ docs
β”‚       β”‚   β”œβ”€β”€ πŸ“ media
β”‚       β”‚   β”œβ”€β”€ πŸ“„ index.md 
β”‚       β”‚   └── πŸ“„ unit-description.md 
β”‚       β”œβ”€β”€ πŸ› οΈ CMakeLists.txt 
β”‚       └── πŸ“„ mkdocs.yml
β”œβ”€β”€ πŸ“„ CITATION
β”œβ”€β”€ πŸ› οΈ CMakeLists.txt
β”œβ”€β”€ ❄️ flake.lock
β”œβ”€β”€ ❄️ flake.nix
β”œβ”€β”€ πŸ“„ Justfile
β”œβ”€β”€ πŸ“„ LICENSE
β”œβ”€β”€ πŸ“„ mkdocs.yml
└── 🐍 requirements.txt

Directories of Interest

  • Source: This directory contains the C libraries for the PDGL.
  • Wrappers: This directory contains the C executable wrappers for the PDGL.
  • Docs: This directory contains the high level documentation for the PDGL.
  • Languages: This directory contains language definitions for the PDGL.

Define a Unit

A unit in this project shall be defined as a header file for a C library module.

Quality

The PDGL and its units shall fail-safe, that is the PDGL and its units can fail, but the failure must be detectable.

Unit Testing

Each C module shall be unit tested. Lower level components may or may not be mocked for higher level components.

Integration Testing

No integration test is expected for the library code. Integration tests are expected to be carried out by wrappers.

Requirements

The PDGL reimplements portions of the original DGL by Maurer 1 (source is available on Dr. Maurer's personal website and mirrored on GitHub). The original DGL consumes a language definition for a grammar (usually context free) and produces a compilable .c source file. This workflow is a little cumbersome in practice. The PDGL intends to implement a set of portable libraries that consume a language definition and directly produce words of that language. To that end the PDGL shall match the features and use cases of the original DGL where possible. Some features may be hard or impossible to reproduce with a modular design. The PDGL shall forgo the DGL language itself in favor of definitions of languages in TOML.

DGL Vs. PDGL Feature Matrix
Symbol Support Level
Full Support
Partial Support
Support Planned
Unsupported
DGL Production Type Support PDGL Production Type or Implementation Difficulty
"Unweighted production" Pure Production
"Weighted production" Weighted Production
"Character Range production [a-z]"
Can be reproduced with a list in a pure production.
Pure Production
"Arithmetic Productions" Hard for native arithmetic productions, as modeling the storage of a global variable is a pain point that requires thought.
action
PDGL doesn't maintain state
Janet Production Adding the ability to maintain state of a production is easy. Having state be scoped to a language is hard.
range Range Production
counter Easy, some care to be taken in the termination case.
unique Easy, some care to be taken in the overflow and termination case.
chain Hard, I can't see how to do this without a language scope state context.
double Easy, straight forward extension of a range production.
permutation Hard, I can't see how to do this without a language scope state context.
sequence Easy, straight forward extension of a pure production.
Functional Requirements
Use Cases

Functional requirements for the toolchain are phrased as use cases. The following use case diagram models the interdependence of those use cases.

flowchart LR

    aU["πŸ‘€ User"]
    aS["πŸ‘€ PDGL"]

subgraph wrap [Wrappers]
subgraph cli [CLI]
    egolfcl(["Execute Generation of Language From Command Line"])
end
subgraph wasm [WASM]
    egolfb(["Execute Generation of Language From Browser"])
end
end

subgraph lib [Libraries]
    SLS(["Supply Language Specification"])
    LL(["Load Language Specification"])
    LSWD(["Language Specification is Well-defined"])
    LSI(["Log State Information"])

    EGL(["Execute Generation of Language"])
    EMG(["Execute Multiple Generations"])
    RPGS(["Report Portion of Generation String"])
    EP(["Execute Production"])
    PPtS(["Push Production to Stack"])
    PPfS(["Pop Production from Stack"])
    EPP(["Execute Pure Production"])
    EWP(["Execute Weighted Production"])
    EJP(["Execute Janet Production"])
    ERP(["Execute Range Production"])
    FTP(["Force Terminate Production"])
    EX(["Force Exit"])
    SG(["Stop Generation"])
    scr[("Stdout")]
    sti[("Stdin")]
    err[("Stderr")]
    sta[("Resolution Stack")]


    SG -. include .-> FTP
    SG -. include .-> EX 
    SLS -. include .-> LSWD

    SLS -. include .-> LL

    EMG -. include .-> EGL
    EGL -. include .-> EP

    EP -. include .-> FTP
    FTP -. include .-> RPGS
    EP -. include .-> PPtS
    EP -. include .-> PPfS
    EP -. include .-> EPP
    EP -. include .-> EWP
    EP -. include .-> ERP
    EP -. include .-> EJP
    EP -. include .-> RPGS

    SLS -. uses .-> sti
    LSI -. uses .-> err 
    RPGS -. uses .-> scr
    PPtS -. uses .-> sta
    PPfS -. uses .-> sta
end
    aS --> LSI 
    aS --> SG 
    aU --> SLS
    aU --> EGL 
    aU --> EMG
    aU --> egolfcl 
    aU --> egolfb 

Phase 1:

Phase 2:

Architectural Decisions

For the PDGL libraries the use cases should be sufficient to motivate and document behavior. When this is insufficient to document specific architectural decisions a collection of [MADR]2 (https://github.com/adr/madr) should be used to document the decisions.

Wrappers may reference system use cases and define their use cases. However, [MADR]2 (https://github.com/adr/madr) should serve as the primary documentation for the architecture of a wrapper.

Nonfunctional Requirements

Colors

Diagrams included in documentation for features (use case and unit descriptions) are expected to use the COLORS color palette.

Technologies
Languages and Frameworks

The PDGL and its components shall be written in C using clang for compiling and CMake as a build system. By design the entry point shall be decoupled from core functionality. These are expected to be compilable with various tooling including C/C++, Python, and JavaScript. This requires all 'external' interfaces to be C++ linkable.

Unit testing of runnable and data wrangler libraries will use the Unity and CMock libraries for unit testing. Test indexing is handled by CTest.

Tools:

  • git
  • mermaid.js
  • Unity
  • clang
  • CMake
  • CTest
  • Doxygen
  • CMock
  • Python
  • mkdocs
  • Pytest
  • prek
  • valgrind
  • tombi
  • uncrustify
  • rumdl
  • MADR2
Documentation of Implementation

C/C++ code is documented with Doxygen, the Doxygen comments shall be parsed and output as XML. General documentation shall be recorded as Markdown files in each module's monorepo. Documentation shall be aggregated using the mkdoxy framework.

Code Style Guide

The C/C++ code in this repository shall be formatted by the bundled uncrustify configuration.



  1. Peter M. Maurer. DGL Version 2 – Random Testing in the Mobile Computing Era. In Henry Han and Erich Baker, editors, Next Generation Data Science, volume 2113, pages 172–183. Springer Nature Switzerland, 2024. URL: https://link.springer.com/10.1007/978-3-031-61816-1_12 (visited on 2026-01-16), doi:10.1007/978-3-031-61816-1_12

  2. Oliver Kopp, Anita Armbruster, and Olaf Zimmermann. Markdown architectural decision records: format and tool support. In ZEUS. 2018.