Struct Function

Source
pub struct Function<'a> {
    pub linkage: Linkage,
    pub name: String,
    pub arguments: Vec<(Type<'a>, Value)>,
    pub return_ty: Option<Type<'a>>,
    pub blocks: Vec<Block<'a>>,
}
Expand description

A QBE function definition.

A function consists of a name, linkage information, arguments, return type, and a collection of blocks containing the function’s implementation.

§Examples

use qbe::{Function, Linkage, Type, Value, Instr, Cmp};

// Create a function that checks if a number is even
let mut is_even = Function::new(
    Linkage::public(),
    "is_even",
    vec![(Type::Word, Value::Temporary("n".to_string()))],
    Some(Type::Word), // Returns 1 if even, 0 if odd
);

// Add the start block
let mut start = is_even.add_block("start");

// Calculate n % 2 (by using n & 1)
start.assign_instr(
    Value::Temporary("remainder".to_string()),
    Type::Word,
    Instr::And(
        Value::Temporary("n".to_string()),
        Value::Const(1),
    ),
);

// Check if remainder is 0 (even number)
start.assign_instr(
    Value::Temporary("is_zero".to_string()),
    Type::Word,
    Instr::Cmp(
        Type::Word,
        Cmp::Eq,
        Value::Temporary("remainder".to_string()),
        Value::Const(0),
    ),
);

// Return the result
start.add_instr(Instr::Ret(Some(Value::Temporary("is_zero".to_string()))));

Fields§

§linkage: Linkage

Function’s linkage

§name: String

Function name

§arguments: Vec<(Type<'a>, Value)>

Function arguments

§return_ty: Option<Type<'a>>

Return type

§blocks: Vec<Block<'a>>

Labelled blocks

Implementations§

Source§

impl<'a> Function<'a>

Source

pub fn new( linkage: Linkage, name: impl Into<String>, arguments: Vec<(Type<'a>, Value)>, return_ty: Option<Type<'a>>, ) -> Self

Instantiates an empty function and returns it

Examples found in repository?
examples/hello_world.rs (lines 6-14)
5fn generate_add_func(module: &mut Module) {
6    let mut func = Function::new(
7        Linkage::private(),
8        "add",
9        vec![
10            (Type::Word, Value::Temporary("a".into())),
11            (Type::Word, Value::Temporary("b".into())),
12        ],
13        Some(Type::Word),
14    );
15
16    func.add_block("start");
17    func.assign_instr(
18        Value::Temporary("c".into()),
19        Type::Word,
20        Instr::Add(Value::Temporary("a".into()), Value::Temporary("b".into())),
21    );
22    func.add_instr(Instr::Ret(Some(Value::Temporary("c".into()))));
23
24    module.add_function(func);
25}
26
27fn generate_main_func(module: &mut Module) {
28    let mut func = Function::new(Linkage::public(), "main", Vec::new(), Some(Type::Word));
29
30    func.add_block("start");
31    func.assign_instr(
32        Value::Temporary("r".into()),
33        Type::Word,
34        Instr::Call(
35            "add".into(),
36            vec![(Type::Word, Value::Const(1)), (Type::Word, Value::Const(1))],
37            None,
38        ),
39    );
40    func.add_instr(Instr::Call(
41        "printf".into(),
42        vec![
43            (Type::Long, Value::Global("fmt".into())),
44            (Type::Word, Value::Temporary("r".into())),
45        ],
46        Some(1),
47    ));
48    func.add_instr(Instr::Ret(Some(Value::Const(0))));
49
50    module.add_function(func);
51}
Source

pub fn add_block(&mut self, label: impl Into<String>) -> &mut Block<'a>

Adds a new empty block with a specified label and returns a reference to it

Examples found in repository?
examples/hello_world.rs (line 16)
5fn generate_add_func(module: &mut Module) {
6    let mut func = Function::new(
7        Linkage::private(),
8        "add",
9        vec![
10            (Type::Word, Value::Temporary("a".into())),
11            (Type::Word, Value::Temporary("b".into())),
12        ],
13        Some(Type::Word),
14    );
15
16    func.add_block("start");
17    func.assign_instr(
18        Value::Temporary("c".into()),
19        Type::Word,
20        Instr::Add(Value::Temporary("a".into()), Value::Temporary("b".into())),
21    );
22    func.add_instr(Instr::Ret(Some(Value::Temporary("c".into()))));
23
24    module.add_function(func);
25}
26
27fn generate_main_func(module: &mut Module) {
28    let mut func = Function::new(Linkage::public(), "main", Vec::new(), Some(Type::Word));
29
30    func.add_block("start");
31    func.assign_instr(
32        Value::Temporary("r".into()),
33        Type::Word,
34        Instr::Call(
35            "add".into(),
36            vec![(Type::Word, Value::Const(1)), (Type::Word, Value::Const(1))],
37            None,
38        ),
39    );
40    func.add_instr(Instr::Call(
41        "printf".into(),
42        vec![
43            (Type::Long, Value::Global("fmt".into())),
44            (Type::Word, Value::Temporary("r".into())),
45        ],
46        Some(1),
47    ));
48    func.add_instr(Instr::Ret(Some(Value::Const(0))));
49
50    module.add_function(func);
51}
Source

pub fn last_block(&mut self) -> &Block<'_>

👎Deprecated since 3.0.0: Use self.blocks.last() or self.blocks.last_mut() instead.

Returns a reference to the last block

Source

pub fn add_instr(&mut self, instr: Instr<'a>)

Adds a new instruction to the last block

Examples found in repository?
examples/hello_world.rs (line 22)
5fn generate_add_func(module: &mut Module) {
6    let mut func = Function::new(
7        Linkage::private(),
8        "add",
9        vec![
10            (Type::Word, Value::Temporary("a".into())),
11            (Type::Word, Value::Temporary("b".into())),
12        ],
13        Some(Type::Word),
14    );
15
16    func.add_block("start");
17    func.assign_instr(
18        Value::Temporary("c".into()),
19        Type::Word,
20        Instr::Add(Value::Temporary("a".into()), Value::Temporary("b".into())),
21    );
22    func.add_instr(Instr::Ret(Some(Value::Temporary("c".into()))));
23
24    module.add_function(func);
25}
26
27fn generate_main_func(module: &mut Module) {
28    let mut func = Function::new(Linkage::public(), "main", Vec::new(), Some(Type::Word));
29
30    func.add_block("start");
31    func.assign_instr(
32        Value::Temporary("r".into()),
33        Type::Word,
34        Instr::Call(
35            "add".into(),
36            vec![(Type::Word, Value::Const(1)), (Type::Word, Value::Const(1))],
37            None,
38        ),
39    );
40    func.add_instr(Instr::Call(
41        "printf".into(),
42        vec![
43            (Type::Long, Value::Global("fmt".into())),
44            (Type::Word, Value::Temporary("r".into())),
45        ],
46        Some(1),
47    ));
48    func.add_instr(Instr::Ret(Some(Value::Const(0))));
49
50    module.add_function(func);
51}
Source

pub fn assign_instr(&mut self, temp: Value, ty: Type<'a>, instr: Instr<'a>)

Adds a new instruction assigned to a temporary

Examples found in repository?
examples/hello_world.rs (lines 17-21)
5fn generate_add_func(module: &mut Module) {
6    let mut func = Function::new(
7        Linkage::private(),
8        "add",
9        vec![
10            (Type::Word, Value::Temporary("a".into())),
11            (Type::Word, Value::Temporary("b".into())),
12        ],
13        Some(Type::Word),
14    );
15
16    func.add_block("start");
17    func.assign_instr(
18        Value::Temporary("c".into()),
19        Type::Word,
20        Instr::Add(Value::Temporary("a".into()), Value::Temporary("b".into())),
21    );
22    func.add_instr(Instr::Ret(Some(Value::Temporary("c".into()))));
23
24    module.add_function(func);
25}
26
27fn generate_main_func(module: &mut Module) {
28    let mut func = Function::new(Linkage::public(), "main", Vec::new(), Some(Type::Word));
29
30    func.add_block("start");
31    func.assign_instr(
32        Value::Temporary("r".into()),
33        Type::Word,
34        Instr::Call(
35            "add".into(),
36            vec![(Type::Word, Value::Const(1)), (Type::Word, Value::Const(1))],
37            None,
38        ),
39    );
40    func.add_instr(Instr::Call(
41        "printf".into(),
42        vec![
43            (Type::Long, Value::Global("fmt".into())),
44            (Type::Word, Value::Temporary("r".into())),
45        ],
46        Some(1),
47    ));
48    func.add_instr(Instr::Ret(Some(Value::Const(0))));
49
50    module.add_function(func);
51}

Trait Implementations§

Source§

impl<'a> Clone for Function<'a>

Source§

fn clone(&self) -> Function<'a>

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'a> Debug for Function<'a>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'a> Default for Function<'a>

Source§

fn default() -> Function<'a>

Returns the “default value” for a type. Read more
Source§

impl Display for Function<'_>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'a> Hash for Function<'a>

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl<'a> Ord for Function<'a>

Source§

fn cmp(&self, other: &Function<'a>) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · Source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · Source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · Source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
Source§

impl<'a> PartialEq for Function<'a>

Source§

fn eq(&self, other: &Function<'a>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<'a> PartialOrd for Function<'a>

Source§

fn partial_cmp(&self, other: &Function<'a>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl<'a> Eq for Function<'a>

Source§

impl<'a> StructuralPartialEq for Function<'a>

Auto Trait Implementations§

§

impl<'a> Freeze for Function<'a>

§

impl<'a> RefUnwindSafe for Function<'a>

§

impl<'a> Send for Function<'a>

§

impl<'a> Sync for Function<'a>

§

impl<'a> Unpin for Function<'a>

§

impl<'a> UnwindSafe for Function<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.