vyre-libs 0.7.2

vyre Category A library ecosystem - pure-IR compositions over foundation IR and primitive-owned kernels
Documentation
use super::*;

pub(in crate::parsing::c::parse::vast) const DECL_KIND_FOR_ROW_OP_ID: &str =
    "vyre-libs::parsing::c11_typedef_decl_kind_for_row";
pub(in crate::parsing::c::parse::vast) const DECL_KIND_FOR_ROW_PACKED_OP_ID: &str =
    "vyre-libs::parsing::c11_typedef_decl_kind_for_row_packed_haystack";

pub(crate) fn emit_declaration_kind_for_index(
    vast_nodes: &str,
    haystack: &str,
    haystack_len: &Expr,
    idx: Expr,
    out_name: &str,
    prefix: &str,
    packed_haystack: bool,
    decl_contexts: Option<&str>,
) -> Vec<Node> {
    emit_declaration_kind_for_index_inner(
        vast_nodes,
        decl_contexts,
        idx,
        out_name,
        prefix,
        Some((haystack, haystack_len, packed_haystack)),
    )
}

pub(crate) fn emit_builtin_declaration_kind_for_index(
    vast_nodes: &str,
    idx: Expr,
    out_name: &str,
    prefix: &str,
    decl_contexts: Option<&str>,
) -> Vec<Node> {
    emit_declaration_kind_for_index_inner(vast_nodes, decl_contexts, idx, out_name, prefix, None)
}

fn decl_kind_phase_program(op_id: &str, packed_haystack: bool) -> Program {
    const NODES: &str = "phase_vast_nodes";
    const HAYSTACK: &str = "phase_haystack";
    const ROW: &str = "phase_row";
    const HAYSTACK_LEN: &str = "phase_haystack_len";
    const NUM_NODES: &str = "phase_num_nodes";
    const RESULT: &str = "phase_result";

    let row = Expr::load(ROW, Expr::u32(0));
    let haystack_len = Expr::load(HAYSTACK_LEN, Expr::u32(0));
    let mut body = vec![Node::let_bind(
        "annot_num_nodes",
        Expr::load(NUM_NODES, Expr::u32(0)),
    )];
    body.extend(emit_declaration_kind_for_index(
        NODES,
        HAYSTACK,
        &haystack_len,
        row,
        RESULT,
        "phase_decl",
        packed_haystack,
        None,
    ));
    body.push(Node::store(RESULT, Expr::u32(0), Expr::var(RESULT)));

    let buffers = vec![
        BufferDecl::storage(NODES, 0, BufferAccess::ReadOnly, DataType::U32)
            .with_count(PHASE_WITNESS_ROWS.saturating_mul(VAST_NODE_STRIDE_U32)),
        BufferDecl::storage(HAYSTACK, 1, BufferAccess::ReadOnly, DataType::U32)
            .with_count(source_haystack_words(PHASE_WITNESS_SOURCE_LEN, packed_haystack)),
        BufferDecl::storage(ROW, 2, BufferAccess::ReadOnly, DataType::U32).with_count(1),
        BufferDecl::storage(HAYSTACK_LEN, 3, BufferAccess::ReadOnly, DataType::U32).with_count(1),
        BufferDecl::storage(NUM_NODES, 4, BufferAccess::ReadOnly, DataType::U32).with_count(1),
        BufferDecl::output(RESULT, 5, DataType::U32).with_count(1),
    ];
    let implementation = child_phase(op_id, &format!("{op_id}::declaration_scan"), body);
    Program::wrapped(
        buffers,
        [256, 1, 1],
        vec![wrap_anonymous(op_id, vec![implementation])],
    )
    .with_entry_op_id(op_id)
}

pub(in crate::parsing::c::parse::vast) fn c11_typedef_decl_kind_for_row() -> Program {
    decl_kind_phase_program(DECL_KIND_FOR_ROW_OP_ID, false)
}

pub(in crate::parsing::c::parse::vast) fn c11_typedef_decl_kind_for_row_packed_haystack() -> Program
{
    decl_kind_phase_program(DECL_KIND_FOR_ROW_PACKED_OP_ID, true)
}

pub(crate) fn emit_declaration_kind_result_assignment(
    out_name: &str,
    is_identifier: Expr,
    declarator_follower: Expr,
    previous_token_allows_declarator: Expr,
    next_token_allows_declarator: Expr,
    contextual_declarator_allowed: Expr,
    has_typedef: Expr,
    has_type: Expr,
) -> Node {
    Node::if_then(
        Expr::and(
            is_identifier,
            Expr::and(
                declarator_follower,
                Expr::and(
                    previous_token_allows_declarator,
                    Expr::and(
                        next_token_allows_declarator,
                        Expr::and(
                            contextual_declarator_allowed,
                            Expr::or(has_typedef.clone(), has_type),
                        ),
                    ),
                ),
            ),
        ),
        vec![Node::assign(
            out_name,
            Expr::select(has_typedef, Expr::u32(1), Expr::u32(2)),
        )],
    )
}