Skip to main content

graphix_compiler/node/
genn.rs

1use super::{
2    bind::Ref,
3    callsite::{Arg, ArgKey, CallSite},
4    Constant, Nop, NOP,
5};
6use crate::{
7    expr::{ExprId, ModPath},
8    typ::{FnType, Type},
9    BindId, ExecCtx, Node, Rt, Scope, UserEvent,
10};
11use enumflags2::BitFlags;
12use fxhash::FxHashMap;
13use netidx::publisher::{Typ, Value};
14use poolshark::local::LPooled;
15
16/// generate a no op with the specific type
17pub fn nop<R: Rt, E: UserEvent>(typ: Type) -> Node<R, E> {
18    Nop::new(typ)
19}
20
21/// bind a variable and return a node referencing it
22pub fn bind<R: Rt, E: UserEvent>(
23    ctx: &mut ExecCtx<R, E>,
24    scope: &ModPath,
25    name: &str,
26    typ: Type,
27    top_id: ExprId,
28) -> (BindId, Node<R, E>) {
29    let id = ctx.env.bind_variable(scope, name, typ.clone()).id;
30    ctx.rt.ref_var(id, top_id);
31    (id, Box::new(Ref { spec: NOP.clone(), typ, id, top_id }))
32}
33
34/// generate a reference to a bind id
35pub fn reference<R: Rt, E: UserEvent>(
36    ctx: &mut ExecCtx<R, E>,
37    id: BindId,
38    typ: Type,
39    top_id: ExprId,
40) -> Node<R, E> {
41    ctx.rt.ref_var(id, top_id);
42    Box::new(Ref { spec: NOP.clone(), typ, id, top_id })
43}
44
45pub fn constant<R: Rt, E: UserEvent>(v: Value) -> Node<R, E> {
46    Box::new(Constant {
47        spec: NOP.clone(),
48        typ: Type::Primitive(Typ::get(&v).into()),
49        value: v,
50    })
51}
52
53/// generate and return an apply node for the given lambda
54pub fn apply<R: Rt, E: UserEvent>(
55    fnode: Node<R, E>,
56    scope: Scope,
57    args: Vec<Node<R, E>>,
58    typ: &FnType,
59    top_id: ExprId,
60) -> Node<R, E> {
61    let ftype = typ.reset_tvars();
62    ftype.alias_tvars(&mut LPooled::take());
63    let args: FxHashMap<ArgKey, Arg<R, E>> = args
64        .into_iter()
65        .enumerate()
66        .map(|(i, node)| {
67            (
68                ArgKey::Positional(i),
69                Arg { id: BindId::new(), node: Some(node), is_default: false },
70            )
71        })
72        .collect();
73    Box::new(CallSite {
74        spec: NOP.clone(),
75        rtype: ftype.rtype.clone(),
76        ftype: Some(ftype),
77        resolved_ftype: None,
78        args,
79        arg_refs: Vec::new(),
80        scope,
81        flags: BitFlags::empty(),
82        fnode,
83        function: None,
84        top_id,
85    })
86}