initial draft
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
package types
|
||||
|
||||
import "core:fmt"
|
||||
|
||||
Numeric_Category :: enum {
|
||||
None,
|
||||
Signed_Integer,
|
||||
Unsigned_Integer,
|
||||
Float,
|
||||
}
|
||||
|
||||
Kind :: enum {
|
||||
Invalid,
|
||||
Void,
|
||||
Int_Constraint,
|
||||
Concrete,
|
||||
}
|
||||
|
||||
Type :: struct {
|
||||
kind: Kind,
|
||||
category: Numeric_Category,
|
||||
bits: int,
|
||||
}
|
||||
|
||||
INVALID :: Type {
|
||||
kind = .Invalid,
|
||||
}
|
||||
VOID :: Type {
|
||||
kind = .Void,
|
||||
}
|
||||
INT :: Type {
|
||||
kind = .Int_Constraint,
|
||||
category = .Signed_Integer,
|
||||
}
|
||||
I8 :: Type {
|
||||
kind = .Concrete,
|
||||
category = .Signed_Integer,
|
||||
bits = 8,
|
||||
}
|
||||
I16 :: Type {
|
||||
kind = .Concrete,
|
||||
category = .Signed_Integer,
|
||||
bits = 16,
|
||||
}
|
||||
I32 :: Type {
|
||||
kind = .Concrete,
|
||||
category = .Signed_Integer,
|
||||
bits = 32,
|
||||
}
|
||||
I64 :: Type {
|
||||
kind = .Concrete,
|
||||
category = .Signed_Integer,
|
||||
bits = 64,
|
||||
}
|
||||
|
||||
is_valid :: proc(value: Type) -> bool {
|
||||
return value.kind != .Invalid
|
||||
}
|
||||
|
||||
is_concrete_integer :: proc(value: Type) -> bool {
|
||||
return(
|
||||
value.kind == .Concrete &&
|
||||
(value.category == .Signed_Integer || value.category == .Unsigned_Integer) \
|
||||
)
|
||||
}
|
||||
|
||||
is_signed :: proc(value: Type) -> bool {
|
||||
return value.kind == .Concrete && value.category == .Signed_Integer
|
||||
}
|
||||
|
||||
equal :: proc(a, b: Type) -> bool {
|
||||
return a.kind == b.kind && a.category == b.category && a.bits == b.bits
|
||||
}
|
||||
|
||||
can_widen :: proc(from, to: Type) -> bool {
|
||||
if equal(from, to) {
|
||||
return true
|
||||
}
|
||||
return(
|
||||
from.kind == .Concrete &&
|
||||
to.kind == .Concrete &&
|
||||
from.category == to.category &&
|
||||
from.bits < to.bits \
|
||||
)
|
||||
}
|
||||
|
||||
widest :: proc(a, b: Type) -> Type {
|
||||
if a.kind != .Concrete || b.kind != .Concrete || a.category != b.category {
|
||||
return INVALID
|
||||
}
|
||||
if a.bits >= b.bits {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
smallest_signed_for_literal :: proc(value: i64) -> Type {
|
||||
if value >= -128 && value <= 127 {
|
||||
return I8
|
||||
}
|
||||
if value >= -32768 && value <= 32767 {
|
||||
return I16
|
||||
}
|
||||
if value >= -2147483648 && value <= 2147483647 {
|
||||
return I32
|
||||
}
|
||||
return I64
|
||||
}
|
||||
|
||||
name :: proc(value: Type) -> string {
|
||||
switch value.kind {
|
||||
case .Invalid:
|
||||
return "<invalid>"
|
||||
case .Void:
|
||||
return "void"
|
||||
case .Int_Constraint:
|
||||
return "int"
|
||||
case .Concrete:
|
||||
switch value.category {
|
||||
case .Signed_Integer:
|
||||
switch value.bits {
|
||||
case 8:
|
||||
return "i8"
|
||||
case 16:
|
||||
return "i16"
|
||||
case 32:
|
||||
return "i32"
|
||||
case 64:
|
||||
return "i64"
|
||||
}
|
||||
case .Unsigned_Integer:
|
||||
return fmt.tprintf("u%d", value.bits)
|
||||
case .Float:
|
||||
return fmt.tprintf("f%d", value.bits)
|
||||
case .None:
|
||||
}
|
||||
}
|
||||
return "<invalid>"
|
||||
}
|
||||
Reference in New Issue
Block a user