feat: implement M4 formatting builtins
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
unit m4_bad_arity;
|
||||
|
||||
fn main() -> i32 {
|
||||
@print("{} {}", 1);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
unit m4_bad_cls;
|
||||
|
||||
fn main() -> i32 {
|
||||
@print("}", 1);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
unit m4_bad_many;
|
||||
|
||||
fn main() -> i32 {
|
||||
@print("{}", 1, 2);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
unit m4_bad_open;
|
||||
|
||||
fn main() -> i32 {
|
||||
@print("{", 1);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
unit m4_bad_runtime;
|
||||
|
||||
fn main() -> i32 {
|
||||
var fmt: str = "{}";
|
||||
@print(fmt, 1);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
unit m4_bad_try;
|
||||
|
||||
fn main() -> i32 {
|
||||
try @print("nope");
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
unit m4_bad_type;
|
||||
|
||||
struct Point { x: i32, }
|
||||
|
||||
fn main() -> i32 {
|
||||
let p: Point = Point{ x: 1 };
|
||||
@print("{}", p);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
unit m4_bad_verb;
|
||||
|
||||
fn main() -> i32 {
|
||||
@print("{q}", 1);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
unit m4_bad_writer;
|
||||
|
||||
fn main() -> i32 {
|
||||
var x: i32 = 0;
|
||||
@fprint(&mut x, "bad");
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
unit m4_format;
|
||||
|
||||
const FMT: str = "n={} hex={x} c={c} s={s} b={b} {{ok}}\n";
|
||||
|
||||
fn main() -> i32 {
|
||||
var raw: [8]u8 = [0, 0, 0, 0, 0, 0, 0, 0];
|
||||
var raw2: [8]u8 = [0, 0, 0, 0, 0, 0, 0, 0];
|
||||
var raw3: [8]u8 = [0, 0, 0, 0, 0, 0, 0, 0];
|
||||
var raw4: [8]u8 = [0, 0, 0, 0, 0, 0, 0, 0];
|
||||
var raw5: [8]u8 = [0, 0, 0, 0, 0, 0, 0, 0];
|
||||
var buf: []u8 = raw[..];
|
||||
var buf2: []u8 = raw2[..];
|
||||
var buf3: []u8 = raw3[..];
|
||||
var buf4: []u8 = raw4[..];
|
||||
var buf5: []u8 = raw5[..];
|
||||
let w: io.Writer = io.buf_writer(&mut buf);
|
||||
const LOCAL_FMT: str = "value={}\n";
|
||||
@print(FMT, 7, 15, 'A', "yes", true);
|
||||
@fprint(&mut w, LOCAL_FMT, 12);
|
||||
let n: usize = @sprint(buf2, "A\x42\u0043defghi");
|
||||
let n2: usize = @sprint(buf3, "xy");
|
||||
let inner_n: usize = @sprint(buf4, "xy");
|
||||
let outer_n: usize = @sprint(buf5, "n={}", @sprint(buf4, "xy"));
|
||||
if n == 8 and buf2[0] == ('A' as u8) and
|
||||
buf2[1] == ('B' as u8) and buf2[2] == ('C' as u8) and
|
||||
n2 == 2 and buf3[0] == ('x' as u8) and
|
||||
inner_n == 2 and outer_n == 3 and
|
||||
buf5[0] == ('n' as u8) and buf5[2] == ('2' as u8) { return 0; }
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
unit m4_prop;
|
||||
|
||||
pub fn propagate(w: &mut io.Writer) -> !void {
|
||||
try @fprint(w, "a{}b", 1);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#include "prop.c"
|
||||
|
||||
static unsigned short calls;
|
||||
|
||||
static unsigned short fail_write(void *ctx, const unsigned char *p,
|
||||
unsigned long n)
|
||||
{
|
||||
(void)ctx;
|
||||
(void)p;
|
||||
(void)n;
|
||||
++calls;
|
||||
return calls == 1 ? 7 : 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
fe_writer w;
|
||||
unsigned short result;
|
||||
w.ctx=0;
|
||||
w.write_fn=fail_write;
|
||||
result=fe_m4_prop_propagate(&w);
|
||||
return (result==7 && calls==1) ? 0 : 1;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
unit m4_try_fprint;
|
||||
|
||||
fn main() -> !void {
|
||||
var raw: [4]u8 = [0, 0, 0, 0];
|
||||
var buf: []u8 = raw[..];
|
||||
let w: io.Writer = io.buf_writer(&mut buf);
|
||||
try @fprint(&mut w, "ok");
|
||||
}
|
||||
@@ -61,3 +61,33 @@ for f in badfld badmat badarr badcycle badstr badchar badfield badindex; do
|
||||
fi
|
||||
done
|
||||
echo "M3 tests: structs, enums, arrays, slices, str, match, and bounds passed"
|
||||
|
||||
m4tmp=$(mktemp -d)
|
||||
trap 'rm -rf "$m2tmp" "$m3tmp" "$m4tmp"' EXIT HUP INT TERM
|
||||
for f in format; do
|
||||
"$root"/fec --target=bits32 --emit-c "$root"/tests/m4/$f.fe -o "$m4tmp/$f.c"
|
||||
${CC:-cc} -std=c89 -pedantic "$m4tmp/$f.c" -o "$m4tmp/$f"
|
||||
"$m4tmp/$f" >"$m4tmp/$f.out"
|
||||
done
|
||||
for f in try-fprint; do
|
||||
"$root"/fec --target=bits32 --emit-c "$root"/tests/m4/$f.fe -o "$m4tmp/$f.c"
|
||||
${CC:-cc} -std=c89 -pedantic "$m4tmp/$f.c" -o "$m4tmp/$f"
|
||||
"$m4tmp/$f"
|
||||
done
|
||||
"$root"/fec --target=bits32 --emit-c "$root"/tests/m4/prop.fe -o "$m4tmp/prop.c"
|
||||
cp "$root"/tests/m4/proptest.c "$m4tmp/proptest.c"
|
||||
${CC:-cc} -std=c89 -pedantic "$m4tmp/proptest.c" -o "$m4tmp/prop"
|
||||
"$m4tmp/prop"
|
||||
for f in bad-arity bad-verb bad-runtime bad-type bad-try bad-writer; do
|
||||
if "$root"/fec --target=bits32 --emit-c "$root"/tests/m4/$f.fe -o "$m4tmp/$f.c" >/dev/null 2>/dev/null; then
|
||||
echo "FAIL (accepted M4 semantic error): $f.fe"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
for f in bad-many bad-open bad-cls; do
|
||||
if "$root"/fec --target=bits32 --emit-c "$root"/tests/m4/$f.fe -o "$m4tmp/$f.c" >/dev/null 2>/dev/null; then
|
||||
echo "FAIL (accepted M4 format-brace error): $f.fe"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
echo "M4 tests: formatting builtins passed"
|
||||
|
||||
Reference in New Issue
Block a user