1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
//! Entities that the code generator use.

use crate::instruction::InstructionInfo;

/// An opaque reference to a Cardinal SSA value.  These can be used as instruction parameters,
/// if a value is not used, it will not be included in the generated code.
#[derive(Clone, Copy, PartialEq)]
pub struct Value(pub u32);

/// An opaque reference to a Cardinal IR block.
#[derive(Clone, Copy, PartialEq)]
pub struct Block(pub u32);

/// An opaque reference to a Cardinal variable.
#[derive(Clone, PartialEq)]
pub struct Variable(pub String);

impl Variable {

    pub fn named(&self) -> Named {
        Named::new(self.0.to_string())
    }

}

/// An opaque reference to a Cardinal global variable.
#[derive(Clone, PartialEq)]
pub struct GlobalVariable(pub String);

impl GlobalVariable {

    pub fn named(&self) -> Named {
        Named::new(self.0.to_string())
    }

}

/// Different types of types that can be declared.
#[derive(Clone, PartialEq)]
pub enum Type {

    /// A plain type, such as `int` or `double`.
    Plain,

    /// An array type, such as `char[]` or `int[]`. `-1` should be used as the size argument if
    /// a size should be declared implicitly.
    Array(isize),

    /// A pointer type, such as `char*` or `int*`.
    Pointer,

}

/// An ABI type.
#[derive(Clone, PartialEq)]
pub struct AbiType(pub String, pub Type);

/// An ABI value used for function parameters.
#[derive(Clone, PartialEq)]
pub struct AbiParam(pub String, pub AbiType);

/// Properties of a `Named` struct that may be basic properties, static properties, pointer
/// properties or index properties.
#[derive(Clone, PartialEq)]
pub enum NamedProperty {

    /// A basic property, for example, `Named.Basic`.
    Basic(String),

    /// A reference to a static property, which is not supported by the C backend. For example,
    /// `Named::Basic` in C++ or Rust.
    Static(String),

    /// A pointer property, for example, `Named->Pointer`.
    Pointer(String),

    /// An index in a named value, for example, `Named[Index]`.  It uses a value that is
    /// determined at compile time.
    Index(Value),

}

/// Used as a named reference to an object.
#[derive(Clone, PartialEq)]
pub struct Named {

    /// The name of the first object in the reference.
    pub name: String,

    /// A list of indexes performed on the Named reference.
    /// 
    /// For example,
    /// ```c
    /// Named.Index1->Index2
    /// ```
    pub properties: Vec<NamedProperty>

}

impl Named {

    /// Creates a Named object with no properties.
    pub fn new(name: String) -> Self {
        Self {
            name,
            properties: vec![]
        }
    }

    /// Creates a Named object with a list of properties.
    pub fn new_props(name: String, properties: Vec<NamedProperty>) -> Self {
        Self {
            name,
            properties
        }
    }

}


/// Information about a value.
#[derive(Clone)]
pub enum ValueInfo {

    /// An integer constant.
    IntegerConstant(u64),

    /// A floating point number constant.
    FloatConstant(f64),

    /// A double constant.
    DoubleConstant(f64),

    /// A boolean constant.
    BooleanConstant(bool),

    /// A string constant.
    StringConstant(String),

    /// A character constant.
    CharConstant(String),

    /// A named reference.
    Named(Named),

    /// A value reference to a block.
    Block(Block),

    /// A pointer to an instruction.
    Instruction(InstructionInfo),

}