Skip to content

Commit 35694a5

Browse files
committed
feat: runtime tests
1 parent 8096546 commit 35694a5

File tree

12 files changed

+422
-1
lines changed

12 files changed

+422
-1
lines changed

.claude/skills/testing-hashql/references/mir-builder-guide.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ The `<id>` can be a numeric literal (`0`, `1`, `42`) or a variable identifier (`
7777
| Syntax | Description | Example |
7878
| ------ | ----------- | ------- |
7979
| `Int` | Integer type | `Int` |
80+
| `Num` | Number (float) type | `Num` |
8081
| `Bool` | Boolean type | `Bool` |
8182
| `Null` | Null type | `Null` |
8283
| `(T1, T2, ...)` | Tuple types | `(Int, Bool, Int)` |

libs/@local/hashql/mir/src/builder/body.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,9 @@ macro_rules! body {
311311
(@type $types:ident; Int) => {
312312
$types.integer()
313313
};
314+
(@type $types:ident; Num) => {
315+
$types.number()
316+
};
314317
(@type $types:ident; ()) => {
315318
$types.tuple([] as [hashql_core::r#type::TypeId; 0])
316319
};

libs/@local/hashql/mir/src/interpret/tests.rs

Lines changed: 193 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use hashql_core::{
2525
use super::{
2626
CallStack, Runtime, RuntimeConfig,
2727
error::InterpretDiagnostic,
28-
value::{Int, Value},
28+
value::{Int, Num, Value},
2929
};
3030
use crate::{
3131
body::{
@@ -293,6 +293,158 @@ fn binary_gte_integers() {
293293
assert_eq!(result, Value::Integer(Int::from(true)));
294294
}
295295

296+
#[test]
297+
fn binary_add_integers() {
298+
let heap = Heap::new();
299+
let interner = Interner::new(&heap);
300+
let env = Environment::new(&heap);
301+
302+
let body = body!(interner, env; fn@0/0 -> Int {
303+
decl result: Int;
304+
305+
bb0() {
306+
result = bin.+ 2 3;
307+
return result;
308+
}
309+
});
310+
311+
let result = run_body(body).expect("should succeed");
312+
assert_eq!(result, Value::Integer(Int::from(5_i128)));
313+
}
314+
315+
#[test]
316+
fn binary_sub_integers() {
317+
let heap = Heap::new();
318+
let interner = Interner::new(&heap);
319+
let env = Environment::new(&heap);
320+
321+
let body = body!(interner, env; fn@0/0 -> Int {
322+
decl result: Int;
323+
324+
bb0() {
325+
result = bin.- 5 3;
326+
return result;
327+
}
328+
});
329+
330+
let result = run_body(body).expect("should succeed");
331+
assert_eq!(result, Value::Integer(Int::from(2_i128)));
332+
}
333+
334+
#[test]
335+
fn binary_add_numbers() {
336+
let heap = Heap::new();
337+
let interner = Interner::new(&heap);
338+
let env = Environment::new(&heap);
339+
340+
let body = body!(interner, env; fn@0/0 -> Num {
341+
decl result: Num;
342+
343+
bb0() {
344+
result = bin.+ 2.5 3.5;
345+
return result;
346+
}
347+
});
348+
349+
let result = run_body(body).expect("should succeed");
350+
assert_eq!(result, Value::Number(Num::from(6.0)));
351+
}
352+
353+
#[test]
354+
fn binary_sub_numbers() {
355+
let heap = Heap::new();
356+
let interner = Interner::new(&heap);
357+
let env = Environment::new(&heap);
358+
359+
let body = body!(interner, env; fn@0/0 -> Num {
360+
decl result: Num;
361+
362+
bb0() {
363+
result = bin.- 5.5 3.0;
364+
return result;
365+
}
366+
});
367+
368+
let result = run_body(body).expect("should succeed");
369+
assert_eq!(result, Value::Number(Num::from(2.5)));
370+
}
371+
372+
#[test]
373+
fn binary_add_int_number() {
374+
let heap = Heap::new();
375+
let interner = Interner::new(&heap);
376+
let env = Environment::new(&heap);
377+
378+
let body = body!(interner, env; fn@0/0 -> Num {
379+
decl result: Num;
380+
381+
bb0() {
382+
result = bin.+ 2 3.5;
383+
return result;
384+
}
385+
});
386+
387+
let result = run_body(body).expect("should succeed");
388+
assert_eq!(result, Value::Number(Num::from(5.5)));
389+
}
390+
391+
#[test]
392+
fn binary_add_number_int() {
393+
let heap = Heap::new();
394+
let interner = Interner::new(&heap);
395+
let env = Environment::new(&heap);
396+
397+
let body = body!(interner, env; fn@0/0 -> Num {
398+
decl result: Num;
399+
400+
bb0() {
401+
result = bin.+ 2.5 3;
402+
return result;
403+
}
404+
});
405+
406+
let result = run_body(body).expect("should succeed");
407+
assert_eq!(result, Value::Number(Num::from(5.5)));
408+
}
409+
410+
#[test]
411+
fn binary_sub_int_number() {
412+
let heap = Heap::new();
413+
let interner = Interner::new(&heap);
414+
let env = Environment::new(&heap);
415+
416+
let body = body!(interner, env; fn@0/0 -> Num {
417+
decl result: Num;
418+
419+
bb0() {
420+
result = bin.- 5 3.5;
421+
return result;
422+
}
423+
});
424+
425+
let result = run_body(body).expect("should succeed");
426+
assert_eq!(result, Value::Number(Num::from(1.5)));
427+
}
428+
429+
#[test]
430+
fn binary_sub_number_int() {
431+
let heap = Heap::new();
432+
let interner = Interner::new(&heap);
433+
let env = Environment::new(&heap);
434+
435+
let body = body!(interner, env; fn@0/0 -> Num {
436+
decl result: Num;
437+
438+
bb0() {
439+
result = bin.- 5.5 3;
440+
return result;
441+
}
442+
});
443+
444+
let result = run_body(body).expect("should succeed");
445+
assert_eq!(result, Value::Number(Num::from(2.5)));
446+
}
447+
296448
#[test]
297449
fn binary_bitand_integers() {
298450
let heap = Heap::new();
@@ -1115,6 +1267,46 @@ fn ice_unknown_field() {
11151267
assert_eq!(result.category, InterpretDiagnosticCategory::TypeInvariant);
11161268
}
11171269

1270+
#[test]
1271+
fn ice_binary_add_type_mismatch() {
1272+
let heap = Heap::new();
1273+
let interner = Interner::new(&heap);
1274+
let env = Environment::new(&heap);
1275+
1276+
let body = body!(interner, env; fn@0/0 -> Int {
1277+
decl tup: (Int, Int), result: Int;
1278+
1279+
bb0() {
1280+
tup = tuple 1, 2;
1281+
result = bin.+ tup 3;
1282+
return result;
1283+
}
1284+
});
1285+
1286+
let result = run_body(body).expect_err("should fail with binary add type mismatch");
1287+
assert_eq!(result.category, InterpretDiagnosticCategory::TypeInvariant);
1288+
}
1289+
1290+
#[test]
1291+
fn ice_binary_sub_type_mismatch() {
1292+
let heap = Heap::new();
1293+
let interner = Interner::new(&heap);
1294+
let env = Environment::new(&heap);
1295+
1296+
let body = body!(interner, env; fn@0/0 -> Int {
1297+
decl tup: (Int, Int), result: Int;
1298+
1299+
bb0() {
1300+
tup = tuple 1, 2;
1301+
result = bin.- 3 tup;
1302+
return result;
1303+
}
1304+
});
1305+
1306+
let result = run_body(body).expect_err("should fail with binary sub type mismatch");
1307+
assert_eq!(result.category, InterpretDiagnosticCategory::TypeInvariant);
1308+
}
1309+
11181310
#[test]
11191311
fn ice_binary_bitand_type_mismatch() {
11201312
let heap = Heap::new();

libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const_fold_add.snap

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const_fold_add_overflow.snap

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const_fold_sub.snap

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const_fold_sub_overflow.snap

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical_operand_sub.snap

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identity_add_zero.snap

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)