You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add #{...} set literal parsing to the PTC-Lisp parser. Sets are currently not supported and LLMs commonly use this Clojure syntax causing parse errors. This issue adds parser support for the set literal syntax.
Context
Architecture reference: Set Literal Implementation Plan - Section 5.1 Phase 1: Parser Dependencies: None (first phase of epic #164) Related issues: Epic #164
Current State
Verified: The parser in lib/ptc_runner/lisp/parser.ex currently has no handling for #{...} syntax. The :expr combinator (lines 147-162) includes vector, map_literal, and list but no set. Attempting to parse #{1 2 3} will fail with a parse error since # is not a valid start character for any expression type.
Critical: Add parsec(:set) BEFORE parsec(:map_literal) in the choice list.
Both combinators use } as closing delimiter, but #{ must be matched before {. If :set comes after :map_literal, the parser will fail on #{...} because # isn't recognized, then {...} matches as a map.
Update lines 147-162:
defcombinatorp(:expr,choice([nil_literal,true_literal,false_literal,float_literal,integer_literal,string_literal,keyword,symbol,parsec(:vector),parsec(:set),# <-- NEW: must come before map_literalparsec(:map_literal),parsec(:list)]))
Test Plan
Add a new describe "sets" block to test/ptc_runner/lisp/parser_test.exs:
describe"sets"dotest"empty set"doassert{:ok,{:set,[]}}=Parser.parse("#{}")endtest"set with elements"doassert{:ok,{:set,[1,2,3]}}=Parser.parse("#{123}")endtest"set with mixed types"doassert{:ok,{:set,[{:keyword,:a},{:string,"b"},3]}}=Parser.parse("#{:a \"b\" 3}")endtest"nested set"doassert{:ok,{:set,[{:set,[1,2]}]}} = Parser.parse("#{#{1 2}}")endtest"set containing vector"doassert{:ok,{:set,[{:vector,[1,2]}]}}=Parser.parse("#{[12]}")end
test "set with whitespace andcommas" do
assert {:ok, {:set, [1, 2, 3]}} = Parser.parse("#{ 1 , 2 , 3 }")endtest"unclosed set returns error"doassert{:error,{:parse_error,_}} = Parser.parse("#{123") end test "spacebetween# and { is invalid" doassert{:error,{:parse_error,_}}=Parser.parse("# {1 2}")endend
Regression tests (already exist, verify they still pass):
Summary
Add
#{...}set literal parsing to the PTC-Lisp parser. Sets are currently not supported and LLMs commonly use this Clojure syntax causing parse errors. This issue adds parser support for the set literal syntax.Context
Architecture reference: Set Literal Implementation Plan - Section 5.1 Phase 1: Parser
Dependencies: None (first phase of epic #164)
Related issues: Epic #164
Current State
Verified: The parser in
lib/ptc_runner/lisp/parser.excurrently has no handling for#{...}syntax. The:exprcombinator (lines 147-162) includesvector,map_literal, andlistbut noset. Attempting to parse#{1 2 3}will fail with a parse error since#is not a valid start character for any expression type.Acceptance Criteria
Parser.parse("#{}")returns{:ok, {:set, []}}Parser.parse("#{1 2 3}")returns{:ok, {:set, [1, 2, 3]}}Parser.parse("#{:a \"b\" 3}")returns{:ok, {:set, [{:keyword, :a}, {:string, "b"}, 3]}}Parser.parse("#{#{1 2}}")returns{:ok, {:set, [{:set, [1, 2]}]}}(nested sets)Parser.parse("#{[1 2]}")returns{:ok, {:set, [{:vector, [1, 2]}]}}(set containing vector)Parser.parse("#{ 1 , 2 , 3 }")returns{:ok, {:set, [1, 2, 3]}}(whitespace/comma handling)Parser.parse("#{1 2 3")(unclosed) returns{:error, {:parse_error, _}}Parser.parse("# {1 2}")(space between # and {) returns{:error, {:parse_error, _}}Implementation
Files to Modify
lib/ptc_runner/lisp/parser.ex:setcombinator, update:exprchoice listlib/ptc_runner/lisp/parser_helpers.exbuild_set/1helper functiontest/ptc_runner/lisp/parser_test.exsStep 1: Add
build_set/1helper toparser_helpers.exAdd after
build_list/1(line 64):Step 2: Add
:setcombinator toparser.exAdd after the
:map_literalcombinator (after line 131):Step 3: Update
:exprcombinatorCritical: Add
parsec(:set)BEFOREparsec(:map_literal)in the choice list.Both combinators use
}as closing delimiter, but#{must be matched before{. If:setcomes after:map_literal, the parser will fail on#{...}because#isn't recognized, then{...}matches as a map.Update lines 147-162:
Test Plan
Add a new
describe "sets"block totest/ptc_runner/lisp/parser_test.exs:Regression tests (already exist, verify they still pass):
{:a 1}→{:ok, {:map, [{{:keyword, :a}, 1}]}}{}→{:ok, {:map, []}}Out of Scope
Documentation Updates
None - documentation updates are handled in Phase 7 after all implementation phases complete.