feat: implement M3 aggregate types and iteration
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
unit m3_array;
|
||||
|
||||
fn main() -> i32 {
|
||||
let a: [3]i32 = [1, 2, 3];
|
||||
let s: []i32 = a[..];
|
||||
let t: []i32 = s[1..3];
|
||||
if a[0] + s[1] + t[0] == 5 and s.n == 3 { return 0; }
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
unit m3_arrayctx;
|
||||
|
||||
fn main() -> i32 {
|
||||
let bytes: [3]u8 = [1, 2, 3];
|
||||
if bytes[0] == 1 and bytes[2] == 3 { return 0; }
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
unit fail_m3_array;
|
||||
fn main() -> i32 {
|
||||
let a: [2]i32 = [1, true, 3];
|
||||
return a[0];
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
unit fail_m3_char;
|
||||
|
||||
fn main() -> i32 {
|
||||
let u: u8 = 'A';
|
||||
return u;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
unit fail_m3_cycle;
|
||||
|
||||
struct A { b: B, }
|
||||
struct B { a: A, }
|
||||
|
||||
fn main() -> i32 { return 0; }
|
||||
@@ -0,0 +1,8 @@
|
||||
unit fail_m3_let_field;
|
||||
|
||||
struct Point { x: i32, y: i32, }
|
||||
fn main() -> i32 {
|
||||
let p: Point = Point{ x: 1, y: 2 };
|
||||
p.x = 3;
|
||||
return p.x;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
unit fail_m3_fields;
|
||||
struct Point { x: i32, y: i32, }
|
||||
fn main() -> i32 {
|
||||
let p: Point = Point{ x: 1 };
|
||||
return p.z;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
unit fail_m3_let_index;
|
||||
|
||||
fn main() -> i32 {
|
||||
let a: [2]i32 = [1, 2];
|
||||
a[0] = 3;
|
||||
return a[0];
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
unit fail_m3_match;
|
||||
enum Shape { Empty, Circle(i32), }
|
||||
fn main() -> i32 {
|
||||
match Shape.Empty { Empty => 0; }
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
unit fail_m3_str;
|
||||
fn main() -> i32 {
|
||||
var text: str = "abc";
|
||||
text[0] = 'z';
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
unit m3_bounds;
|
||||
|
||||
fn main() -> i32 {
|
||||
let a: [2]i32 = [1, 2];
|
||||
return a[2];
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
unit m3_char;
|
||||
|
||||
fn main() -> i32 {
|
||||
let c: char = '\u0041';
|
||||
let u: u8 = c as u8;
|
||||
let d: char = u as char;
|
||||
if c == d and u == ('A' as u8) { return 0; }
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
unit m3_enum;
|
||||
|
||||
enum Shape { Empty, Circle(i32), Rect { w: i32, h: i32, }, }
|
||||
|
||||
fn score(s: Shape) -> i32 {
|
||||
match s {
|
||||
Empty => { return 0; }
|
||||
Circle(value) => { return value; }
|
||||
Rect { w, h } => { return w * h; }
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> i32 {
|
||||
if score(Shape.Circle(5)) == 5 and score(Shape.Rect{ w: 2, h: 3 }) == 6 { return 0; }
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
unit m3_for;
|
||||
|
||||
fn main() -> i32 {
|
||||
var total: i32 = 0;
|
||||
let a: [3]i32 = [1, 2, 3];
|
||||
let s: []i32 = a[..];
|
||||
var m: [1]i32 = [1];
|
||||
let ready: bool = true;
|
||||
if ready { total += 0; }
|
||||
while false { total += 100; }
|
||||
for x in a { total += x.^; }
|
||||
for i, x in a { if i == 1 and x.^ == 2 { total += 1; } }
|
||||
for x in "ab" { if x.^ == ('a' as u8) { total += 1; } }
|
||||
for x in s { if x.^ == 3 { total += 1; } }
|
||||
for x in m { x.^ = 2; }
|
||||
if total == 9 and m[0] == 2 { return 0; }
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
unit m3_nested;
|
||||
|
||||
struct Outer { inner: Inner, }
|
||||
struct Inner { value: i32, }
|
||||
|
||||
fn main() -> i32 {
|
||||
let x: Outer = Outer{ inner: Inner{ value: 7 } };
|
||||
if x.inner.value == 7 { return 0; }
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
unit m3_str;
|
||||
|
||||
fn main() -> i32 {
|
||||
let text: str = "abc";
|
||||
if text[1] == ('b' as u8) and text.n == 3 { return 0; }
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
unit m3_struct;
|
||||
|
||||
struct Point { x: i32, y: i32, }
|
||||
packed struct PackedPoint { x: u8, y: i32, }
|
||||
struct Natural { a: u8, b: i32, }
|
||||
|
||||
fn main() -> i32 {
|
||||
let p: Point = Point{ x: 3, y: 4 };
|
||||
let q: PackedPoint = PackedPoint{ x: 1, y: 6 };
|
||||
let n: Natural = Natural{ a: 1, b: 2 };
|
||||
if p.x + p.y == 7 and q.y == 6 and n.b == 2 and
|
||||
(Point{ x: 1, y: 2 }.x == 1) and @size_of(Natural) == 8 { return 0; }
|
||||
return 1;
|
||||
}
|
||||
@@ -40,3 +40,24 @@ for f in bad-condition bad-cast bad-assign bad-unknown bad-arity bad-types bad-r
|
||||
fi
|
||||
done
|
||||
echo "M2 tests: integer control-flow smoke passed"
|
||||
|
||||
m3tmp=$(mktemp -d)
|
||||
trap 'rm -rf "$m2tmp" "$m3tmp"' EXIT HUP INT TERM
|
||||
for f in struct enum array arrayctx str for nested char; do
|
||||
"$root"/fec --target=bits32 --emit-c "$root"/tests/m3/$f.fe -o "$m3tmp/$f.c"
|
||||
${CC:-cc} -std=c89 -pedantic "$m3tmp/$f.c" -o "$m3tmp/$f"
|
||||
"$m3tmp/$f"
|
||||
done
|
||||
"$root"/fec --target=bits32 --emit-c "$root"/tests/m3/bounds.fe -o "$m3tmp/bounds.c"
|
||||
${CC:-cc} -std=c89 -pedantic "$m3tmp/bounds.c" -o "$m3tmp/bounds"
|
||||
if "$m3tmp/bounds"; then
|
||||
echo "FAIL (bounds trap did not fire): tests/m3/bounds.fe"
|
||||
exit 1
|
||||
fi
|
||||
for f in badfld badmat badarr badcycle badstr badchar badfield badindex; do
|
||||
if "$root"/fec --target=bits32 --emit-c "$root"/tests/m3/$f.fe -o "$m3tmp/$f.c" >/dev/null 2>/dev/null; then
|
||||
echo "FAIL (accepted M3 semantic error): $f.fe"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
echo "M3 tests: structs, enums, arrays, slices, str, match, and bounds passed"
|
||||
|
||||
Reference in New Issue
Block a user