Skip to content

Commit ddb78e1

Browse files
committed
fix: comparison operators in ZynML grammar and signed integer comparisons
- Fix comparison expressions in ml.zyn grammar to properly build Binary expressions instead of discarding the operator with `-> inner` - Add comparison_with_op and comparison_no_op rules to handle `a < b` etc. - Fix Cranelift backend to use operand type (not result type) for signed vs unsigned comparison selection - Add SSA lowering to pass operand type for comparison instructions - While loops and if statements now work correctly with comparisons Also adds minimal test examples for stdlib features: - test_01 through test_13 for println, arithmetic, control flow, etc. - hello_basic.zynml as working tensor example without f-strings
1 parent 25f810a commit ddb78e1

31 files changed

Lines changed: 653 additions & 94 deletions

crates/compiler/src/cranelift_backend.rs

Lines changed: 299 additions & 90 deletions
Large diffs are not rendered by default.

crates/compiler/src/ssa.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,7 +1343,7 @@ impl SsaBuilder {
13431343
) -> CompilerResult<HirId> {
13441344
use zyntax_typed_ast::typed_ast::TypedExpression;
13451345
use crate::hir::{BinaryOp, UnaryOp};
1346-
1346+
13471347
match &expr.node {
13481348
TypedExpression::Variable(name) => {
13491349
// Check if this is an address-taken variable - need to load from stack
@@ -1484,12 +1484,24 @@ impl SsaBuilder {
14841484
let result_type = self.convert_type(&expr.ty);
14851485

14861486
let hir_op = self.convert_binary_op(op);
1487+
1488+
// For comparisons, use the operand type (not Bool result type) for the instruction
1489+
let inst_type = match hir_op {
1490+
crate::hir::BinaryOp::Lt | crate::hir::BinaryOp::Le |
1491+
crate::hir::BinaryOp::Gt | crate::hir::BinaryOp::Ge |
1492+
crate::hir::BinaryOp::Eq | crate::hir::BinaryOp::Ne => {
1493+
// Use the left operand type so cranelift can determine signed/unsigned
1494+
self.convert_type(&left.ty)
1495+
}
1496+
_ => result_type.clone()
1497+
};
1498+
14871499
let result = self.create_value(result_type.clone(), HirValueKind::Instruction);
14881500

14891501
let inst = HirInstruction::Binary {
14901502
op: hir_op,
14911503
result,
1492-
ty: result_type,
1504+
ty: inst_type,
14931505
left: left_val,
14941506
right: right_val,
14951507
};
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Basic hello.zynml - test core tensor operations
2+
import tensor
3+
4+
def main() {
5+
println("Hello from ZynML!")
6+
7+
// Create tensors using arange (which works)
8+
let a = Tensor::arange(1.0, 5.0, 1.0) // [1.0, 2.0, 3.0, 4.0]
9+
let b = Tensor::arange(5.0, 9.0, 1.0) // [5.0, 6.0, 7.0, 8.0]
10+
11+
println("Tensor a:")
12+
println(a)
13+
14+
println("Tensor b:")
15+
println(b)
16+
17+
// Arithmetic operations using operator overloading
18+
let sum = a + b
19+
println("a + b:")
20+
println(sum)
21+
22+
let diff = b - a
23+
println("b - a:")
24+
println(diff)
25+
26+
let prod = a * b
27+
println("a * b (element-wise):")
28+
println(prod)
29+
30+
// Reduction operations
31+
let total = a.sum()
32+
println("Sum of a:")
33+
println(total)
34+
35+
let avg = a.mean()
36+
println("Mean of a:")
37+
println(avg)
38+
39+
println("Done!")
40+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Test 01: Basic println with string
2+
import prelude
3+
4+
def main() {
5+
println("Hello World!")
6+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Test 02: Basic println with integers
2+
import prelude
3+
4+
def main() {
5+
println(42)
6+
println(-10)
7+
println(0)
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Test 03: Basic println with floats
2+
import prelude
3+
4+
def main() {
5+
println(3.14)
6+
println(-2.5)
7+
println(0.0)
8+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Test 04: Let bindings
2+
import prelude
3+
4+
def main() {
5+
let x = 42
6+
let name = "Alice"
7+
let pi = 3.14159
8+
9+
println(x)
10+
println(name)
11+
println(pi)
12+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Test 05: Basic arithmetic
2+
import prelude
3+
4+
def main() {
5+
let a = 10
6+
let b = 3
7+
8+
println(a + b)
9+
println(a - b)
10+
println(a * b)
11+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Test 06: Function definitions and calls
2+
import prelude
3+
4+
def add(a: int, b: int): int {
5+
a + b
6+
}
7+
8+
def greet(name: str) {
9+
println(name)
10+
}
11+
12+
def main() {
13+
let result = add(5, 7)
14+
println(result)
15+
greet("Hello from function!")
16+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Test 07: If-else control flow
2+
import prelude
3+
4+
def main() {
5+
let x = 10
6+
7+
if x > 5 {
8+
println("x is greater than 5")
9+
} else {
10+
println("x is not greater than 5")
11+
}
12+
}

0 commit comments

Comments
 (0)