You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
296 lines
5.9 KiB
D
296 lines
5.9 KiB
D
/**
|
|
* Data structures which represent kind-of `Entity`(s),
|
|
* starting with the base-`Entity`, `Type`, which represents
|
|
* a name that describes a data type
|
|
*/
|
|
module tlang.compiler.symbols.typing.core;
|
|
|
|
import tlang.compiler.symbols.data;
|
|
import std.string : cmp;
|
|
import std.conv : to;
|
|
|
|
public import tlang.compiler.symbols.typing.builtins;
|
|
|
|
/**
|
|
* The base entity from which all types are derived
|
|
* from
|
|
*/
|
|
public class Type : Entity
|
|
{
|
|
/* TODO: Add width here */
|
|
|
|
/**
|
|
* TODO: See what we need in here, Entity name could be our Type name
|
|
* But to make it look nice we could just have `getType`
|
|
* Actually yeah, we should, as Number types won't be entities
|
|
* Wait lmao they will
|
|
*/
|
|
|
|
/**
|
|
* Constructs a new `Type` with the
|
|
* given name
|
|
*
|
|
* Params:
|
|
* name = the new type's name
|
|
*/
|
|
this(string name)
|
|
{
|
|
super(name);
|
|
}
|
|
|
|
// TODO: A comparator would be nice but I would have to then see
|
|
// ... where referene equality was used, hence I stear clear of that
|
|
}
|
|
|
|
/**
|
|
* Represents a void type, a type
|
|
* which has no return value for it
|
|
*/
|
|
public final class Void : Primitive
|
|
{
|
|
/**
|
|
* Constructs a new `Void` type
|
|
*/
|
|
this()
|
|
{
|
|
super("void");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Represents all primitive data types
|
|
*/
|
|
public class Primitive : Type
|
|
{
|
|
/**
|
|
* Constructs a new `Primitive`
|
|
* type
|
|
*
|
|
* Params:
|
|
* name = the new type's name
|
|
*/
|
|
this(string name)
|
|
{
|
|
super(name);
|
|
}
|
|
}
|
|
|
|
/* TODO: Move width to Type class */
|
|
/**
|
|
* Represents any kind of number
|
|
*
|
|
* This means it has a width associated
|
|
* with it which is the number of bytes
|
|
* wide it is
|
|
*/
|
|
public class Number : Primitive
|
|
{
|
|
/**
|
|
* Number of bytes (1,2,4,8)
|
|
*/
|
|
private ubyte width;
|
|
|
|
/* TODO: Aligbment details etc. */
|
|
/**
|
|
* COnstructs a new `Number` type
|
|
* with the given name and width
|
|
*
|
|
* Params:
|
|
* name = the new type's name
|
|
* width = the bit-width (in bytes)
|
|
*/
|
|
this(string name, ubyte width)
|
|
{
|
|
super(name);
|
|
this.width = width;
|
|
}
|
|
|
|
/**
|
|
* Returns the bit-width of this number
|
|
*
|
|
* Returns: the width in bytes
|
|
*/
|
|
public final ubyte getSize()
|
|
{
|
|
return width;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Represents an integer, a kind-of `Number`,
|
|
* but with a signedness/unsignedness encoding
|
|
* scheme associated with it
|
|
*/
|
|
public class Integer : Number
|
|
{
|
|
/**
|
|
* Whether or not signed (if so, then 2's complement)
|
|
*/
|
|
private bool signed;
|
|
|
|
/**
|
|
* Constructs a new `Integer` type with the given
|
|
* parameters
|
|
*
|
|
* Params:
|
|
* name = the name of this type
|
|
* width = the bit-width (in bytes)
|
|
* signed = whether or not it represents a
|
|
* two's complement signed integer or not
|
|
*/
|
|
this(string name, ubyte width, bool signed = false)
|
|
{
|
|
super(name, width);
|
|
this.signed = signed;
|
|
}
|
|
|
|
/**
|
|
* Determines if the type of
|
|
* integer being described is signed
|
|
* or not
|
|
*
|
|
* Returns: `true` if signed, `false`
|
|
* otherwise
|
|
*/
|
|
public final bool isSigned()
|
|
{
|
|
return signed;
|
|
}
|
|
|
|
/* TODO: Remove ig */
|
|
/**
|
|
* Returns a string representation of
|
|
* this `Integer` type
|
|
*
|
|
* Returns: a `string`
|
|
*/
|
|
public override string toString()
|
|
{
|
|
return name;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Represents a floating point number
|
|
*/
|
|
public class Float : Number
|
|
{
|
|
/**
|
|
* Constructs a new floating point
|
|
* type with the given name and width
|
|
*
|
|
* Params:
|
|
* name = this type's name
|
|
* width = the width (in bytes) of
|
|
* the floating point
|
|
*/
|
|
this(string name, ubyte width)
|
|
{
|
|
super(name, width);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A `Pointer`, is a kind-of `Integer`
|
|
* which is unsigned. This represents
|
|
* a memory address and is CURRENTLY
|
|
* set to `8` bytes (TODO: Change this
|
|
* to be dependent on the system used
|
|
* basically it should actually take
|
|
* in a size)
|
|
*
|
|
* A pointer is a 64-bit integer
|
|
* that point to data in memory of
|
|
* another given type
|
|
*/
|
|
public class Pointer : Integer
|
|
{
|
|
/**
|
|
* Data type being pointed to
|
|
*/
|
|
private Type dataType;
|
|
|
|
/**
|
|
* Constructs a new `Pointer` to point
|
|
* to data of the given type
|
|
*
|
|
* Params:
|
|
* dataType = the `Type` of data being
|
|
* pointed to
|
|
*/
|
|
this(Type dataType)
|
|
{
|
|
/* The name should be `dataType*` */
|
|
string name = dataType.toString()~"*";
|
|
|
|
/* TODO: Change below, per architetcure (the 8 byte width) */
|
|
super(name, 8);
|
|
this.dataType = dataType;
|
|
}
|
|
|
|
/**
|
|
* Returns the `Type` of the data this
|
|
* pointer refers to
|
|
*
|
|
* Returns: the `Type`
|
|
*/
|
|
public Type getReferredType()
|
|
{
|
|
return dataType;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Stack-based Array type
|
|
*/
|
|
public class StackArray : Type
|
|
{
|
|
/**
|
|
* Size of the stack array to allocate
|
|
*/
|
|
private ulong arraySize;
|
|
|
|
/**
|
|
* Component type
|
|
*/
|
|
private Type elementType;
|
|
|
|
/**
|
|
* Constructs a new `StackArray` type
|
|
* with the given type of element and
|
|
* the size to allocate on the stack
|
|
*
|
|
* Params:
|
|
* elementType = the component `Type`
|
|
* arraySize = the stack allocation size
|
|
*/
|
|
this(Type elementType, ulong arraySize)
|
|
{
|
|
/* The name should be `elementType[arraySize]` */
|
|
super(to!(string)(elementType)~"["~to!(string)(arraySize)~"]");
|
|
|
|
this.elementType = elementType;
|
|
this.arraySize = arraySize;
|
|
}
|
|
|
|
/**
|
|
* Gets the stack array's element type
|
|
*
|
|
* Returns: the `Type` of the components
|
|
*/
|
|
public Type getComponentType()
|
|
{
|
|
return elementType;
|
|
}
|
|
|
|
/**
|
|
* Gets the size to be allocated on the stack
|
|
* for this array
|
|
*
|
|
* Returns: the size
|
|
*/
|
|
public ulong getAllocatedSize()
|
|
{
|
|
return arraySize;
|
|
}
|
|
} |