netidx-bscript 0.28.2

An incremental scripting language for netidx
Documentation
use super::{
    callsite::CallSite, lambda::Lambda, select::Select, Add, And, Any, Array, ArrayRef,
    ArraySlice, Bind, Block, Connect, Constant, Div, Eq, Gt, Gte, Lt, Lte, Mul, Ne, Not,
    Or, Qop, Ref, StringInterpolate, Struct, StructRef, StructWith, Sub, Tuple, TupleRef,
    TypeCast, TypeDef, Use, Variant, ByRef, Deref,
};
use crate::{
    expr::{Expr, ExprId, ExprKind, ModPath, ModuleKind},
    Ctx, ExecCtx, Node, UserEvent,
};
use anyhow::{bail, Context, Result};
use compact_str::format_compact;

pub(crate) fn compile<C: Ctx, E: UserEvent>(
    ctx: &mut ExecCtx<C, E>,
    spec: Expr,
    scope: &ModPath,
    top_id: ExprId,
) -> Result<Node<C, E>> {
    match &spec {
        Expr { kind: ExprKind::Constant(v), id: _, pos: _ } => {
            Constant::compile(spec.clone(), v)
        }
        Expr { kind: ExprKind::Do { exprs }, id, pos: _ } => {
            let scope = ModPath(scope.append(&format_compact!("do{}", id.inner())));
            Block::compile(ctx, spec.clone(), &scope, top_id, exprs)
        }
        Expr { kind: ExprKind::Array { args }, id: _, pos: _ } => {
            Array::compile(ctx, spec.clone(), scope, top_id, args)
        }
        Expr { kind: ExprKind::ArrayRef { source, i }, id: _, pos: _ } => {
            ArrayRef::compile(ctx, spec.clone(), scope, top_id, source, i)
        }
        Expr { kind: ExprKind::ArraySlice { source, start, end }, id: _, pos: _ } => {
            ArraySlice::compile(ctx, spec.clone(), scope, top_id, source, start, end)
        }
        Expr { kind: ExprKind::StringInterpolate { args }, id: _, pos: _ } => {
            StringInterpolate::compile(ctx, spec.clone(), scope, top_id, args)
        }
        Expr { kind: ExprKind::Tuple { args }, id: _, pos: _ } => {
            Tuple::compile(ctx, spec.clone(), scope, top_id, args)
        }
        Expr { kind: ExprKind::Variant { tag, args }, id: _, pos: _ } => {
            Variant::compile(ctx, spec.clone(), scope, top_id, tag, args)
        }
        Expr { kind: ExprKind::Struct { args }, id: _, pos: _ } => {
            Struct::compile(ctx, spec.clone(), scope, top_id, args)
        }
        Expr { kind: ExprKind::Module { name, export: _, value }, id: _, pos } => {
            let scope = ModPath(scope.append(&name));
            match value {
                ModuleKind::Unresolved => {
                    bail!("at {} you must resolve external modules", pos)
                }
                ModuleKind::Resolved(ori) => {
                    let res =
                        Block::compile(ctx, spec.clone(), &scope, top_id, &ori.exprs)
                            .with_context(|| ori.clone())?;
                    ctx.env.modules.insert_cow(scope.clone());
                    Ok(res)
                }
                ModuleKind::Inline(exprs) => {
                    let res = Block::compile(ctx, spec.clone(), &scope, top_id, exprs)?;
                    ctx.env.modules.insert_cow(scope.clone());
                    Ok(res)
                }
            }
        }
        Expr { kind: ExprKind::Use { name }, id: _, pos } => {
            Use::compile(ctx, spec.clone(), scope, name, pos)
        }
        Expr { kind: ExprKind::Connect { name, value }, id: _, pos } => {
            Connect::compile(ctx, spec.clone(), scope, top_id, name, value, pos)
        }
        Expr { kind: ExprKind::Lambda(l), id: _, pos: _ } => {
            Lambda::compile(ctx, spec.clone(), scope, l)
        }
        Expr { kind: ExprKind::Any { args }, id: _, pos: _ } => {
            Any::compile(ctx, spec.clone(), scope, top_id, args)
        }
        Expr { kind: ExprKind::Apply { args, function: f }, id: _, pos } => {
            CallSite::compile(ctx, spec.clone(), scope, top_id, args, f, pos)
        }
        Expr { kind: ExprKind::Bind(b), id: _, pos } => {
            Bind::compile(ctx, spec.clone(), scope, top_id, b, pos)
        }
        Expr { kind: ExprKind::Qop(e), id: _, pos } => {
            Qop::compile(ctx, spec.clone(), scope, top_id, e, pos)
        }
        Expr { kind: ExprKind::ByRef(e), id: _, pos: _ } => {
            ByRef::compile(ctx, spec.clone(), scope, top_id, e)
        }
        Expr { kind: ExprKind::Deref(e), id: _, pos: _ } => {
            Deref::compile(ctx, spec.clone(), scope, top_id, e)
        }
        Expr { kind: ExprKind::Ref { name }, id: _, pos } => {
            Ref::compile(ctx, spec.clone(), scope, top_id, name, pos)
        }
        Expr { kind: ExprKind::TupleRef { source, field }, id: _, pos: _ } => {
            TupleRef::compile(ctx, spec.clone(), scope, top_id, source, field)
        }
        Expr { kind: ExprKind::StructRef { source, field }, id: _, pos: _ } => {
            StructRef::compile(ctx, spec.clone(), scope, top_id, source, field)
        }
        Expr { kind: ExprKind::StructWith { source, replace }, id: _, pos: _ } => {
            StructWith::compile(ctx, spec.clone(), scope, top_id, source, replace)
        }
        Expr { kind: ExprKind::Select { arg, arms }, id: _, pos } => {
            Select::compile(ctx, spec.clone(), scope, top_id, arg, arms, pos)
        }
        Expr { kind: ExprKind::TypeCast { expr, typ }, id: _, pos } => {
            TypeCast::compile(ctx, spec.clone(), scope, top_id, expr, typ, pos)
        }
        Expr { kind: ExprKind::TypeDef { name, params, typ }, id: _, pos } => {
            TypeDef::compile(ctx, spec.clone(), scope, name, params, typ, pos)
        }
        Expr { kind: ExprKind::Not { expr }, id: _, pos: _ } => {
            Not::compile(ctx, spec.clone(), scope, top_id, expr)
        }
        Expr { kind: ExprKind::Eq { lhs, rhs }, id: _, pos: _ } => {
            Eq::compile(ctx, spec.clone(), scope, top_id, lhs, rhs)
        }
        Expr { kind: ExprKind::Ne { lhs, rhs }, id: _, pos: _ } => {
            Ne::compile(ctx, spec.clone(), scope, top_id, lhs, rhs)
        }
        Expr { kind: ExprKind::Lt { lhs, rhs }, id: _, pos: _ } => {
            Lt::compile(ctx, spec.clone(), scope, top_id, lhs, rhs)
        }
        Expr { kind: ExprKind::Gt { lhs, rhs }, id: _, pos: _ } => {
            Gt::compile(ctx, spec.clone(), scope, top_id, lhs, rhs)
        }
        Expr { kind: ExprKind::Lte { lhs, rhs }, id: _, pos: _ } => {
            Lte::compile(ctx, spec.clone(), scope, top_id, lhs, rhs)
        }
        Expr { kind: ExprKind::Gte { lhs, rhs }, id: _, pos: _ } => {
            Gte::compile(ctx, spec.clone(), scope, top_id, lhs, rhs)
        }
        Expr { kind: ExprKind::And { lhs, rhs }, id: _, pos: _ } => {
            And::compile(ctx, spec.clone(), scope, top_id, lhs, rhs)
        }
        Expr { kind: ExprKind::Or { lhs, rhs }, id: _, pos: _ } => {
            Or::compile(ctx, spec.clone(), scope, top_id, lhs, rhs)
        }
        Expr { kind: ExprKind::Add { lhs, rhs }, id: _, pos: _ } => {
            Add::compile(ctx, spec.clone(), scope, top_id, lhs, rhs)
        }
        Expr { kind: ExprKind::Sub { lhs, rhs }, id: _, pos: _ } => {
            Sub::compile(ctx, spec.clone(), scope, top_id, lhs, rhs)
        }
        Expr { kind: ExprKind::Mul { lhs, rhs }, id: _, pos: _ } => {
            Mul::compile(ctx, spec.clone(), scope, top_id, lhs, rhs)
        }
        Expr { kind: ExprKind::Div { lhs, rhs }, id: _, pos: _ } => {
            Div::compile(ctx, spec.clone(), scope, top_id, lhs, rhs)
        }
    }
}