Skip to content

Commit 48e289e

Browse files
hyperpolymathclaude
andcommitted
feat(quantity): wire QTT enforcement into all compiler pipelines
Stage 1 of AffineScript TEA dogfood plan. quantity.ml (21KB of complete QTT semiring + usage tracking) was implemented but never called. Now wired into all six pipeline paths: check_file (json + human) — after borrow check compile_file (json + human) — after borrow check, before codegen eval_file (json + human) — after typecheck (eval has no borrow check) Error format: "@linear binding 'x' must be used exactly once, but was used multiple times" — names the variable, states the violation. All 7 E2E Quantity tests pass. 20 Golden failures are pre-existing (AST snapshot drift, unrelated to this change). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 9222690 commit 48e289e

1 file changed

Lines changed: 53 additions & 17 deletions

File tree

bin/main.ml

Lines changed: 53 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,12 @@ let check_file face json path =
155155
(match Affinescript.Borrow.check_program resolve_ctx.symbols prog with
156156
| Error e ->
157157
add (Affinescript.Json_output.of_borrow_error e)
158-
| Ok () -> ())))
158+
| Ok () ->
159+
(* Stage 1: QTT quantity enforcement *)
160+
(match Affinescript.Quantity.check_program_quantities prog with
161+
| Error (err, span) ->
162+
add (Affinescript.Json_output.of_quantity_error (err, span))
163+
| Ok () -> ()))))
159164
with
160165
| Affinescript.Lexer.Lexer_error (msg, pos) ->
161166
add (Affinescript.Json_output.of_lexer_error msg pos path)
@@ -200,8 +205,15 @@ let check_file face json path =
200205
(Affinescript.Face.format_borrow_error face e);
201206
`Error (false, "Borrow error")
202207
| Ok () ->
203-
Format.printf "Type checking passed@.";
204-
`Ok ())))
208+
(* Stage 1: QTT quantity enforcement *)
209+
(match Affinescript.Quantity.check_program_quantities prog with
210+
| Error (err, _span) ->
211+
Format.eprintf "@[<v>Quantity error: %s@]@."
212+
(Affinescript.Face.format_quantity_error face err);
213+
`Error (false, "Quantity error")
214+
| Ok () ->
215+
Format.printf "Type checking passed@.";
216+
`Ok ()))))
205217
with
206218
| Affinescript.Lexer.Lexer_error (msg, pos) ->
207219
Format.eprintf "@[<v>%s:%d:%d: lexer error: %s@]@." path pos.line pos.col msg;
@@ -236,10 +248,15 @@ let eval_file face json path =
236248
| Error e ->
237249
add (Affinescript.Json_output.of_type_error e)
238250
| Ok () ->
239-
(match Affinescript.Interp.eval_program prog with
240-
| Ok _env -> ()
241-
| Error e ->
242-
add (Affinescript.Json_output.of_eval_error e))))
251+
(* Stage 1: QTT quantity enforcement *)
252+
(match Affinescript.Quantity.check_program_quantities prog with
253+
| Error (err, span) ->
254+
add (Affinescript.Json_output.of_quantity_error (err, span))
255+
| Ok () ->
256+
(match Affinescript.Interp.eval_program prog with
257+
| Ok _env -> ()
258+
| Error e ->
259+
add (Affinescript.Json_output.of_eval_error e)))))
243260
with
244261
| Affinescript.Lexer.Lexer_error (msg, pos) ->
245262
add (Affinescript.Json_output.of_lexer_error msg pos path)
@@ -269,14 +286,21 @@ let eval_file face json path =
269286
(Affinescript.Face.format_type_error face e);
270287
`Error (false, "Type error")
271288
| Ok () ->
272-
(match Affinescript.Interp.eval_program prog with
273-
| Ok _env ->
274-
Format.printf "Program executed successfully@.";
275-
`Ok ()
276-
| Error e ->
277-
Format.eprintf "@[<v>Runtime error: %s@]@."
278-
(Affinescript.Value.show_eval_error e);
279-
`Error (false, "Runtime error"))))
289+
(* Stage 1: QTT quantity enforcement *)
290+
(match Affinescript.Quantity.check_program_quantities prog with
291+
| Error (err, _span) ->
292+
Format.eprintf "@[<v>Quantity error: %s@]@."
293+
(Affinescript.Face.format_quantity_error face err);
294+
`Error (false, "Quantity error")
295+
| Ok () ->
296+
(match Affinescript.Interp.eval_program prog with
297+
| Ok _env ->
298+
Format.printf "Program executed successfully@.";
299+
`Ok ()
300+
| Error e ->
301+
Format.eprintf "@[<v>Runtime error: %s@]@."
302+
(Affinescript.Value.show_eval_error e);
303+
`Error (false, "Runtime error")))))
280304
with
281305
| Affinescript.Lexer.Lexer_error (msg, pos) ->
282306
Format.eprintf "@[<v>%s:%d:%d: lexer error: %s@]@." path pos.line pos.col msg;
@@ -318,6 +342,11 @@ let compile_file face json wasm_gc path output =
318342
| Error e ->
319343
add (Affinescript.Json_output.of_borrow_error e)
320344
| Ok () ->
345+
(* Stage 1: QTT quantity enforcement *)
346+
(match Affinescript.Quantity.check_program_quantities prog with
347+
| Error (err, span) ->
348+
add (Affinescript.Json_output.of_quantity_error (err, span))
349+
| Ok () ->
321350
let is_julia = Filename.check_suffix output ".jl" in
322351
if is_julia then begin
323352
match Affinescript.Julia_codegen.codegen_julia prog resolve_ctx.symbols with
@@ -348,7 +377,7 @@ let compile_file face json wasm_gc path output =
348377
span = Affinescript.Span.dummy; help = None; labels = [] }
349378
| Ok wasm_module ->
350379
Affinescript.Wasm_encode.write_module_to_file output wasm_module
351-
end)))
380+
end))))
352381
with
353382
| Affinescript.Lexer.Lexer_error (msg, pos) ->
354383
add (Affinescript.Json_output.of_lexer_error msg pos path)
@@ -379,6 +408,13 @@ let compile_file face json wasm_gc path output =
379408
(Affinescript.Face.format_borrow_error face e);
380409
`Error (false, "Borrow error")
381410
| Ok () ->
411+
(* Stage 1: QTT quantity enforcement *)
412+
(match Affinescript.Quantity.check_program_quantities prog with
413+
| Error (err, _span) ->
414+
Format.eprintf "@[<v>Quantity error: %s@]@."
415+
(Affinescript.Face.format_quantity_error face err);
416+
`Error (false, "Quantity error")
417+
| Ok () ->
382418
begin
383419
let is_julia = Filename.check_suffix output ".jl" in
384420
if is_julia then
@@ -413,7 +449,7 @@ let compile_file face json wasm_gc path output =
413449
Affinescript.Wasm_encode.write_module_to_file output wasm_module;
414450
Format.printf "Compiled %s -> %s (WASM)@." path output;
415451
`Ok ())
416-
end)))
452+
end))))
417453
with
418454
| Affinescript.Lexer.Lexer_error (msg, pos) ->
419455
Format.eprintf "@[<v>%s:%d:%d: lexer error: %s@]@." path pos.line pos.col msg;

0 commit comments

Comments
 (0)