Summary
Create the foundational infrastructure for the PTC-Lisp parser: AST node type definitions, parser helper functions, and the NimbleParsec parser skeleton. This establishes the structure for subsequent parser development while implementing literal parsing as a first milestone.
Context
Architecture reference: docs/ptc-lisp-parser-plan.md - Sections 1-3
Dependencies: API Refactor phase complete (issues #100, #102, #104)
Related issues: None (first Lisp parser issue)
Current State
lib/ptc_runner/lisp/ directory does not exist
- No PTC-Lisp parsing capability
- NimbleParsec is not yet a dependency in mix.exs
- The parser plan specifies the complete AST structure and implementation approach
Acceptance Criteria
Implementation Hints
Files to create:
lib/ptc_runner/lisp/ast.ex - AST node types and constructors (see plan Section 1)
lib/ptc_runner/lisp/parser_helpers.ex - Reduce functions for NimbleParsec (see plan Section 4)
lib/ptc_runner/lisp/parser.ex - NimbleParsec combinators (see plan Section 3)
test/ptc_runner/lisp/parser_test.exs - Unit tests (see plan Section 5)
Files to modify:
mix.exs - Add {:nimble_parsec, "~> 1.4"}
Patterns to follow:
- See
lib/ptc_runner/json/parser.ex for error handling patterns
- NimbleParsec usage:
defcombinatorp, defparsec, parsec(:name) for recursion
Edge cases to consider:
nil, true, false must not match as prefixes of longer symbols (nilly, truthy)
- Negative numbers vs
- symbol: -5 is integer -5, not symbol - followed by 5
- Float requires both integer and decimal parts:
.5 and 5. are invalid
- Single-line strings only (no literal newlines, use
\n escape)
- Empty string
"" is valid
Test Plan
Unit tests:
nil, true, false literals
- Integers: positive, negative, zero
- Floats: positive, negative, with exponent (
2.5e10)
- Strings: simple, with escapes (
\n, \t, \\, \"), empty
- Keywords:
:name, :user_id, :kebab-case
- Symbol boundary tests:
nilly, truthy, nil?
Error tests:
- Leading decimal
.5 → parse error
- Trailing decimal
5. → parse error
- Unclosed string
"hello → parse error
- Multiline string literal → parse error
Out of Scope
- Symbols (will be next issue)
- Collections: vectors
[], maps {}, lists () (subsequent issues)
- Whitespace and comment handling (subsequent issue)
- Integration with
PtcRunner.Lisp.run/2 (Phase 4 - Integration)
lib/ptc_runner/lisp.ex placeholder module (can be added separately or with integration)
Documentation Updates
- None required for this issue (internal implementation)
- Documentation updates for the Lisp parser will be done in the Integration phase
Summary
Create the foundational infrastructure for the PTC-Lisp parser: AST node type definitions, parser helper functions, and the NimbleParsec parser skeleton. This establishes the structure for subsequent parser development while implementing literal parsing as a first milestone.
Context
Architecture reference: docs/ptc-lisp-parser-plan.md - Sections 1-3
Dependencies: API Refactor phase complete (issues #100, #102, #104)
Related issues: None (first Lisp parser issue)
Current State
lib/ptc_runner/lisp/directory does not existAcceptance Criteria
lib/ptc_runner/lisp/ast.excreated with AST type specs and constructorslib/ptc_runner/lisp/parser_helpers.excreated with number/string/collection builderslib/ptc_runner/lisp/parser.excreated with NimbleParsec structurenil,true,false, integers, floats, strings (with escapes), keywordsparse/1public API returning{:ok, ast}or{:error, {:parse_error, message}}mix compile --warnings-as-errorspassesImplementation Hints
Files to create:
lib/ptc_runner/lisp/ast.ex- AST node types and constructors (see plan Section 1)lib/ptc_runner/lisp/parser_helpers.ex- Reduce functions for NimbleParsec (see plan Section 4)lib/ptc_runner/lisp/parser.ex- NimbleParsec combinators (see plan Section 3)test/ptc_runner/lisp/parser_test.exs- Unit tests (see plan Section 5)Files to modify:
mix.exs- Add{:nimble_parsec, "~> 1.4"}Patterns to follow:
lib/ptc_runner/json/parser.exfor error handling patternsdefcombinatorp,defparsec,parsec(:name)for recursionEdge cases to consider:
nil,true,falsemust not match as prefixes of longer symbols (nilly,truthy)-symbol:-5is integer -5, not symbol-followed by5.5and5.are invalid\nescape)""is validTest Plan
Unit tests:
nil,true,falseliterals2.5e10)\n,\t,\\,\"), empty:name,:user_id,:kebab-casenilly,truthy,nil?Error tests:
.5→ parse error5.→ parse error"hello→ parse errorOut of Scope
[], maps{}, lists()(subsequent issues)PtcRunner.Lisp.run/2(Phase 4 - Integration)lib/ptc_runner/lisp.explaceholder module (can be added separately or with integration)Documentation Updates