-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathconstants.jou
107 lines (95 loc) · 3.21 KB
/
constants.jou
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import "stdlib/str.jou"
import "stdlib/io.jou"
import "stdlib/mem.jou"
import "./utils.jou"
import "./types.jou"
# Constants can appear in AST and also compilation steps after AST.
enum ConstantKind:
EnumMember
Integer
Float
Double
String
Null
Bool
class IntegerConstant:
size_in_bits: int
is_signed: bool
value: long
class EnumMemberConstant:
enumtype: Type*
memberidx: int
class Constant:
kind: ConstantKind
union:
integer: IntegerConstant
str: byte*
# TODO: rename double_or_float_text --> float_or_double_text to be consistent with AST
double_or_float_text: byte[100] # convenient because LLVM wants a string anyway
boolean: bool
enum_member: EnumMemberConstant
def print(self) -> None:
match self->kind:
case ConstantKind.EnumMember:
printf("enum member %d of %s", self->enum_member.memberidx, self->enum_member.enumtype->name)
case ConstantKind.Bool:
if self->boolean:
printf("True")
else:
printf("False")
case ConstantKind.Float:
printf("float %s", self->double_or_float_text)
case ConstantKind.Double:
printf("double %s", self->double_or_float_text)
case ConstantKind.Integer:
if self->integer.is_signed:
signed_or_unsigned = "signed"
else:
signed_or_unsigned = "unsigned"
printf(
"%lld (%d-bit %s)",
self->integer.value,
self->integer.size_in_bits,
signed_or_unsigned,
)
case ConstantKind.Null:
printf("NULL")
case ConstantKind.String:
printf("string ")
print_string(self->str, strlen(self->str))
printf("\n")
def free(self) -> None:
if self->kind == ConstantKind.String:
free(self->str)
def copy(self: Constant) -> Constant:
if self.kind == ConstantKind.String:
self.str = strdup(self.str)
assert self.str != NULL
return self
def get_type(self) -> Type*:
match self->kind:
case ConstantKind.EnumMember:
return self->enum_member.enumtype
case ConstantKind.Null:
return voidPtrType
case ConstantKind.Double:
return doubleType
case ConstantKind.Float:
return floatType
case ConstantKind.Bool:
return boolType
case ConstantKind.String:
return byteType->pointer_type()
case ConstantKind.Integer:
return get_integer_type(self->integer.size_in_bits, self->integer.is_signed)
assert False
def int_constant(type: Type*, value: long) -> Constant:
assert type->is_integer_type()
return Constant{
kind = ConstantKind.Integer,
integer = IntegerConstant{
size_in_bits = type->size_in_bits,
is_signed = type->kind == TypeKind.SignedInteger,
value = value
}
}