Cthulhu  0.2.10
Cthulhu compiler collection
value.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: LGPL-3.0-only
2 
3 #include "arena/arena.h"
4 #include "common.h"
5 
6 #include "cthulhu/tree/tree.h"
7 
8 #include "std/vector.h"
9 
10 #include "base/panic.h"
11 #include "memory/memory.h"
12 
13 #define EXPECT_TYPE(TY, KIND) CTASSERTF(TY->kind == KIND, "expected %s, got %s", ssa_type_name(KIND), ssa_type_name(TY->kind))
14 
15 static ssa_value_t *ssa_value_new(const ssa_type_t *type, bool init, ssa_value_state_t value)
16 {
17  arena_t *arena = get_global_arena();
18  ssa_value_t *self = ARENA_MALLOC(sizeof(ssa_value_t), "ssa_value", NULL, arena);
19  self->type = type;
20  self->value = value;
21  self->init = init;
22  return self;
23 }
24 
26 {
27  EXPECT_TYPE(type, eTypeEmpty);
28  ssa_literal_value_t literal = { 0 };
29  return ssa_value_literal(type, literal);
30 }
31 
33 {
34  EXPECT_TYPE(type, eTypeUnit);
35  ssa_literal_value_t literal = { 0 };
36  return ssa_value_literal(type, literal);
37 }
38 
39 ssa_value_t *ssa_value_bool(const ssa_type_t *type, bool value)
40 {
41  EXPECT_TYPE(type, eTypeBool);
42  ssa_literal_value_t literal = { .boolean = value };
43  return ssa_value_literal(type, literal);
44 }
45 
46 ssa_value_t *ssa_value_digit(const ssa_type_t *type, const mpz_t value)
47 {
48  EXPECT_TYPE(type, eTypeDigit);
49  ssa_literal_value_t literal = { 0 };
50  mpz_init_set(literal.digit, value);
51  return ssa_value_literal(type, literal);
52 }
53 
54 ssa_value_t *ssa_value_char(const ssa_type_t *type, char value)
55 {
56  EXPECT_TYPE(type, eTypeDigit);
57  ssa_literal_value_t literal = { 0 };
58  mpz_init_set_ui(literal.digit, value);
59  return ssa_value_literal(type, literal);
60 }
61 
63 {
64  EXPECT_TYPE(type, eTypePointer);
65 
66  const char *string = text.text;
67  size_t length = text.length;
68 
69  ssa_type_pointer_t ptr = type->pointer;
70  EXPECT_TYPE(ptr.pointer, eTypeDigit);
71  CTASSERTF(ptr.length != 0 && ptr.length != SIZE_MAX, "invalid string length: %zu", ptr.length);
72 
73  arena_t *arena = get_global_arena();
74  vector_t *data = vector_of(length, arena);
75  for (size_t i = 0; i < length; i++)
76  {
77  ssa_value_t *value = ssa_value_char(ptr.pointer, string[i]);
78  vector_set(data, i, value);
79  }
80 
81  ssa_literal_value_t literal = { .data = data };
82  ssa_value_t *self = ssa_value_literal(type, literal);
83 
84  return self;
85 }
86 
87 ssa_value_t *ssa_value_from(map_t *types, const tree_t *expr)
88 {
89  const ssa_type_t *type = ssa_type_create_cached(types, tree_get_type(expr));
90  switch (expr->kind)
91  {
92  case eTreeExprEmpty: return ssa_value_empty(type);
93  case eTreeExprUnit: return ssa_value_unit(type);
94  case eTreeExprBool: return ssa_value_bool(type, expr->bool_value);
95  case eTreeExprDigit: return ssa_value_digit(type, expr->digit_value);
96  case eTreeExprString: return ssa_value_string(type, expr->string_value);
97  default: CT_NEVER("Invalid expr kind: %d", expr->kind);
98  }
99 }
100 
102 {
103  return ssa_value_new(type, false, eValueLiteral);
104 }
105 
107 {
108  ssa_value_t *self = ssa_value_new(type, true, eValueLiteral);
109  self->literal = value;
110  return self;
111 }
112 
114 {
115  ssa_value_t *self = ssa_value_new(type, true, eValueRelative);
116  self->relative = value;
117  return self;
118 }
119 
121 {
122  ssa_literal_value_t literal = { 0 };
123  mpz_init_set(literal.pointer, value);
124  return ssa_value_literal(type, literal);
125 }
126 
127 STA_DECL
129 {
130  CTASSERT(value != NULL);
131  CTASSERT(value->value == eValueLiteral);
132  return value->literal;
133 }
134 
135 STA_DECL
136 bool ssa_value_get_bool(const ssa_value_t *value)
137 {
139  CTASSERTF(value->type->kind == eTypeBool, "expected bool, got %s", ssa_type_name(value->type->kind));
140 
141  return literal.boolean;
142 }
143 
144 STA_DECL
145 void ssa_value_get_digit(const ssa_value_t *value, mpz_t result)
146 {
148  CTASSERTF(value->type->kind == eTypeDigit, "expected digit, got %s", ssa_type_name(value->type->kind));
149 
150  mpz_init_set(result, literal.digit);
151 }
CT_PUREFN CT_TREE_API const tree_t * tree_get_type(const tree_t *tree)
Definition: context.c:132
ssa_type_t * ssa_type_create_cached(map_t *cache, const tree_t *type)
Definition: type.c:226
#define STA_DECL
sal2 annotation on function implementations to copy annotations from the declaration
CT_MEMORY_API arena_t * get_global_arena(void)
get the global memory arena
Definition: memory.c:16
#define ARENA_MALLOC(size, name, parent, arena)
allocate memory from a custom allocator
Definition: arena.h:392
#define CT_NEVER(...)
assert that a code path is never reached
Definition: panic.h:136
#define CTASSERT(expr)
assert a condition, prints the condition as a message
Definition: panic.h:130
#define CTASSERTF(expr,...)
assert a condition with a message and optional format arguments
Definition: panic.h:116
CT_CONSTFN CT_NODISCARD CT_SSA_API const char * ssa_type_name(STA_IN_RANGE(0, eTypeCount - 1) ssa_kind_t kind)
STA_DECL bool ssa_value_get_bool(const ssa_value_t *value)
Definition: value.c:136
ssa_value_state_t
Definition: ssa.h:61
STA_DECL ssa_literal_value_t ssa_value_get_literal(const ssa_value_t *value)
Definition: value.c:128
CT_NODISCARD CT_STD_API vector_t * vector_of(size_t len, arena_t *arena)
create a new vector with a specified length
Definition: vector.c:71
CT_STD_API void vector_set(vector_t *vector, size_t index, void *value)
set a value in a vector
Definition: vector.c:125
an allocator object
Definition: arena.h:86
an unordered hash map
Definition: map.h:38
const ssa_type_t * pointer
Definition: ssa.h:137
size_t length
Definition: ssa.h:138
ssa_kind_t kind
Definition: ssa.h:146
ssa_type_pointer_t pointer
Definition: ssa.h:153
ssa_literal_value_t literal
Definition: ssa.h:184
ssa_value_state_t value
Definition: ssa.h:179
const ssa_type_t * type
Definition: ssa.h:178
a non-owning view of text
Definition: text.h:24
size_t length
the number of characters in the text
Definition: text.h:30
Definition: tree.h:67
tree_kind_t kind
Definition: tree.h:68
bool bool_value
Definition: tree.h:78
text_view_t string_value
Definition: tree.h:81
mpz_t digit_value
Definition: tree.h:75
a generic vector of pointers
Definition: vector.c:16
vector_t * data
Definition: ssa.h:167
mpz_t pointer
Definition: ssa.h:170
ssa_value_t * ssa_value_bool(const ssa_type_t *type, bool value)
Definition: value.c:39
ssa_value_t * ssa_value_unit(const ssa_type_t *type)
Definition: value.c:32
ssa_value_t * ssa_value_string(const ssa_type_t *type, text_view_t text)
Definition: value.c:62
ssa_value_t * ssa_value_opaque_literal(const ssa_type_t *type, mpz_t value)
Definition: value.c:120
ssa_value_t * ssa_value_from(map_t *types, const tree_t *expr)
Definition: value.c:87
#define EXPECT_TYPE(TY, KIND)
Definition: value.c:13
ssa_value_t * ssa_value_relative(const ssa_type_t *type, ssa_relative_value_t value)
Definition: value.c:113
ssa_value_t * ssa_value_empty(const ssa_type_t *type)
Definition: value.c:25
ssa_value_t * ssa_value_literal(const ssa_type_t *type, ssa_literal_value_t value)
Definition: value.c:106
ssa_value_t * ssa_value_char(const ssa_type_t *type, char value)
Definition: value.c:54
ssa_value_t * ssa_value_digit(const ssa_type_t *type, const mpz_t value)
Definition: value.c:46
STA_DECL void ssa_value_get_digit(const ssa_value_t *value, mpz_t result)
Definition: value.c:145
ssa_value_t * ssa_value_noinit(const ssa_type_t *type)
Definition: value.c:101