Enum AstType
pub enum AstType {
Show 19 variants
Void,
Bool,
Char,
SignedChar,
Short,
Int,
Long,
LongLong,
UnsignedChar,
UnsignedShort,
UnsignedInt,
UnsignedLong,
UnsignedLongLong,
Float,
Double,
LongDouble,
Pointer(Box<AstType>),
Array {
element_type: Box<AstType>,
count: usize,
},
Function {
return_type: Box<AstType>,
params: Vec<AstType>,
},
}Expand description
The canonical type of an expression.
The semantic analysis stage annotates every expression in the parsed AST with its AstType.
Variants§
Void
Bool
Char
SignedChar
Short
Int
Long
LongLong
UnsignedChar
UnsignedShort
UnsignedInt
UnsignedLong
UnsignedLongLong
Float
Double
LongDouble
Pointer(Box<AstType>)
Array
Function
Implementations§
§impl AstType
impl AstType
pub fn new_pointer_to(ty: AstType) -> Self
pub fn new_pointer_to(ty: AstType) -> Self
Creates a new pointer type to the given AstType.
pub fn __ptrdiff_t() -> Self
pub fn __ptrdiff_t() -> Self
A signed integer type that can hold the value of subtracting one pointer from another.
The underlying type for ptrdiff_t.
pub fn __size_t() -> Self
pub fn __size_t() -> Self
An unsigned integer type used to represent the size of objects in bytes.
The underlying type for size_t.
pub fn is_basic_type(&self) -> bool
pub fn is_basic_type(&self) -> bool
Is this type a ‘basic type’?
The term ‘basic type’ is not used in the C Standard, but it is used informally when discussing C parsers. The basic type is the first type we see in a declaration before any of the declarators.
long double salary = 0.0;
~~~~~~~~~~~
unsigned long int *age = 0, data[4], calculate(float salary);
~~~~~~~~~~~~~~~~~This function returns true if the AstType is not a pointer, array or function type.
pub fn is_complete(&self) -> bool
pub fn is_complete(&self) -> bool
Is the type a ‘complete’ type, meaning the compiler knows its size and layout?
pub fn is_aggregate(&self) -> bool
pub fn is_aggregate(&self) -> bool
Is this type an aggregate type?
pub fn is_pointer(&self) -> bool
pub fn is_pointer(&self) -> bool
Is this type a pointer type?
pub fn is_pointer_to_void(&self) -> bool
pub fn is_pointer_to_void(&self) -> bool
Is this type a pointer-to-void (void *) type?
pub fn is_pointer_to_complete(&self) -> bool
pub fn is_pointer_to_complete(&self) -> bool
Is this type a pointer to a complete type?
pub fn is_character_array(&self) -> bool
pub fn is_character_array(&self) -> bool
Is this type an array of a character type?
pub fn is_function_pointer(&self) -> bool
pub fn is_function_pointer(&self) -> bool
Is this type a function pointer type?
A function pointer is a pointer whose referent is a function. In other words, there is only one level of indirection from the function.
In C, a function pointer can be called without needing to dereference it first.
int get(void);
int (*a)(void) = get; // `a` is a function pointer.
int (**b)(void) = &a; // `b` is _NOT_ a function pointer; it points to the object `a`.
int v1 = a(); // Can call `a` without dereferencing.
int v2 = (*a)(); // Or can explicitly dereference.pub fn is_function(&self) -> bool
pub fn is_function(&self) -> bool
Is this type a function type? (Not a function pointer.)
pub fn is_arithmetic(&self) -> bool
pub fn is_arithmetic(&self) -> bool
Is this type an arithmetic type (integer, boolean, or floating-point)?
pub fn is_integer(&self) -> bool
pub fn is_integer(&self) -> bool
Is this type an integral type? (Includes _Bool.)
pub fn is_floating_point(&self) -> bool
pub fn is_floating_point(&self) -> bool
Is this type a floating-point type?
pub fn is_character(&self) -> bool
pub fn is_character(&self) -> bool
Is this type a character type? (Does not include _Bool.)
pub fn get_innermost_scalar_type(&self) -> &AstType
pub fn get_innermost_scalar_type(&self) -> &AstType
Gets the type’s inner-most scalar type.
For an aggregate type, recurses into the type until a scalar type is found.
AstType::AstType { AstType::AstType { AstType::Char } } —> AstType::Char
pub fn is_signed_integer(&self) -> bool
pub fn is_signed_integer(&self) -> bool
Is this type a signed integer?
pub fn is_unsigned_integer(&self) -> bool
pub fn is_unsigned_integer(&self) -> bool
Is this type an unsigned integer? (Includes _Bool.)
pub fn same_signedness(&self, other: &AstType) -> bool
pub fn same_signedness(&self, other: &AstType) -> bool
Does this type have the same signedness as the other type?
pub fn to_unsigned(self) -> Self
pub fn to_unsigned(self) -> Self
Makes an unsigned integer version of the current integer type.
Precondition: self.is_integer() == true
pub fn valid_range_as_str(&self) -> Option<&'static str>
pub fn valid_range_as_str(&self) -> Option<&'static str>
Returns the type’s valid range of values as a string slice, if the type has one. Otherwise returns None.
§Examples
assert_eq!(Some("[0, 255]"), AstType::UnsignedChar.valid_range_as_str());
assert_eq!(Some("[-2147483648, 2147483647]"), AstType::Int.valid_range_as_str());
assert_eq!(Some("+/- 3.4028235e38"), AstType::Float.valid_range_as_str());pub fn get_common_type(a: &AstType, b: &AstType) -> Self
pub fn get_common_type(a: &AstType, b: &AstType) -> Self
Gets the common AstType for the given two types.
This does not perform any integer promotions, e.g. the common type for AstType::Short and AstType::Char
is AstType::Short.
pub fn fits_inside(&self, other: &AstType) -> bool
pub fn fits_inside(&self, other: &AstType) -> bool
Can all the values of this type fit inside the given other type?
§Examples
assert_eq!(false, AstType::Int.fits_inside(&AstType::UnsignedInt));
assert_eq!(false, AstType::Int.fits_inside(&AstType::Short));
assert_eq!(true, AstType::Int.fits_inside(&AstType::Int));
assert_eq!(true, AstType::Int.fits_inside(&AstType::Long));
assert_eq!(false, AstType::UnsignedInt.fits_inside(&AstType::Int));
assert_eq!(true, AstType::UnsignedInt.fits_inside(&AstType::Long));
assert_eq!(true, AstType::Float.fits_inside(&AstType::Double));
assert_eq!(true, AstType::Double.fits_inside(&AstType::LongDouble));pub fn can_hold_value(&self, value: u64) -> bool
pub fn can_hold_value(&self, value: u64) -> bool
Can the given u64 value fit inside the range of values supported by the current type?
§Examples
assert_eq!(true, AstType::Short.can_hold_value(30_000_u64));
assert_eq!(false, AstType::Short.can_hold_value(100_000_u64));pub fn promote_if_rank_lower_than_int(self) -> (Self, bool)
pub fn promote_if_rank_lower_than_int(self) -> (Self, bool)
Promotes a small integer type (‘_Bool’, ‘char’, or ‘short’) to AstType::Int.
If the type is an integral type with a rank lower than ‘int’ then the type is consumed and replaced with
AstType::Int. Otherwise, the existing type is returned unchanged.
Returns a tuple of the type and a boolean value indicating whether or not it was promoted.
The C standard specifies that smaller integer types should be promoted to ‘unsigned int’ if their values cannot fit inside ‘int’, but in all mainstream implementations (including this one) all smaller integer types, both signed and unsigned, can fit into ‘int’.
pub fn integer_rank(&self) -> usize
pub fn integer_rank(&self) -> usize
The rank of the integer type. Types that fit larger values have a higher rank.