-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This commit adds the `hieratika-mangler` crate, responsible for implementing the hieratika name mangling scheme in a centralized fashion. As it exists, the name mangling scheme implemented is _not final_, and is likely to change and evolve as the requirements are clarified. To that end, the mangling design docs have not been updated, as no coherent design process has yet taken place for the mangling scheme.
- Loading branch information
1 parent
525a2bb
commit 9cea036
Showing
10 changed files
with
408 additions
and
1 deletion.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
//! Errors in the mangling process. | ||
use thiserror::Error; | ||
|
||
use crate::backtrace::WithBacktrace; | ||
|
||
/// The result type for use in the mangler. | ||
pub type Result<T> = miette::Result<T, WithBacktrace<Error>>; | ||
|
||
/// This error type is for use during the process of compilation from LLVM IR to | ||
/// the Cairo IR. | ||
#[derive(Debug, Error)] | ||
pub enum Error { | ||
#[error("The input {_0} is not a valid mangle input")] | ||
InvalidInput(String), | ||
} | ||
|
||
impl Error { | ||
/// Constructs [`Error::InvalidInput`] while allowing conversion from a | ||
/// [`str`]. | ||
pub fn invalid_input(mangle_input: &str) -> Self { | ||
Self::InvalidInput(mangle_input.to_string()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
[package] | ||
name = "hieratika-mangler" | ||
version.workspace = true | ||
homepage.workspace = true | ||
repository.workspace = true | ||
license-file.workspace = true | ||
|
||
authors.workspace = true | ||
description = "A crate implementing the Hieratika internal mangling scheme." | ||
keywords.workspace = true | ||
categories.workspace = true | ||
|
||
edition.workspace = true | ||
rust-version.workspace = true | ||
|
||
[dependencies] | ||
hieratika-errors.workspace = true | ||
hieratika-flo.workspace = true | ||
|
||
[dev-dependencies] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Hieratika Mangler | ||
|
||
This crate is responsible for implementing the name mangling algorithm used by Hieratika. For more | ||
information, please see the [docs](../../docs/Name%20Mangling.md) on name mangling. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
//! This module contains constants that specify portions of the mangling | ||
//! behavior. | ||
/// A marker used to separate sections in the mangled string. | ||
pub const SECTION_SEPARATOR: &str = "$"; | ||
|
||
/// A marker used to signify the beginning of a snapshot mangle segment. | ||
pub const BEGIN_SNAPSHOT: &str = "m"; | ||
|
||
/// A marker used to signify the beginning of an array. | ||
pub const BEGIN_ARRAY: &str = "A"; | ||
|
||
/// A marker used to signify the beginning of a struct. | ||
pub const BEGIN_STRUCT: &str = "S"; | ||
|
||
/// A marker used to signify the end of a struct. | ||
pub const END_STRUCT: &str = "s"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
//! This crate implements Hieratika's name mangling scheme, providing a | ||
//! centralized place for the mangling functionality to live that can be | ||
//! accessed by all the other crates. | ||
//! | ||
//! See [`mangle`] for the primary interface to the crate and for usage | ||
//! examples. | ||
//! | ||
//! # Mangling Scheme | ||
//! | ||
//! The mangling scheme is designed to ensure a compact and unique | ||
//! representation for functions across different modules that may share name | ||
//! and/or type information. Please note that the current design of this | ||
//! mangling scheme is **not final** and is subject to change. | ||
#![warn(clippy::all, clippy::cargo, clippy::pedantic)] | ||
#![expect(clippy::multiple_crate_versions)] // Enforced by our dependencies | ||
|
||
pub mod constants; | ||
pub mod mapping; | ||
mod util; | ||
|
||
use hieratika_flo::types::Type; | ||
|
||
use crate::{ | ||
constants::SECTION_SEPARATOR, | ||
mapping::{mangle_params, mangle_returns}, | ||
}; | ||
|
||
/// The result type for the library. | ||
pub type Result<T> = hieratika_errors::mangle::Result<T>; | ||
|
||
/// The error type for the library. | ||
pub type Error = hieratika_errors::mangle::Error; | ||
|
||
/// Generates the mangled form of the provided `name`. | ||
/// | ||
/// A mangled name consists of the return types string, followed by the function | ||
/// name, followed by the params string, followed by the function's module, all | ||
/// separated using the [`SECTION_SEPARATOR`]. | ||
/// | ||
/// ``` | ||
/// use hieratika_flo::types::Type; | ||
/// use hieratika_mangler::{NameInfo, mangle}; | ||
/// | ||
/// let func_name = NameInfo::new( | ||
/// "my_func", | ||
/// "my_module", | ||
/// vec![Type::Double, Type::Bool], | ||
/// vec![Type::Float, Type::Bool], | ||
/// ); | ||
/// | ||
/// assert_eq!(mangle(func_name).unwrap(), "fc$my_func$dc$my_module"); | ||
/// ``` | ||
/// | ||
/// # Errors | ||
/// | ||
/// - [`Error::InvalidInput`] if any of the types in the input `name` cannot be | ||
/// mangled. | ||
pub fn mangle(name: NameInfo) -> Result<String> { | ||
let returns_string = mangle_returns(&name.return_types)?; | ||
let params_string = mangle_params(&name.parameter_types)?; | ||
let func_name = name.name; | ||
let func_module = name.module; | ||
Ok([returns_string, func_name, params_string, func_module].join(SECTION_SEPARATOR)) | ||
} | ||
|
||
/// The inputs to the name mangling process. | ||
#[derive(Clone, Debug, Eq, PartialEq)] | ||
pub struct NameInfo { | ||
/// The name of the symbol to be mangled. | ||
pub name: String, | ||
|
||
/// The name of the module in which the symbol was found. | ||
pub module: String, | ||
|
||
/// The types of the parameters to the function to be mangled. | ||
pub parameter_types: Vec<Type>, | ||
|
||
/// The types of the returns from the function to be mangled. | ||
pub return_types: Vec<Type>, | ||
} | ||
|
||
impl NameInfo { | ||
/// Creates a new [`NameInfo`] instance from the provided information. | ||
#[must_use] | ||
pub fn new( | ||
name: &str, | ||
module: &str, | ||
parameter_types: Vec<Type>, | ||
return_types: Vec<Type>, | ||
) -> Self { | ||
let name = name.into(); | ||
let module = module.into(); | ||
NameInfo { | ||
name, | ||
module, | ||
parameter_types, | ||
return_types, | ||
} | ||
} | ||
} |
Oops, something went wrong.