Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
cec9cdb
Update some dependencies
lefticus Aug 26, 2024
b2d40b8
Merge branch 'main' into develop
lefticus Apr 3, 2025
691f9a7
Claude inspired tests (#13)
lefticus Apr 13, 2025
8bfa3ba
Add recursion support (#14)
lefticus Apr 13, 2025
86d6642
Remove "do" built in
lefticus Apr 13, 2025
b111009
Add "begin" support
lefticus Apr 13, 2025
8faad32
Add 'cond' built in function
lefticus Apr 13, 2025
dbabf22
Merge implementations of string like things
lefticus Apr 14, 2025
e11fc55
Add documentation notes from Claude
lefticus Apr 14, 2025
c5be65e
Add character escape sequence processing
lefticus Apr 14, 2025
bb2c986
Add tests to try and reach 100% code coverage
lefticus Apr 14, 2025
c977d62
Add "error?" and fix issue with floating point parsing
lefticus Apr 14, 2025
202d482
Tests passing for coverage increasing
lefticus Apr 14, 2025
bd98ade
Progress towards better float parsing
lefticus Apr 15, 2025
25c619a
Add coverage report generation
lefticus Apr 15, 2025
e5bd2c8
Number parsing fixes and tests
lefticus Apr 15, 2025
fd660fb
Add failing test for bad character escape sequence
lefticus Apr 15, 2025
bf0c0e9
98% code coverage obtained
lefticus Apr 16, 2025
afdfd98
Fix return type from parse to be more correct
lefticus Apr 16, 2025
c3dcf67
clang-format applied
lefticus Apr 16, 2025
1c47e7b
Add failing test for addition of mismatched types
lefticus Apr 16, 2025
c06d308
Add test case against adding ' symbols
lefticus Apr 17, 2025
a591060
Get quoting behavior in line with mainstream scheme
lefticus Apr 18, 2025
f10ce45
First pass at TODO list
lefticus Apr 19, 2025
69c6da5
Scoping and recursion fixes:
lefticus Apr 19, 2025
fe60829
Add predicates for more types
lefticus Apr 21, 2025
8079422
Fix failing tests
lefticus Apr 21, 2025
6e08f37
Document TODO and implementation strategies
lefticus Apr 21, 2025
f382340
Add missing type_predicate_tests
lefticus Apr 22, 2025
e4575e9
Fix incorrect warning from gcc
lefticus May 10, 2025
b00c759
Get clang-tidy narrowed down
lefticus May 10, 2025
6670c3e
Fix fuzz_tester implementation and cons_expr braces
lefticus May 13, 2025
f62136e
Add file input support to CLI and tests
lefticus May 13, 2025
1d6120f
Fix unterminated escape sequence handling in strings
lefticus May 20, 2025
c2f367d
Document branch coverage analysis process in TODO.md
lefticus May 22, 2025
5c2aa2f
Add targeted edge case tests to improve branch coverage
lefticus May 22, 2025
c8a48be
Enhance branch coverage with comprehensive error handling and edge ca…
lefticus May 22, 2025
c8ad730
Add comprehensive branch coverage tests improving coverage from 34% t…
lefticus May 22, 2025
9f2e010
Add advanced error path and edge case tests targeting specific uncove…
lefticus May 22, 2025
2678a8b
Make car and cdr consistent: both now error on empty lists
lefticus May 24, 2025
4f07930
Increase coverage testing
lefticus May 26, 2025
14e3d68
:art: Committing clang-format changes
Jun 24, 2025
b4bd8dd
Fix clang and gcc build errors, upgrade gcc
lefticus Jun 24, 2025
f24065a
Add build script that can help Claude
lefticus Sep 21, 2025
8266192
Update gcovr call
lefticus Jan 1, 2026
aec7db5
Add emscripten capability from cmake_template project
lefticus Jan 2, 2026
e68b839
Claude's attempt to get both ftxui and regular console working
lefticus Jan 2, 2026
8ecbc45
:art: Committing clang-format changes
Jan 2, 2026
24aa9a5
Update to gcc 15, ubuntu latest
lefticus Jan 2, 2026
0bf3c0b
Specify gcc 15.2
lefticus Jan 2, 2026
9ecac95
Move to GCC 14 with ubuntu latest
lefticus Jan 2, 2026
bfd5710
Upgrade / include clang release
lefticus Jan 2, 2026
f477cb6
Fixes related to clang-tidy
lefticus Jan 3, 2026
fc50ca2
:art: Committing clang-format changes
Jan 3, 2026
8987b9e
Remove incorrect fmt dependency
lefticus Jan 3, 2026
b735643
Remove fuzz test from normal test runs
lefticus Jan 3, 2026
75230a5
Attempt to fix CI coverage reporting
lefticus Jan 3, 2026
14fb365
Merge pull request #15 from lefticus/cleanups_add_missing_features
lefticus Jan 3, 2026
4ddd023
Correct links to the demo in the README.md
lefticus Jan 3, 2026
ac1ef52
Update README.md
lefticus Jan 4, 2026
351b990
Get the "main_minimal" example compiling
lefticus Mar 25, 2026
042f2e0
Error propagation handling (#16)
lefticus Mar 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
---

# Unfortunately const-correctness seems to be almost completely broken
# (clang 19)
Checks: "*,
-abseil-*,
-altera-*,
Expand All @@ -11,18 +14,29 @@ Checks: "*,
-readability-else-after-return,
-readability-static-accessed-through-instance,
-readability-avoid-const-params-in-decls,
-readability-simplify-boolean-expr,
-cppcoreguidelines-non-private-member-variables-in-classes,
-misc-non-private-member-variables-in-classes,
-misc-const-correctness,
"
WarningsAsErrors: ''
HeaderFilterRegex: ''
HeaderFilterRegex: '^(src|include)/.*'
FormatStyle: none

CheckOptions:
readability-identifier-length.IgnoredVariableNames: 'x|y|z|id|ch'
readability-identifier-length.IgnoredParameterNames: 'x|y|z|id|ch'


# Command line options
ExtraArgs: [
'-Wno-unknown-warning-option',
'-Wno-ignored-optimization-argument',
'-Wno-unused-command-line-argument',
'-Wno-unknown-argument',
'-Wno-gcc-compat'
]

# Quiet mode is set via command line with --quiet
# It doesn't have a YAML equivalent

CheckOptions:
readability-identifier-length.IgnoredVariableNames: 'x|y|z|id|ch|to'
readability-identifier-length.IgnoredParameterNames: 'x|y|z|id|ch|to'

19 changes: 13 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
- develop

env:
CLANG_TIDY_VERSION: "16.0.0"
CLANG_TIDY_VERSION: "19.1.1"
VERBOSE: 1


Expand All @@ -29,10 +29,11 @@ jobs:
# and your own projects needs
matrix:
os:
- ubuntu-22.04
- ubuntu-latest
compiler:
# you can specify the version after `-` like "llvm-16.0.0".
- gcc-13
- gcc-14
- llvm-19.1.1
generator:
- "Ninja Multi-Config"
build_type:
Expand All @@ -45,8 +46,8 @@ jobs:
include:
# Add appropriate variables for gcov version required. This will intentionally break
# if you try to use a compiler that does not have gcov set
- compiler: gcc-13
gcov_executable: gcov
- compiler: gcc-14
gcov_executable: gcov-14
enable_ipo: On


Expand All @@ -55,6 +56,10 @@ jobs:
packaging_maintainer_mode: OFF
package_generator: TBZ2

- compiler: llvm-19.1.1
enable_ip: Off
gcov_executable: "llvm-cov gcov"


steps:
- name: Check for llvm version mismatches
Expand Down Expand Up @@ -114,7 +119,7 @@ jobs:
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: |
ctest -C ${{matrix.build_type}}
gcovr -j ${{env.nproc}} --delete --root ../ --print-summary --xml-pretty --xml coverage.xml . --gcov-executable '${{ matrix.gcov_executable }}'
gcovr -j ${{env.nproc}} --root ../ --print-summary --xml-pretty --xml coverage.xml . --gcov-executable '${{ matrix.gcov_executable }}'

- name: Windows - Test and coverage
if: runner.os == 'Windows'
Expand All @@ -139,6 +144,8 @@ jobs:
- name: Publish to codecov
uses: codecov/codecov-action@v2
with:
fail_ci_if_error: true
flags: ${{ runner.os }}
name: ${{ runner.os }}-coverage
token: ${{ secrets.CODECOV_TOKEN }}
files: ./build/coverage.xml
59 changes: 59 additions & 0 deletions .github/workflows/wasm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Build Intro WASM and Deploy to GitHub Pages

on:
pull_request:
release:
types: [published]
push:
branches: [main, develop]
tags: ['**']

permissions:
contents: write

jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup Emscripten
uses: mymindstorm/setup-emsdk@v14
with:
version: 'latest'

- name: Install Ninja
run: sudo apt-get install -y ninja-build

- name: Configure CMake
run: emcmake cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release

- name: Build all WASM targets
run: emmake cmake --build build --target web-dist

- name: Prepare deployment
run: |
# web-dist target already created build/web-dist/
# Just copy it to dist/ for GitHub Pages action
cp -r build/web-dist dist

- name: Determine deploy path
id: deploy-path
if: github.event_name != 'pull_request' && github.event_name != 'release'
run: |
if [[ "$GITHUB_REF" == refs/tags/* ]]; then
echo "path=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
elif [[ "$GITHUB_REF" == refs/heads/main ]]; then
echo "path=." >> $GITHUB_OUTPUT
elif [[ "$GITHUB_REF" == refs/heads/develop ]]; then
echo "path=develop" >> $GITHUB_OUTPUT
fi

- name: Deploy to GitHub Pages
if: github.event_name != 'pull_request' && github.event_name != 'release'
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./dist
destination_dir: ${{ steps.deploy-path.outputs.path }}
keep_files: true
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,5 @@ $RECYCLE.BIN/
.TemporaryItems
ehthumbs.db
Thumbs.db

**/.claude/settings.local.json
98 changes: 98 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

You are an expert in C++. You use C++23 and prefer to use constexpr wherever possible. You always apply C++ Best Practices as taught by Jason Turner.

You are also an expert in scheme-like languages and know the pros and cons of various design decisions.



## Build Commands
- Configure: `cmake -S . -B ./build`
- Build: `cmake --build ./build`
- Run tests: `cd ./build && ctest -C Debug`
- Run specific test: `cd ./build && ctest -C Debug -R "unittests.*"` or `ctest -C Debug -R "constexpr.*"`
- Build constexpr tests: `cmake --build ./build --target constexpr_tests`
- Build runtime assertion tests: `cmake --build ./build --target relaxed_constexpr_tests`
- Run a specific test category: `./test/relaxed_constexpr_tests "[category]"`

## Testing
- The library is designed to run both at compile-time and runtime
- `constexpr_tests` target compiles tests with static assertions
- Will fail to compile if tests fail since they use static assertions
- Makes debugging difficult as you won't see which specific test failed
- Will always fail to compile if there's a fail test; use relaxed_constexpr_tests or directly execute the tests with cons_expr command line tool for debugging
- `relaxed_constexpr_tests` target compiles with runtime assertions
- Preferred for debugging since it shows which specific tests fail
- Use this target when developing/debugging:
```bash
cmake --build ./build --target relaxed_constexpr_tests && ./build/test/relaxed_constexpr_tests
```

### Catch2 Command Line Arguments
- Run specific test tag: `./build/test/relaxed_constexpr_tests "[tag]"`
- Run tests with specific name: `./build/test/relaxed_constexpr_tests "quote function"`
- Increase verbosity: `./build/test/relaxed_constexpr_tests --verbosity high`
- List all tests: `./build/test/relaxed_constexpr_tests --list-tests`
- List all tags: `./build/test/relaxed_constexpr_tests --list-tags`
- Show help: `./build/test/relaxed_constexpr_tests --help`

### Command-line Debugging
- Prefer using the `cons_expr` command-line tool for quick debugging and iteration
- Build it with: `cmake --build ./build --target cons_expr_cli`
- Test expressions directly with: `./build/src/cons_expr_cli/cons_expr_cli --exec "(expression-to-test)"`
- This is faster than rebuilding and running test suites for quick iteration

### Writing Tests
- All tests should pass in both modes (constexpr and runtime)
- Catch2 is used for testing framework
- Use the TEST_CASE macro with meaningful name and tags
- Split complex tests into smaller, focused tests
- All constexpr tests should use STATIC_CHECK to ensure they can be evaluated at compile time
- When testing parsing functions:
- Use `std::string_view` when passing string literals
- Remember `parse()` always returns a list containing the parsed expressions
- Navigate the result carefully by checking the types at each level
- Separate parse tests (parser_tests.cpp) from evaluation tests (constexpr_tests.cpp)

## Code Style
- C++23 standard
- No C++ extensions (CMAKE_CXX_EXTENSIONS OFF)
- Treat warnings as errors
- Code is header-only library (include/cons_expr)
- Header files follow #ifndef/#define guard pattern
- Entire system is `constexpr` capable unless it uses IO
- Use modern C++ style casts over C-style casts
- Avoid macros completely except for header guards
- Prefer templates, constexpr functions or concepts over macros
- Use `static constexpr` for compile-time known constants
- Prefer local constants within functions over function variables for readability

## Naming and Structure
- Namespace: lefticus
- Use snake_case for variables and functions
- Classes/structs use PascalCase
- Template parameters use PascalCase
- All objects are immutable once captured

## Error Handling
- Avoid exceptions and dynamic allocations
- Use std::expected for error handling
- Check bounds and sizes before access

## Parser and Expression Structure
- `parse()` function always returns a list containing the parsed expressions
- Even a single expression is wrapped in a list
- Expression types are stored as variants
- Elements can be:
- Atoms (identifiers, symbols, strings, numbers, booleans)
- Lists (collections of elements)
- Literal lists (quoted lists that aren't evaluated)
- Closures (lambda functions with environment)
- Errors (with expected and got information)
- The parser handles nested structures, quotes, and comments
- Use string_view for all string literals in parser tests

## Known Issues
- String handling: Special attention needed for escaped quotes in strings
16 changes: 16 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,19 @@ project(
LANGUAGES CXX C)

include(cmake/PreventInSourceBuilds.cmake)
include(cmake/Emscripten.cmake)
include(ProjectOptions.cmake)

if(MSVC)

elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
add_compile_options(-fconstexpr-steps=12712420)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")

else()

# TODO support Intel compiler
endif()

cons_expr_setup_options()

Expand Down Expand Up @@ -67,6 +78,11 @@ add_subdirectory(src)

add_subdirectory(examples)

# Create unified web deployment directory (for WASM builds)
if(EMSCRIPTEN)
cons_expr_create_web_dist()
endif()

# Don't even look at tests if we're not top level
if(NOT PROJECT_IS_TOP_LEVEL)
return()
Expand Down
6 changes: 3 additions & 3 deletions Dependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@ function(cons_expr_setup_dependencies)
NAME
spdlog
VERSION
1.11.0
1.14.1
GITHUB_REPOSITORY
"gabime/spdlog"
OPTIONS
"SPDLOG_USE_STD_FORMAT ON")
endif()

if(NOT TARGET Catch2::Catch2WithMain)
cpmaddpackage("gh:catchorg/Catch2@3.3.2")
cpmaddpackage("gh:catchorg/Catch2@3.8.1")
endif()

if(NOT TARGET CLI11::CLI11)
cpmaddpackage("gh:CLIUtils/CLI11@2.3.2")
cpmaddpackage("gh:CLIUtils/CLI11@2.4.2")
endif()

if(NOT TARGET ftxui::screen)
Expand Down
Loading
Loading