use crate::ir::{BufferDecl, DataType, Expr, Node, Program};
use crate::ops::AlgebraicLaw;
use crate::ops::OpSpec;
pub const INPUTS: &[DataType] = &[DataType::Bytes];
pub const LAWS: &[AlgebraicLaw] = &[AlgebraicLaw::Bounded {
lo: 0,
hi: u32::MAX,
}];
pub const OUTPUTS: &[DataType] = &[DataType::U32, DataType::U32, DataType::U32];
#[must_use]
pub fn prefix_brace_program() -> Program {
Program::new(
vec![
BufferDecl::read("file_bytes", 0, DataType::Bytes),
BufferDecl::output("brace_depths", 1, DataType::U32),
BufferDecl::read_write("nested_depths", 2, DataType::U32),
BufferDecl::read_write("newline_sums", 3, DataType::U32),
],
[1, 1, 1],
vec![
Node::let_bind("file_size", Expr::buf_len("file_bytes")),
Node::store("newline_sums", Expr::u32(0), Expr::u32(0)),
Node::if_then(
Expr::gt(Expr::var("file_size"), Expr::u32(0)),
vec![
Node::let_bind("brace_depth", Expr::u32(0)),
Node::let_bind("nested_depth", Expr::u32(0)),
Node::let_bind("newline_count", Expr::u32(0)),
Node::loop_for(
"i",
Expr::u32(0),
Expr::var("file_size"),
vec![
Node::store("brace_depths", Expr::var("i"), Expr::var("brace_depth")),
Node::store("nested_depths", Expr::var("i"), Expr::var("nested_depth")),
Node::let_bind("byte", Expr::load("file_bytes", Expr::var("i"))),
Node::if_then(
Expr::eq(Expr::var("byte"), Expr::u32(123)),
vec![
Node::assign(
"brace_depth",
Expr::add(Expr::var("brace_depth"), Expr::u32(1)),
),
Node::assign(
"nested_depth",
Expr::add(Expr::var("nested_depth"), Expr::u32(1)),
),
],
),
Node::if_then(
Expr::eq(Expr::var("byte"), Expr::u32(125)),
vec![
Node::if_then(
Expr::gt(Expr::var("brace_depth"), Expr::u32(0)),
vec![Node::assign(
"brace_depth",
Expr::sub(Expr::var("brace_depth"), Expr::u32(1)),
)],
),
Node::if_then(
Expr::gt(Expr::var("nested_depth"), Expr::u32(0)),
vec![Node::assign(
"nested_depth",
Expr::sub(Expr::var("nested_depth"), Expr::u32(1)),
)],
),
],
),
Node::if_then(
Expr::eq(Expr::var("byte"), Expr::u32(40)),
vec![Node::assign(
"nested_depth",
Expr::add(Expr::var("nested_depth"), Expr::u32(1)),
)],
),
Node::if_then(
Expr::eq(Expr::var("byte"), Expr::u32(41)),
vec![Node::if_then(
Expr::gt(Expr::var("nested_depth"), Expr::u32(0)),
vec![Node::assign(
"nested_depth",
Expr::sub(Expr::var("nested_depth"), Expr::u32(1)),
)],
)],
),
Node::if_then(
Expr::eq(Expr::var("byte"), Expr::u32(10)),
vec![Node::assign(
"newline_count",
Expr::add(Expr::var("newline_count"), Expr::u32(1)),
)],
),
Node::store(
"newline_sums",
Expr::add(Expr::var("i"), Expr::u32(1)),
Expr::var("newline_count"),
),
],
),
],
),
],
)
}
pub const SPEC: OpSpec = OpSpec::composition(
"string.prefix_brace",
INPUTS,
OUTPUTS,
LAWS,
prefix_brace_program,
);