Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Lower collections extension #1720

Merged
merged 11 commits into from
Nov 27, 2024
10 changes: 10 additions & 0 deletions hugr-core/src/std_extensions/collections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,16 @@ impl ListValue {
pub fn custom_type(&self) -> CustomType {
list_custom_type(self.1.clone())
}

/// Returns the type of values inside the `[ListValue]`.
pub fn get_element_type(&self) -> &Type {
&self.1
}

/// Returns the values contained inside the `[ListValue]`.
pub fn get_contents(&self) -> &[Value] {
&self.0
}
}

impl TryHash for ListValue {
Expand Down
36 changes: 35 additions & 1 deletion hugr-llvm/src/emit/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::{collections::HashMap, rc::Rc};

use anyhow::{anyhow, Result};
use hugr_core::{
extension::prelude::{either_type, option_type},
ops::{constant::CustomConst, ExtensionOp, FuncDecl, FuncDefn},
types::Type,
HugrView, NodeIndex, PortIndex, Wire,
Expand All @@ -12,7 +13,7 @@ use inkwell::{
context::Context,
module::Module,
types::{BasicType, BasicTypeEnum, FunctionType},
values::{BasicValueEnum, FunctionValue, GlobalValue},
values::{BasicValueEnum, FunctionValue, GlobalValue, IntValue},
};
use itertools::zip_eq;

Expand Down Expand Up @@ -314,3 +315,36 @@ impl<'c, 'a, H: HugrView> EmitFuncContext<'c, 'a, H> {
Ok((self.emit_context, self.todo))
}
}

/// Builds an optional value wrapping `some_value` conditioned on the provided `is_some` flag.
pub fn build_option<'c, H: HugrView>(
ctx: &mut EmitFuncContext<'c, '_, H>,
is_some: IntValue<'c>,
some_value: BasicValueEnum<'c>,
hugr_ty: HugrType,
) -> Result<BasicValueEnum<'c>> {
let option_ty = ctx.llvm_sum_type(option_type(hugr_ty))?;
let builder = ctx.builder();
let some = option_ty.build_tag(builder, 1, vec![some_value])?;
let none = option_ty.build_tag(builder, 0, vec![])?;
let option = builder.build_select(is_some, some, none, "")?;
Ok(option)
}

/// Builds a result value wrapping either `ok_value` or `else_value` depending on the provided
/// `is_ok` flag.
pub fn build_ok_or_else<'c, H: HugrView>(
ctx: &mut EmitFuncContext<'c, '_, H>,
is_ok: IntValue<'c>,
ok_value: BasicValueEnum<'c>,
ok_hugr_ty: HugrType,
else_value: BasicValueEnum<'c>,
else_hugr_ty: HugrType,
) -> Result<BasicValueEnum<'c>> {
let either_ty = ctx.llvm_sum_type(either_type(else_hugr_ty, ok_hugr_ty))?;
let builder = ctx.builder();
let left = either_ty.build_tag(builder, 0, vec![else_value])?;
let right = either_ty.build_tag(builder, 1, vec![ok_value])?;
let either = builder.build_select(is_ok, right, left, "")?;
Ok(either)
}
3 changes: 2 additions & 1 deletion hugr-llvm/src/emit/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use hugr_core::ops::handle::FuncID;
use hugr_core::std_extensions::arithmetic::{
conversions, float_ops, float_types, int_ops, int_types,
};
use hugr_core::std_extensions::logic;
use hugr_core::std_extensions::{collections, logic};
use hugr_core::types::TypeRow;
use hugr_core::{Hugr, HugrView};
use inkwell::module::Module;
Expand Down Expand Up @@ -153,6 +153,7 @@ impl SimpleHugrConfig {
float_ops::EXTENSION_ID,
conversions::EXTENSION_ID,
logic::EXTENSION_ID,
collections::EXTENSION_ID,
]),
),
)
Expand Down
1 change: 1 addition & 0 deletions hugr-llvm/src/extension.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod collections;
pub mod conversions;
pub mod float;
pub mod int;
Expand Down
Loading
Loading