elysium/types.go

194 lines
4.3 KiB
Go
Raw Normal View History

2024-03-11 22:05:36 +01:00
package main
import (
2024-03-17 19:55:28 +01:00
"errors"
"slices"
2024-03-11 22:05:36 +01:00
"strconv"
)
type Lang_I8 int8
type Lang_I16 int16
type Lang_I32 int32
type Lang_I64 int64
type Lang_U8 uint8
type Lang_U16 uint16
type Lang_U32 uint32
type Lang_U64 uint64
2024-03-14 16:42:22 +01:00
type Lang_Bool bool
2024-03-17 19:55:28 +01:00
var PRIMITIVE_TYPE_NAMES = []string{"i8", "i16", "i32", "i64", "u8", "u16", "u32", "u64", "f32", "f64", "bool"}
2024-03-11 22:05:36 +01:00
type PrimitiveType uint32
const (
Primitive_I8 PrimitiveType = iota
Primitive_I16
Primitive_I32
Primitive_I64
Primitive_U8
Primitive_U16
Primitive_U32
Primitive_U64
Primitive_F32
Primitive_F64
2024-03-14 16:42:22 +01:00
Primitive_Bool
2024-03-11 22:05:36 +01:00
)
2024-03-17 19:55:28 +01:00
const STRING_TYPE_NAME = "string"
var STRING_TYPE = Type{Type: Type_Named, Value: STRING_TYPE_NAME}
2024-03-11 22:05:36 +01:00
const InvalidValue = 0xEEEEEE // Magic value
2024-03-13 23:26:20 +01:00
type CompilerError struct {
Position TokenPosition
2024-03-13 23:26:20 +01:00
Message string
}
func (e CompilerError) Error() string {
return e.Message + " (at " + e.Position.SourceFile + ", index " + strconv.FormatUint(e.Position.Position, 10) + ")"
2024-03-13 23:26:20 +01:00
}
2024-03-11 22:05:36 +01:00
func isSignedInt(primitiveType PrimitiveType) bool {
switch primitiveType {
case Primitive_I8, Primitive_I16, Primitive_I32, Primitive_I64:
return true
default:
return false
}
}
func isUnsignedInt(primitiveType PrimitiveType) bool {
switch primitiveType {
case Primitive_U8, Primitive_U16, Primitive_U32, Primitive_U64:
return true
default:
return false
}
}
func isFloatingPoint(primitiveType PrimitiveType) bool {
switch primitiveType {
case Primitive_F32, Primitive_F64:
return true
default:
return false
}
}
func getBits(primitiveType PrimitiveType) int {
switch primitiveType {
case Primitive_I8, Primitive_U8:
return 8
case Primitive_I16, Primitive_U16:
return 16
case Primitive_I32, Primitive_U32, Primitive_F32:
return 32
case Primitive_I64, Primitive_U64, Primitive_F64:
return 64
default:
panic("Passed an invalid type (" + strconv.FormatUint(uint64(primitiveType), 10) + ") to getBits()")
}
}
2024-03-17 19:55:28 +01:00
func getPrimitiveTypeByName(name string) (PrimitiveType, error) {
idx := slices.Index(PRIMITIVE_TYPE_NAMES, name)
if idx == -1 {
return InvalidValue, errors.New("not a primitive type name")
}
return PrimitiveType(idx), nil
}
2024-03-23 14:03:20 +01:00
2024-03-28 15:48:50 +01:00
func getPrimitiveTypeName(primitiveType PrimitiveType) string {
return PRIMITIVE_TYPE_NAMES[primitiveType]
}
func getTypeName(theType Type) string {
switch theType.Type {
case Type_Primitive:
return getPrimitiveTypeName(theType.Value.(PrimitiveType))
case Type_Named:
return theType.Value.(NamedType).TypeName
case Type_Array:
return getTypeName(theType.Value.(ArrayType).ElementType) + "[]"
case Type_Tuple:
name := "("
for idx, member := range theType.Value.(TupleType).Types {
name += getTypeName(member)
if idx != len(theType.Value.(TupleType).Types)-1 {
name += ", "
}
}
name += ")"
return name
default:
panic("type name not implemented")
}
}
func (t Type) String() string {
return getTypeName(t)
}
func (t PrimitiveType) String() string {
return getPrimitiveTypeName(t)
}
2024-03-23 14:03:20 +01:00
func isAssigmentOperator(operator Operator) bool {
switch operator {
case Operator_Equals, Operator_PlusEquals, Operator_MinusEquals, Operator_MultiplyEquals, Operator_DivideEquals, Operator_ModuloEquals:
return true
default:
return false
}
}
2024-03-24 14:01:23 +01:00
func getOperation(operator Operator) Operation {
2024-03-23 14:03:20 +01:00
switch operator {
case Operator_Greater:
2024-03-24 14:01:23 +01:00
return Operation_Greater
2024-03-23 14:03:20 +01:00
case Operator_Less:
2024-03-24 14:01:23 +01:00
return Operation_Less
2024-03-23 14:03:20 +01:00
case Operator_Not:
2024-03-24 14:01:23 +01:00
return Operation_LogicalNot
2024-03-23 14:03:20 +01:00
case Operator_Plus, Operator_PlusEquals:
2024-03-24 14:01:23 +01:00
return Operation_Add
2024-03-23 14:03:20 +01:00
case Operator_Minus, Operator_MinusEquals:
2024-03-24 14:01:23 +01:00
return Operation_Sub
2024-03-23 14:03:20 +01:00
case Operator_Multiply, Operator_MultiplyEquals:
2024-03-24 14:01:23 +01:00
return Operation_Mul
2024-03-23 14:03:20 +01:00
case Operator_Divide, Operator_DivideEquals:
2024-03-24 14:01:23 +01:00
return Operation_Div
2024-03-23 14:03:20 +01:00
case Operator_Modulo, Operator_ModuloEquals:
2024-03-24 14:01:23 +01:00
return Operation_Mod
2024-03-23 14:03:20 +01:00
case Operator_EqualsEquals:
2024-03-24 14:01:23 +01:00
return Operation_Equals
2024-03-23 14:03:20 +01:00
case Operator_GreaterEquals:
2024-03-24 14:01:23 +01:00
return Operation_GreaterEquals
2024-03-23 14:03:20 +01:00
case Operator_LessEquals:
2024-03-24 14:01:23 +01:00
return Operation_LessEquals
2024-03-23 14:03:20 +01:00
case Operator_NotEquals:
2024-03-24 14:01:23 +01:00
return Operation_NotEquals
2024-03-23 14:03:20 +01:00
default:
return InvalidValue
}
}
2024-03-24 14:01:23 +01:00
func isBooleanOperation(operation Operation) bool {
switch operation {
case Operation_Greater, Operation_Less, Operation_LogicalNot, Operation_Equals, Operation_GreaterEquals, Operation_LessEquals, Operation_NotEquals:
return true
default:
return false
}
}
func isArithmeticOperation(operation Operation) bool {
return !isBooleanOperation(operation)
}