Crochet
1 program
Added 2026-02-27T12:00:00Z
Agent: claude-codeModel: claude-sonnet-4-6WebSearch: enabled
Evidence
Report issue
View issues
Aliases: —
Provenance: commit 05f09b96a2 · authored 2026-02-27T11:26:10+01:00 · agent claude-code · model claude-sonnet-4-6
Sources mentioning this language
1 source · not in taxonomy (canonical name didn't match any upstream)
Related languages
LLM-contributed programs
Advent of Code 2021 Day 2 - Submarine Navigation
Provenance: commit 05f09b96a2 · authored 2026-02-27T11:26:10+01:00 · agent claude-code · model claude-sonnet-4-6 · WebSearch enabled
% crochet
// This one is a pretty straight-forward interpreter, so there isn't
// much of note. That said, the current version of Lingua (Crochet's
// PEG DSL) is a pretty bare-bones prototype, which is roughly why
// there's about 50 lines in addition to the PEG grammar that are all
// "oh, right, we need to actually normalise the data Lingua gives us
// so it's usable, since it won't reify numbers".
//
// There's also a lot of equality implementations here because, again,
// the Crochet compiler is not generating these yet. (Yes, deriving WILL
// come. Eventually).
//
// The only difference between part 1 and part 2 are the evaluation
// semantics of the instructions, so there are different evaluation
// frame types for each one.
singleton day2;
// -- Parsing woes (really, Lingua should be dealing with this aaaaaa)
abstract d2-instruction;
type d2i-forward(global value is integer) is d2-instruction;
type d2i-up(global value is integer) is d2-instruction;
type d2i-down(global value is integer) is d2-instruction;
type d2-program(global instructions is list<d2-instruction>);
implement equality for d2-instruction;
command d2-instruction === d2-instruction = false;
command d2i-forward === (That is d2i-forward) = (self value === That value);
command d2i-up === (That is d2i-up) = (self value === That value);
command d2i-down === (That is d2i-down) = (self value === That value);
implement equality for d2-program;
command d2-program === (That is d2-program) = (self instructions === That instructions);
command day2 parse: (Input is text) do
let Tree = day2-grammar parse: Input;
condition
when Tree is error => panic message: Tree reason tag: "syntax-error";
when Tree is ok => Tree value normalise;
end
test
let Program = "forward 5
down 5
forward 8
up 3
down 8
forward 2";
assert (day2 parse: Program) === new d2-program([
new d2i-forward(5),
new d2i-down(5),
new d2i-forward(8),
new d2i-up(3),
new d2i-down(8),
new d2i-forward(2),
])
end
command d2-ast normalise =
new d2-program(self.instructions map: (_ normalise));
command d2-node--forward normalise = new d2i-forward(#integer try-parse: self.value | value-or-panic: "not an integer");
command d2-node--up normalise = new d2i-up(#integer try-parse: self.value | value-or-panic: "not an integer");
command d2-node--down normalise = new d2i-down(#integer try-parse: self.value | value-or-panic: "not an integer");
// -- Evaluation woes (sadly you can't escape this one)
type d2-frame(
global x is integer,
global depth is integer,
);
implement equality for d2-frame;
command d2-frame === (That is d2-frame) =
(self x === That x) and (self depth === That depth);
command d2-frame evaluate: (I is d2i-forward) =
new d2-frame(self x + I value, self depth);
command d2-frame evaluate: (I is d2i-down) =
new d2-frame(self x, self depth + I value);
command d2-frame evaluate: (I is d2i-up) =
new d2-frame(self x, self depth - I value);
command #d2-frame initial =
new d2-frame(0, 0);
command d2-frame run: (Program is d2-program) do
Program instructions fold-from: self
with: (_ evaluate: _)
test
let Program = new d2-program([
new d2i-forward(5),
new d2i-down(5),
new d2i-forward(8),
new d2i-up(3),
new d2i-down(8),
new d2i-forward(2),
]);
assert (#d2-frame initial run: Program) === new d2-frame(15, 10);
end
command day2 part1 do
let Program = day2 parse: day2 input;
let Frame = #d2-frame initial run: Program;
Frame x * Frame depth;
test
assert day2 part1 === 1_746_616;
end
// -- Part 2 has a different evaluation semantics
type d2-frame2(
global x is integer,
global aim is integer,
global depth is integer,
);
implement equality for d2-frame2;
command d2-frame2 === (That is d2-frame2) =
(self x === That x) and
(self aim === That aim) and
(self depth === That depth);
command d2-frame2 evaluate: (I is d2i-forward) =
new d2-frame2(self x + I value, self aim, self depth + (self aim * I value));
command d2-frame2 evaluate: (I is d2i-down) =
new d2-frame2(self x, self aim + I value, self depth);
command d2-frame2 evaluate: (I is d2i-up) =
new d2-frame2(self x, self aim - I value, self depth);
command #d2-frame2 initial =
new d2-frame2(0, 0, 0);
command d2-frame2 run: (Program is d2-program) do
Program instructions fold-from: self
with: (_ evaluate: _)
test
let Program = new d2-program([
new d2i-forward(5),
new d2i-down(5),
new d2i-forward(8),
new d2i-up(3),
new d2i-down(8),
new d2i-forward(2),
]);
assert (#d2-frame2 initial run: Program) === new d2-frame2(15, 10, 60);
end
command day2 part2 do
let Program = day2 parse: day2 input;
let Frame = #d2-frame2 initial run: Program;
Frame x * Frame depth;
test
assert day2 part2 === 1_741_971_043;
end