2 Using the Backend Directly
Most users should stay at the source-language level and use #lang intercal or #lang reader "intercal.rkt". The repository also exposes the lower level backend used by the reader. That backend is useful for:
frontend and runtime regression tests,
macro-expansion inspection,
debugging semantic mismatches in the evaluator, and
writing small programs directly in the normalized S-expression form.
These interfaces live in "sick.rkt". They are developer-facing APIs, not the main end-user surface of the package, but they are important enough to document because the test suite, tutorial material, and debugging workflow all use them.
2.1 Main Entry Points
syntax
(sick-program line ...)
This is useful when you want a minimal runtime test or when you are already working directly in the normalized S-expression form produced by "ick-normalize.rkt".
syntax
(sick-program/syslib line ...)
This is the form used by the normal source-language frontend, since real INTERCAL programs rely on syslib helpers for arithmetic and control support.
syntax
(sick-program-core line-ir ...)
This form is primarily for compiler debugging. Handwritten programs should normally use sick-program or sick-program/syslib instead.
2.2 A Minimal Backend Example
(call-with-values (lambda () (parameterize ([sick-capture-output #t]) (sick-program (10 (do (assign 0.1 (mesh 1)))) (20 (do (read-out 0.1))) (30 (please (give-up)))))) list)
This corresponds to the INTERCAL program:
DO .1 <- #1 |
DO READ OUT .1 |
PLEASE GIVE UP |
The backend example is useful when you want to isolate runtime semantics without involving the lexer and parser.
2.3 Backend Helpers
procedure
(mesh rn) → exact-integer?
rn : (or/c exact-integer? symbol?)
This is mainly useful in handwritten sick-program tests, where (mesh 10) and (mesh 'X) both denote the same INTERCAL constant.
procedure
(clean-intercal-source str) → string?
str : string?
This step merges continuation lines, keeps only parseable INTERCAL statements, and preserves the upstream-style prefix forms accepted by the frontend. It is useful when debugging reader behavior independently of runtime semantics.
2.4 Useful Runtime Parameters
The backend exposes several parameters that are especially helpful while testing or debugging:
sick-capture-output: when true, READ OUT accumulates values and returns them as multiple values instead of only printing.
sick-debug: enables runtime tracing.
sick-debug-lines and sick-debug-vars: restrict tracing to specific lines or variables.
sick-break-lines and sick-break-repeat: stop execution at selected lines or after a repeated control-flow state.
sick-max-steps: aborts a run after a bounded number of executed steps.
For example:
(parameterize ([sick-capture-output #t] [sick-max-steps 1000]) (call-with-values (lambda () (sick-program (10 (do (assign 0.1 (mesh 1)))) (20 (do (read-out 0.1))) (30 (please (give-up))))) list))
parameter
(sick-capture-output) → boolean?
(sick-capture-output capture?) → void? capture? : boolean?
parameter
(sick-debug) → boolean?
(sick-debug enabled?) → void? enabled? : boolean?
parameter
(sick-debug-lines) → (or/c #f (listof exact-integer?))
(sick-debug-lines maybe-lines) → void? maybe-lines : (or/c #f (listof exact-integer?))
parameter
(sick-debug-vars) → (or/c #f (listof symbol?))
(sick-debug-vars maybe-vars) → void? maybe-vars : (or/c #f (listof symbol?))
parameter
(sick-break-lines) → (or/c #f (listof exact-integer?))
(sick-break-lines maybe-lines) → void? maybe-lines : (or/c #f (listof exact-integer?))
parameter
(sick-break-repeat) → (or/c #f exact-positive-integer?)
(sick-break-repeat maybe-count) → void? maybe-count : (or/c #f exact-positive-integer?)
parameter
(sick-max-steps) → (or/c #f exact-positive-integer?)
(sick-max-steps maybe-limit) → void? maybe-limit : (or/c #f exact-positive-integer?)
2.5 When to Use the Backend
Use the backend directly when you want to:
write a focused runtime regression test,
inspect the macro-generated Racket code for a small fragment,
test syslib-driven control flow without going through the textual frontend, or
debug a pit program by progressively narrowing the problem to the evaluator.