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.
tlang/source/tlang/compiler/symbols/typing/core.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;
}
}