eyg/ir/tree

Types

pub type DependencyError(t) {
  InvalidPath(String)
  BadReference(t)
  ReferenceCycle(List(String))
}

Constructors

  • InvalidPath(String)
  • BadReference(t)
  • ReferenceCycle(List(String))

The entire structure of an EYG program is specified in the following expression nodes.

pub type Expression(m) {
  Variable(label: String)
  Lambda(label: String, body: #(Expression(m), m))
  Apply(func: #(Expression(m), m), argument: #(Expression(m), m))
  Let(
    label: String,
    definition: #(Expression(m), m),
    body: #(Expression(m), m),
  )
  Binary(value: BitArray)
  Integer(value: Int)
  String(value: String)
  Tail
  Cons
  Vacant
  Empty
  Extend(label: String)
  Select(label: String)
  Overwrite(label: String)
  Tag(label: String)
  Case(label: String)
  NoCases
  Perform(label: String)
  Handle(label: String)
  Builtin(identifier: String)
  Reference(reference: Reference)
}

Constructors

  • Variable(label: String)
  • Lambda(label: String, body: #(Expression(m), m))
  • Apply(func: #(Expression(m), m), argument: #(Expression(m), m))
  • Let(
      label: String,
      definition: #(Expression(m), m),
      body: #(Expression(m), m),
    )
  • Binary(value: BitArray)
  • Integer(value: Int)
  • String(value: String)
  • Tail
  • Cons
  • Vacant
  • Empty
  • Extend(label: String)
  • Select(label: String)
  • Overwrite(label: String)
  • Tag(label: String)
  • Case(label: String)
  • NoCases
  • Perform(label: String)
  • Handle(label: String)
  • Builtin(identifier: String)
  • Reference(reference: Reference)

A node consists of an expression and associated metadata

pub type Node(m) =
  #(Expression(m), m)

A reference to another eyg module.

Content and Pinned are verifyable against a given module, any shared/or published module can only use these references. Version is fixed, the EYG hub does not accept republishing modules. Package refers only to a package by name. In most instances this will resolve to the latest release in a local cache. Relative is specific to the workspace running the program. This is often the filesystem but can be other things i.e. the location can be cells in a spreadsheet using EYG for scripting.

pub type Reference {
  Content(cid: v1.Cid)
  Package(package: String)
  Version(package: String, version: Int)
  Pinned(release: Release)
  Relative(location: String)
}

Constructors

  • Content(cid: v1.Cid)
  • Package(package: String)
  • Version(package: String, version: Int)
  • Pinned(release: Release)
  • Relative(location: String)

The identifier of a fully qualified release.

pub type Release {
  Release(package: String, version: Int, module: v1.Cid)
}

Constructors

  • Release(package: String, version: Int, module: v1.Cid)

Values

pub fn add(
  a: #(Expression(Nil), Nil),
  b: #(Expression(Nil), Nil),
) -> #(Expression(Nil), Nil)
pub fn apply(
  func: #(Expression(m), m),
  argument: #(Expression(m), m),
) -> #(Expression(m), Nil)
pub fn binary(value: BitArray) -> #(Expression(m), Nil)
pub fn block(
  assignments: List(#(String, #(Expression(Nil), Nil))),
  then: #(Expression(Nil), Nil),
) -> #(Expression(Nil), Nil)
pub fn builtin(identifier: String) -> #(Expression(m), Nil)
pub fn call(
  f: #(Expression(Nil), Nil),
  args: List(#(Expression(Nil), Nil)),
) -> #(Expression(Nil), Nil)
pub fn case_(label: String) -> #(Expression(m), Nil)
pub fn children(
  node: #(Expression(a), a),
) -> List(#(Expression(a), a))

Return the children of the given node in canonical order.

pub fn clear_annotation(
  source: #(Expression(a), a),
) -> #(Expression(Nil), Nil)
pub fn cons() -> #(Expression(m), Nil)
pub fn do_gather_snippets(
  node: #(Expression(m), m),
  comments: List(String),
  assigns: List(#(String, #(Expression(m), m), m)),
  acc: List(
    #(List(String), List(#(String, #(Expression(m), m), m))),
  ),
) -> List(
  #(List(String), List(#(String, #(Expression(m), m), m))),
)
pub fn do_list(
  reversed: List(#(Expression(Nil), Nil)),
  acc: #(Expression(Nil), Nil),
) -> #(Expression(Nil), Nil)
pub fn do_record(
  reversed: List(#(String, #(Expression(Nil), Nil))),
  acc: #(Expression(Nil), Nil),
) -> #(Expression(Nil), Nil)
pub fn empty() -> #(Expression(m), Nil)
pub fn extend(label: String) -> #(Expression(m), Nil)
pub fn false() -> #(Expression(Nil), Nil)
pub fn fold(
  node: #(Expression(a), a),
  acc: b,
  f: fn(b, #(Expression(a), a)) -> fn(fn(b) -> t) -> t,
) -> fn(fn(b) -> t) -> t

Visit each node in a pre-order depth-first traversal and accumulate a value

pub fn fold_post_order(
  node: #(Expression(a), a),
  acc: b,
  f: fn(b, #(Expression(a), a)) -> fn(fn(b) -> t) -> t,
) -> fn(fn(b) -> t) -> t

Visit each node in a post-order depth-first traversal and accumulate a value

pub fn free_variables(
  node: #(Expression(a), a),
  ignore: List(String),
) -> List(String)

The variables that are free in this expressions. Free variables need to be in an environment of the expression may crash.

pub fn from_block(
  assigns: List(#(String, #(Expression(m), m), m)),
  tail: #(Expression(m), m),
) -> #(Expression(m), m)
pub fn func(
  params: List(String),
  body: #(Expression(Nil), Nil),
) -> #(Expression(Nil), Nil)
pub fn gather_snippets(
  source: #(Expression(m), m),
) -> List(
  #(List(String), List(#(String, #(Expression(m), m), m))),
)
pub fn get(
  value: #(Expression(Nil), Nil),
  label: String,
) -> #(Expression(Nil), Nil)
pub fn get_annotation(node: #(Expression(a), a)) -> List(a)
pub fn handle(label: String) -> #(Expression(m), Nil)
pub fn integer(value: Int) -> #(Expression(m), Nil)
pub fn lambda(
  label: String,
  body: #(Expression(m), m),
) -> #(Expression(m), Nil)
pub fn let_(
  label: String,
  value: #(Expression(m), m),
  then: #(Expression(m), m),
) -> #(Expression(m), Nil)
pub fn list(
  items: List(#(Expression(Nil), Nil)),
) -> #(Expression(Nil), Nil)
pub fn list_builtins(node: #(Expression(a), a)) -> List(String)
pub fn list_references(
  node: #(Expression(a), a),
) -> List(Reference)
pub fn locate(
  source: #(Expression(a), a),
  root: String,
  resolve: fn(String) -> fn(
    fn(Result(#(Expression(a), a), s)) -> t,
  ) -> t,
  halt: fn(DependencyError(s)) -> fn(
    fn(
      #(List(#(String, #(Expression(a), a))), #(Expression(a), a)),
    ) -> t,
  ) -> t,
) -> fn(
  fn(#(List(#(String, #(Expression(a), a))), #(Expression(a), a))) -> t,
) -> t

Rewrite relative references to absolute paths and load their sources. Located sources are before their dependencies. The root directory must be absolute.

pub fn map_annotation(
  in: #(Expression(a), a),
  f: fn(a) -> b,
) -> #(Expression(b), b)
pub fn map_children(
  exp: Expression(a),
  f: fn(#(Expression(a), a)) -> fn(fn(#(Expression(b), b)) -> t) -> t,
) -> fn(fn(Expression(b)) -> t) -> t

Apply a function f to the children of an expression.

Note map_children works over expressions, not nodes. This allows the returned metadata type to be transformed by the f. The parent metadata is mapped explicitly when rebuilding Node(b)

pub fn map_children_with(
  exp: Expression(a),
  acc: c,
  f: fn(c, #(Expression(b), a)) -> fn(
    fn(#(c, #(Expression(b), b))) -> t,
  ) -> t,
) -> fn(fn(#(c, Expression(b))) -> t) -> t

Like map_children but with an accumulator value passed to f with each node in order.

pub fn match(
  value: #(Expression(Nil), Nil),
  matches: List(#(String, #(Expression(Nil), Nil))),
) -> #(Expression(Nil), Nil)
pub fn multiply(
  a: #(Expression(Nil), Nil),
  b: #(Expression(Nil), Nil),
) -> #(Expression(Nil), Nil)
pub fn nocases() -> #(Expression(m), Nil)
pub fn overwrite(label: String) -> #(Expression(m), Nil)
pub fn package(package: String) -> #(Expression(m), Nil)
pub fn perform(label: String) -> #(Expression(m), Nil)
pub fn pin(
  source: #(Expression(a), a),
  resolve: fn(String, option.Option(Int)) -> fn(fn(Release) -> t) -> t,
) -> fn(fn(#(List(#(a, Release)), #(Expression(a), a))) -> t) -> t

Replace package and version references with pinned references. Each transformed nodes metadata is returned.

pub fn record(
  fields: List(#(String, #(Expression(Nil), Nil))),
) -> #(Expression(Nil), Nil)
pub fn reference(identifier: v1.Cid) -> #(Expression(m), Nil)
pub fn relative(location: String) -> #(Expression(m), Nil)
pub fn release(
  package: String,
  version: Int,
  module: v1.Cid,
) -> #(Expression(m), Nil)
pub fn rewrite(
  node: #(Expression(a), a),
  f: fn(#(Expression(b), a)) -> fn(fn(#(Expression(b), b)) -> t) -> t,
) -> fn(fn(#(Expression(b), b)) -> t) -> t

Transform each node in a tree. The transformation function f sees any children as already rewritten.

pub fn rewrite_meta(
  node: #(Expression(a), a),
  f: fn(a) -> fn(fn(b) -> t) -> t,
) -> fn(fn(#(Expression(b), b)) -> t) -> t

Transform just the metadata in each node.

pub fn rewrite_with(
  node: #(Expression(a), a),
  with acc: c,
  using f: fn(c, #(Expression(b), a)) -> fn(
    fn(#(c, #(Expression(b), b))) -> t,
  ) -> t,
) -> fn(fn(#(c, #(Expression(b), b))) -> t) -> t

Transform each node in a tree while passing an accumlated value in post order. The transformation function f sees any children as already rewritten.

pub fn select(label: String) -> #(Expression(m), Nil)
pub fn string(value: String) -> #(Expression(m), Nil)
pub fn subtract(
  a: #(Expression(Nil), Nil),
  b: #(Expression(Nil), Nil),
) -> #(Expression(Nil), Nil)
pub fn tag(label: String) -> #(Expression(m), Nil)
pub fn tagged(
  label: String,
  inner: #(Expression(Nil), Nil),
) -> #(Expression(Nil), Nil)
pub fn tail() -> #(Expression(m), Nil)
pub fn true() -> #(Expression(Nil), Nil)
pub fn unit() -> #(Expression(m), Nil)
pub fn vacant() -> #(Expression(m), Nil)
pub fn variable(label: String) -> #(Expression(m), Nil)
pub fn version(
  package: String,
  version: Int,
) -> #(Expression(m), Nil)
Search Document