Skip to content

Latest commit

 

History

History
184 lines (137 loc) · 7 KB

File metadata and controls

184 lines (137 loc) · 7 KB

AGENTS.md - Coding Agent Guidelines for brgen

Project Overview

brgen (BinaRy encoder/decoder GENerator) is a polyglot code generator that produces encoder/decoder code for binary formats. It parses .bgn format definitions into a JSON AST (src2json), then code generators (json2go, json2cpp2, json2rust, json2c, json2ts, json2kaitai, json2mermaid, json2vm) emit target-language code. AST manipulation libraries exist for Go, TypeScript, Rust, Python, and C. Many AST library files (astlib/ast2go/, astlib/ast2ts/, astlib/ast2py/, astlib/ast2rust/) are auto-generated -- look for // Code generated by gen_ast2...; DO NOT EDIT. headers and do not manually edit those files.

External dependency: futils (github.com/on-keyday/utils) provides libfutils and is cloned automatically by script/clone_utils.sh or script/clone_utils.bat.

Build Commands

C++ (core parser + C++/C/TS/VM generators) -- CMake + Ninja + Clang

# Linux/macOS/Windows: configure + build (defaults to Debug)
python build.py native Debug

# Build only (after configure)
ninja -C built/native/Debug
ninja -C built/native/Debug install

Requires: CMake >= 3.26, Ninja, Clang (C++20), libfutils from futils repo. Build output goes to built/native/<Debug|Release>/tool/.

Go (json2go, brgen driver, json2kaitai, json2mermaid, gen_ast2*)

# Build a single Go tool directly
go build -o tool/json2go ./src/tool/json2go

# Run Go tests
go test ./src/tool/s2jgo/
go test ./...

Module: github.com/on-keyday/brgen, Go 1.24.

Rust (json2rust, cmptest, unictest)

# Build json2rust
cargo build --manifest-path src/tool/json2rust/Cargo.toml

# Build cmptest
cargo build --manifest-path src/tool/cmptest/Cargo.toml

# Run Rust tests
cargo test --manifest-path astlib/ast2rust/Cargo.toml

TypeScript/Node.js (ast2ts, LSP, web playground)

# ast2ts library
cd astlib/ast2ts && npm install && npm run build

# LSP extension
cd lsp && npm install && npm run compile

# Web playground
cd web/dev && npm install && tsc && webpack

Test Commands

C++ Tests (GoogleTest)

# Run all C++ tests
CTEST_OUTPUT_ON_FAILURE=1 ninja -C built/native/Debug test

# Run a single C++ test by name
ctest --test-dir built/native/Debug -R lexer_test
ctest --test-dir built/native/Debug -R ast_test

# Run test executable directly
./built/native/Debug/test/lexer_test
./built/native/Debug/test/ast_test

Available test names: lexer_test, ast_test, typing_test, middle_test, from_json_test, section_writer_test, type_attribute, derive_test, ctype_test, deep_copy_test.

Go Tests

# Run all Go tests
go test ./...

# Run a single Go test
go test ./src/tool/s2jgo/ -run TestName

# Fuzz testing
go test -fuzz ./src/test/test_tool/

Rust Tests

cargo test --manifest-path astlib/ast2rust/Cargo.toml
cargo test --manifest-path src/tool/json2rust/Cargo.toml

Integration Tests (cmptest)

tool/cmptest -f ignore/example/test_info.json -c testkit/cmptest.json --expected-test-total 8 --debug

Formatting and Linting

C++

  • clang-format with config in .clang-format (Google-based, 4-space indent, no column limit, no include sorting)
  • clang-tidy enabled via VS Code settings
  • Format on save is enabled in .vscode/settings.json
  • Run manually: clang-format -i <file>

Go

  • Standard gofmt / goimports. Code generators use go/format to auto-format output.
  • Run: gofmt -w <file> or goimports -w <file>

Rust

  • Standard rustfmt. Run: cargo fmt --manifest-path <path>/Cargo.toml

Python

  • mypy is used for type checking (.mypy_cache/ present)

Code Style Guidelines

C++ Conventions

  • Standard: C++20. Heavy use of constexpr, auto&&, templates.
  • License: Every file starts with /*license*/ on the first line.
  • Includes: Angle brackets for external/framework (<core/ast/json.h>), quotes for relative ("../common/print.h"). Include sorting is disabled.
  • Namespaces: Top-level brgen::, sub-namespaces like brgen::ast, brgen::lexer. All namespace content is indented (per .clang-format).
  • Types: PascalCase for structs/classes (Context, BitFieldMeta).
  • Functions: PascalCase for top-level entry points (Main), snake_case for methods.
  • Variables/fields: snake_case (no_color, use_error). Booleans often prefixed with is_, use_, add_, enable_.
  • Error handling: No exceptions. Return futils::error::Error<>{} or check validity. Print to cerr for user-facing errors.
  • Headers: Use #pragma once.
  • Braces: Same-line opening brace, else on new line after closing brace.
  • Indent: 4 spaces, no tabs.

Go Conventions

  • Imports: Standard library first, blank line, then third-party/project imports. Use named imports when needed (e.g., ast2go "github.com/on-keyday/brgen/astlib/ast2go/ast").
  • Types: PascalCase for exported, camelCase for unexported.
  • Functions: PascalCase exported, camelCase unexported.
  • Error handling: Standard if err != nil pattern, wrap with fmt.Errorf("...: %w", err).
  • Flags: Use the standard flag package (not cobra).
  • TODO tags: Use // TODO(on-keyday): format.

Rust Conventions

  • Types/Structs: PascalCase. Functions/methods: snake_case. Constants: SCREAMING_SNAKE_CASE.
  • Error handling: anyhow::Result with ? propagation. Use eprintln! + ExitCode::FAILURE in main.
  • CLI args: clap with derive macros (#[derive(Parser)]).
  • Serialization: serde / serde_json for AST deserialization.
  • Smart pointers: Rc<RefCell<T>> aliased as SharedPtr<T>.

TypeScript Conventions

  • Variables/functions: camelCase. Classes/interfaces: PascalCase.
  • Error handling: async/await with try/catch, reject(new Error(...)).
  • Imports: Named imports (import { ... } from "...").

Python Conventions

  • Types: PascalCase. Functions: snake_case. Enum members: SCREAMING_SNAKE_CASE.
  • Type hints: Use from __future__ import annotations and typing module.
  • Note: Most Python AST code is auto-generated -- do not edit manually.

Key Architecture Notes

  1. Pipeline: .bgn source -> src2json (C++ parser) -> JSON AST -> json2* generators -> target code.
  2. Auto-generated files: AST libraries in astlib/ are generated by gen_ast2* tools in src/tool/gen/. Regenerate with the corresponding gen_ast2* binary, do not edit by hand.
  3. WASM support: C++ uses #ifdef __EMSCRIPTEN__, Go uses //go:build !js || !wasm, Rust uses wasm_bindgen. The web playground runs these tools in-browser.
  4. Cross-platform: CI builds for Linux (x86+ARM), macOS, Windows, Android, and WASM.
  5. Comments are sparse across all languages -- the codebase favors self-documenting code. When adding comments, use // style and keep them concise.
  6. Binary format definitions (.bgn files) live in example/ with ~100+ real-world protocol/format examples (UDP, TCP, DNS, TLS, ZIP, ELF, etc.).