Doesn't give right answer yet and out of bound check fails. No constructor yet for static arrays, but module constants work. Which don't work yet for tuples and structs. Also, u32 for indexing please. Also, more module constant types.
203 lines
4.2 KiB
Python
203 lines
4.2 KiB
Python
"""
|
|
The phasm type system
|
|
"""
|
|
from typing import Optional, List
|
|
|
|
class TypeBase:
|
|
"""
|
|
TypeBase base class
|
|
"""
|
|
__slots__ = ()
|
|
|
|
def alloc_size(self) -> int:
|
|
"""
|
|
When allocating this type in memory, how many bytes do we need to reserve?
|
|
"""
|
|
raise NotImplementedError(self, 'alloc_size')
|
|
|
|
class TypeNone(TypeBase):
|
|
"""
|
|
The None (or Void) type
|
|
"""
|
|
__slots__ = ()
|
|
|
|
class TypeBool(TypeBase):
|
|
"""
|
|
The boolean type
|
|
"""
|
|
__slots__ = ()
|
|
|
|
class TypeUInt8(TypeBase):
|
|
"""
|
|
The Integer type, unsigned and 8 bits wide
|
|
|
|
Note that under the hood we need to use i32 to represent
|
|
these values in expressions. So we need to add some operations
|
|
to make sure the math checks out.
|
|
|
|
So while this does save bytes in memory, it may not actually
|
|
speed up or improve your code.
|
|
"""
|
|
__slots__ = ()
|
|
|
|
def alloc_size(self) -> int:
|
|
return 4 # Int32 under the hood
|
|
|
|
class TypeUInt32(TypeBase):
|
|
"""
|
|
The Integer type, unsigned and 32 bits wide
|
|
"""
|
|
__slots__ = ()
|
|
|
|
def alloc_size(self) -> int:
|
|
return 4
|
|
|
|
class TypeUInt64(TypeBase):
|
|
"""
|
|
The Integer type, unsigned and 64 bits wide
|
|
"""
|
|
__slots__ = ()
|
|
|
|
def alloc_size(self) -> int:
|
|
return 8
|
|
|
|
class TypeInt32(TypeBase):
|
|
"""
|
|
The Integer type, signed and 32 bits wide
|
|
"""
|
|
__slots__ = ()
|
|
|
|
def alloc_size(self) -> int:
|
|
return 4
|
|
|
|
class TypeInt64(TypeBase):
|
|
"""
|
|
The Integer type, signed and 64 bits wide
|
|
"""
|
|
__slots__ = ()
|
|
|
|
def alloc_size(self) -> int:
|
|
return 8
|
|
|
|
class TypeFloat32(TypeBase):
|
|
"""
|
|
The Float type, 32 bits wide
|
|
"""
|
|
__slots__ = ()
|
|
|
|
def alloc_size(self) -> int:
|
|
return 4
|
|
|
|
class TypeFloat64(TypeBase):
|
|
"""
|
|
The Float type, 64 bits wide
|
|
"""
|
|
__slots__ = ()
|
|
|
|
def alloc_size(self) -> int:
|
|
return 8
|
|
|
|
class TypeBytes(TypeBase):
|
|
"""
|
|
The bytes type
|
|
"""
|
|
__slots__ = ()
|
|
|
|
class TypeTupleMember:
|
|
"""
|
|
Represents a tuple member
|
|
"""
|
|
def __init__(self, idx: int, type_: TypeBase, offset: int) -> None:
|
|
self.idx = idx
|
|
self.type = type_
|
|
self.offset = offset
|
|
|
|
class TypeTuple(TypeBase):
|
|
"""
|
|
The tuple type
|
|
"""
|
|
__slots__ = ('members', )
|
|
|
|
members: List[TypeTupleMember]
|
|
|
|
def __init__(self) -> None:
|
|
self.members = []
|
|
|
|
def render_internal_name(self) -> str:
|
|
"""
|
|
Generates an internal name for this tuple
|
|
"""
|
|
mems = '@'.join('?' for x in self.members) # FIXME: Should not be a questionmark
|
|
assert ' ' not in mems, 'Not implement yet: subtuples'
|
|
return f'tuple@{mems}'
|
|
|
|
def alloc_size(self) -> int:
|
|
return sum(
|
|
x.type.alloc_size()
|
|
for x in self.members
|
|
)
|
|
|
|
class TypeStaticArrayMember:
|
|
"""
|
|
Represents a static array member
|
|
"""
|
|
def __init__(self, idx: int, offset: int) -> None:
|
|
self.idx = idx
|
|
self.offset = offset
|
|
|
|
class TypeStaticArray(TypeBase):
|
|
"""
|
|
The static array type
|
|
"""
|
|
__slots__ = ('member_type', 'members', )
|
|
|
|
member_type: TypeBase
|
|
members: List[TypeStaticArrayMember]
|
|
|
|
def __init__(self, member_type: TypeBase) -> None:
|
|
self.member_type = member_type
|
|
self.members = []
|
|
|
|
def alloc_size(self) -> int:
|
|
return self.member_type.alloc_size() * len(self.members)
|
|
|
|
class TypeStructMember:
|
|
"""
|
|
Represents a struct member
|
|
"""
|
|
def __init__(self, name: str, type_: TypeBase, offset: int) -> None:
|
|
self.name = name
|
|
self.type = type_
|
|
self.offset = offset
|
|
|
|
class TypeStruct(TypeBase):
|
|
"""
|
|
A struct has named properties
|
|
"""
|
|
__slots__ = ('name', 'lineno', 'members', )
|
|
|
|
name: str
|
|
lineno: int
|
|
members: List[TypeStructMember]
|
|
|
|
def __init__(self, name: str, lineno: int) -> None:
|
|
self.name = name
|
|
self.lineno = lineno
|
|
self.members = []
|
|
|
|
def get_member(self, name: str) -> Optional[TypeStructMember]:
|
|
"""
|
|
Returns a member by name
|
|
"""
|
|
for mem in self.members:
|
|
if mem.name == name:
|
|
return mem
|
|
|
|
return None
|
|
|
|
def alloc_size(self) -> int:
|
|
return sum(
|
|
x.type.alloc_size()
|
|
for x in self.members
|
|
)
|