kasl-ir 0.3.5

An intermediate representation for the KASL language.
Documentation
//
//  Copyright 2026 Shuntaro Kasatani
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//

mod block_sort;

use crate::{Block, BlockData, IRType, Value, Variable};
use std::{
    collections::{BTreeMap, HashMap},
    fmt::Display,
};

#[derive(Default, Clone)]
pub struct Function {
    /// The blocks in the function.
    pub(crate) blocks: BTreeMap<Block, BlockData>,
    /// The entry block of the function.
    pub(crate) entry_block: Option<Block>,
    /// The map from value IDs to their types.
    pub(crate) values: HashMap<Value, IRType>,
    /// The map from variable IDs to their types.
    pub(crate) variables: HashMap<Variable, IRType>,
}

impl Function {
    /// Returns all blocks in the function.
    pub fn get_blocks(&self) -> Vec<Block> {
        self.blocks.keys().copied().collect()
    }

    /// Returns a reference to the block data.
    pub fn get_block(&self, block: &Block) -> Option<&BlockData> {
        self.blocks.get(block)
    }

    /// Returns a mutable reference to the block data.
    pub fn get_block_mut(&mut self, block: &Block) -> Option<&mut BlockData> {
        self.blocks.get_mut(block)
    }

    /// Returns the entry block of the function.
    pub fn entry_block(&self) -> Option<Block> {
        self.entry_block
    }

    /// Checks if the given value has the specified type.
    pub(crate) fn is_val_type(&self, val: Value, ty: IRType) -> bool {
        self.get_val_type(val) == ty
    }

    /// Returns the type of the given value.
    /// The caller must call this method with the value generated by this builder.
    pub fn get_val_type(&self, val: Value) -> IRType {
        self.values[&val]
    }

    /// Returns all variables in the function.
    pub fn get_vars(&self) -> Vec<Variable> {
        self.variables.keys().copied().collect()
    }

    /// Returns all values in the function.
    pub fn get_vals(&self) -> Vec<Value> {
        self.values.keys().copied().collect()
    }

    /// Returns the map of the types of all variables in the function.
    pub fn get_var_types(&self) -> &HashMap<Variable, IRType> {
        &self.variables
    }

    /// Returns the map of the types of all values in the function.
    pub fn get_val_types(&self) -> &HashMap<Value, IRType> {
        &self.values
    }

    /// Returns the type of the given variable.
    /// The caller must call this method with the variable generated by this builder.
    pub fn get_var_type(&self, var: Variable) -> IRType {
        self.variables[&var]
    }
}

impl Display for Function {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        for (block, data) in self.blocks.iter() {
            write!(f, "{}{}", block, data)?;
        }
        Ok(())
    }
}