Skip to content

Commit af5a5f6

Browse files
committed
Changed '$T' polymorphs to always allow built-in auto conversions (equivalent to '$~T' in previous versions)
1 parent bad7b99 commit af5a5f6

File tree

9 files changed

+76
-56
lines changed

9 files changed

+76
-56
lines changed

include/AST/ast_type.h

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,15 @@ typedef struct {
108108

109109
// ---------------- ast_elem_polymorph_t ----------------
110110
// Type element for a polymorphic type variable
111+
#define DERIVE_ELEM_POLYMORPH struct { \
112+
unsigned int id; \
113+
source_t source; \
114+
strong_cstr_t name; \
115+
bool allow_auto_conversion; \
116+
}
117+
111118
typedef struct {
112-
unsigned int id;
113-
source_t source;
114-
strong_cstr_t name;
115-
bool allow_auto_conversion;
119+
DERIVE_ELEM_POLYMORPH;
116120
} ast_elem_polymorph_t;
117121

118122
// ---------------- ast_elem_polycount_t ----------------
@@ -126,13 +130,10 @@ typedef struct {
126130
// ---------------- ast_elem_polymorph_prereq_t ----------------
127131
// Type element for a polymorphic type variable which only fits
128132
// for structs that match the similarity prerequisite
129-
// NOTE: Must overlap with 'ast_elem_polymorph_t'
133+
// NOTE: Guaranteed to overlap with 'ast_elem_polymorph_t'
130134
typedef struct {
131-
unsigned int id;
132-
source_t source;
133-
strong_cstr_t name;
134-
bool allow_auto_conversion;
135-
// ----------------------------
135+
DERIVE_ELEM_POLYMORPH;
136+
136137
strong_cstr_t similarity_prerequisite;
137138
} ast_elem_polymorph_prereq_t;
138139

include/UTIL/ground.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ typedef struct {
107107
} lenstr_t, strong_lenstr_t, weak_lenstr_t;
108108

109109
inline bool lenstreq(lenstr_t a, lenstr_t b){
110-
return a.length == b.length ? memcmp(a.cstr, b.cstr, a.length) == 0 : false;
110+
return a.length == b.length && memcmp(a.cstr, b.cstr, a.length) == 0;
111111
}
112112

113113
inline int lenstrcmp(lenstr_t a, lenstr_t b){

include/UTIL/util.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ extern "C" {
2121
#endif
2222
// ----------------------------------------------------------
2323

24+
// ---------------- memclone ----------------
25+
// Clones a section of memory
26+
void *memclone(void *memory, length_t bytes);
27+
2428
// ---------------- expand ----------------
2529
// Expands an array if it won't be able hold new elements
2630
void expand(void **inout_memory, length_t unit_size, length_t length, length_t *inout_capacity,

src/DRVR/config.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ static successful_t config_read_adept_config_value(config_t *config, jsmnh_obj_c
217217
// Since we are using binary file stream mode, don't rely on fprintf
218218
time_t timestamp = time(NULL);
219219
char timestamp_buffer[256];
220-
sprintf(timestamp_buffer, "%zu", (uint64_t) timestamp);
220+
sprintf(timestamp_buffer, "%zu", (size_t) timestamp);
221221
fwrite(timestamp_buffer, 1, strlen(timestamp_buffer), f);
222222

223223
fwrite(buffer.content + last_update.end, 1, buffer.capacity - last_update.end, f);

src/IRGEN/ir_gen_check_prereq.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ static ast_elem_base_t *try_ast_elem_base(ast_elem_t *elem){
3535

3636
static errorcode_t ir_gen_check_prereq_number(ast_elem_t *concrete_elem, bool *out_meets){
3737
ast_elem_base_t *base_elem = try_ast_elem_base(concrete_elem);
38-
*out_meets = base_elem ? typename_builtin_type(base_elem->base) != BUILTIN_TYPE_NONE : false;
38+
*out_meets = base_elem && typename_builtin_type(base_elem->base) != BUILTIN_TYPE_NONE;
3939
return SUCCESS;
4040
}
4141

@@ -49,7 +49,7 @@ static errorcode_t ir_gen_check_prereq_pod(compiler_t *compiler, object_t *objec
4949

5050
static errorcode_t ir_gen_check_prereq_primitive(ast_elem_t *concrete_elem, bool *out_meets){
5151
ast_elem_base_t *base_elem = try_ast_elem_base(concrete_elem);
52-
*out_meets = base_elem ? typename_is_extended_builtin_type(base_elem->base) : false;
52+
*out_meets = base_elem && typename_is_extended_builtin_type(base_elem->base);
5353
return SUCCESS;
5454
}
5555

src/IRGEN/ir_gen_polymorphable.c

Lines changed: 50 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,32 @@
1616
#include "UTIL/color.h"
1717
#include "UTIL/ground.h"
1818

19+
static errorcode_t enforce_polymorph(
20+
compiler_t *compiler,
21+
object_t *object,
22+
ast_poly_catalog_t *catalog,
23+
ast_elem_polymorph_t *polymorph_elem,
24+
ast_poly_catalog_type_t *type_var,
25+
ast_type_t *concrete_replacement
26+
){
27+
if(type_var == NULL){
28+
// No existing type variable was found, so add to it to the catalog
29+
ast_poly_catalog_add_type(catalog, polymorph_elem->name, concrete_replacement);
30+
return SUCCESS;
31+
}
32+
33+
if(!ast_types_identical(concrete_replacement, &type_var->binding)){
34+
// Allow built-in auto conversion regardless of 'polymorph_elem->allow_auto_conversion' flag from before v2.6
35+
36+
if(!is_allowed_builtin_auto_conversion(compiler, object, concrete_replacement, &type_var->binding)){
37+
// Given arguments don't meet consistency requirements of type variables
38+
return FAILURE;
39+
}
40+
}
41+
42+
return SUCCESS;
43+
}
44+
1945
static errorcode_t enforce_prereq(
2046
compiler_t *compiler,
2147
object_t *object,
@@ -50,7 +76,7 @@ static errorcode_t enforce_prereq(
5076
ast_poly_catalog_type_t *type_var = ast_poly_catalog_find_type(catalog, prereq->name);
5177

5278
// Determine special allowed auto conversions
53-
if(type_var ? is_allowed_builtin_auto_conversion(compiler, object, &type_var->binding, concrete_type) : false){
79+
if(type_var && is_allowed_builtin_auto_conversion(compiler, object, &type_var->binding, concrete_type)){
5480
return SUCCESS;
5581
}
5682
}
@@ -139,32 +165,24 @@ static errorcode_t ir_gen_polymorphable_elem_prereq(
139165
}
140166

141167
if(enforce_prereq(compiler, object, polymorphic_type, concrete_type, catalog, index)) return FAILURE;
142-
143-
// DANGEROUS: Manually managed AST type with semi-ownership
144-
// DANGEROUS: Potentially bad memory tricks
145-
ast_type_t replacement;
146-
replacement.elements_length = concrete_type->elements_length - index;
147-
replacement.elements = malloc(sizeof(ast_elem_t*) * replacement.elements_length);
148-
memcpy(replacement.elements, &concrete_type->elements[index], sizeof(ast_elem_t*) * replacement.elements_length);
149-
replacement.source = replacement.elements[0]->source;
168+
169+
// DANGEROUS: AST type with semi-ownership
170+
length_t replacement_length = concrete_type->elements_length - index;
171+
172+
ast_type_t replacement = (ast_type_t){
173+
.elements = memclone((void*) &concrete_type->elements[index], sizeof(ast_elem_t*) * replacement_length),
174+
.elements_length = replacement_length,
175+
.source = concrete_type->elements[index]->source,
176+
};
150177

151178
// Ensure consistency with catalog
152179
ast_elem_polymorph_prereq_t *prereq = (ast_elem_polymorph_prereq_t*) polymorphic_type->elements[index];
153180
ast_poly_catalog_type_t *type_var = ast_poly_catalog_find_type(catalog, prereq->name);
154181

155-
if(type_var){
156-
if(!ast_types_identical(&replacement, &type_var->binding)){
157-
// Given arguments don't meet consistency requirements of type variables
158-
free(replacement.elements);
159-
return FAILURE;
160-
}
161-
} else {
162-
// Add to catalog since it's not already present
163-
ast_poly_catalog_add_type(catalog, prereq->name, &replacement);
164-
}
165-
182+
// Ok since 'ast_elem_polymorph_t' is guaranteed to overlap with 'ast_elem_polymorph_t'
183+
errorcode_t res = enforce_polymorph(compiler, object, catalog, (ast_elem_polymorph_t*) prereq, type_var, &replacement);
166184
free(replacement.elements);
167-
return SUCCESS;
185+
return res;
168186
}
169187

170188
errorcode_t ir_gen_polymorphable(compiler_t *compiler, object_t *object, ast_type_t *polymorphic_type, ast_type_t *concrete_type, ast_poly_catalog_t *catalog){
@@ -232,29 +250,22 @@ errorcode_t ir_gen_polymorphable(compiler_t *compiler, object_t *object, ast_typ
232250
return ALT_FAILURE;
233251
}
234252

235-
// DANGEROUS: Manually managed AST type with semi-ownership
236-
// DANGEROUS: Potentially bad memory tricks
237-
ast_type_t replacement;
238-
replacement.elements_length = concrete_type->elements_length - i;
239-
replacement.elements = malloc(sizeof(ast_elem_t*) * replacement.elements_length);
240-
memcpy(replacement.elements, &concrete_type->elements[i], sizeof(ast_elem_t*) * replacement.elements_length);
241-
replacement.source = replacement.elements[0]->source;
253+
// DANGEROUS: AST type with semi-ownership
254+
length_t replacement_length = concrete_type->elements_length - i;
255+
256+
ast_type_t replacement = (ast_type_t){
257+
.elements = memclone(&concrete_type->elements[i], sizeof(ast_elem_t*) * replacement_length),
258+
.elements_length = replacement_length,
259+
.source = concrete_type->elements[i]->source,
260+
};
242261

243262
// Ensure consistency with catalog
244263
ast_elem_polymorph_t *polymorphic_elem = (ast_elem_polymorph_t*) polymorphic_type->elements[i];
245264
ast_poly_catalog_type_t *type_var = ast_poly_catalog_find_type(catalog, polymorphic_elem->name);
246265

247-
if(type_var){
248-
if(!ast_types_identical(&replacement, &type_var->binding)){
249-
if(!polymorphic_elem->allow_auto_conversion || !is_allowed_builtin_auto_conversion(compiler, object, &replacement, &type_var->binding)){
250-
// Given arguments don't meet consistency requirements of type variables
251-
free(replacement.elements);
252-
return FAILURE;
253-
}
254-
}
255-
} else {
256-
// Add to catalog since it's not already present
257-
ast_poly_catalog_add_type(catalog, polymorphic_elem->name, &replacement);
266+
if(enforce_polymorph(compiler, object, catalog, polymorphic_elem, type_var, &replacement)){
267+
free(replacement.elements);
268+
return FAILURE;
258269
}
259270

260271
i = concrete_type->elements_length - 1;

src/PARSE/parse_type.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,9 @@ errorcode_t parse_type(parse_ctx_t *ctx, ast_type_t *out_type){
167167
// If polymorph tokens starts with tilde, then we allow auto conversion
168168
if(name[0] == '~'){
169169
allow_auto_conversion = true;
170-
memmove(name, &name[1], strlen(name) /* - 1 + 1*/);
170+
memmove(name, &name[1], strlen(name)); // (includes '\0')
171171
}
172-
172+
173173
if(tokens[*i].id == TOKEN_BIT_COMPLEMENT){
174174
if(!ctx->allow_polymorphic_prereqs){
175175
free(name);

src/UTIL/util.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
#include "UTIL/ground.h"
1414
#include "UTIL/util.h"
1515

16+
void *memclone(void *memory, length_t bytes){
17+
return memcpy(malloc(bytes), memory, bytes);
18+
}
19+
1620
void expand(void **inout_memory, length_t unit_size, length_t length, length_t *inout_capacity, length_t amount, length_t default_capacity){
1721
// Expands an array in memory to be able to fit more units
1822

todolists/2.6.todolist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ LOW-PRIORITY:
5353
#end
5454
}
5555
```
56-
* fix issues with __assign__ auto-generation broken in b32ccdb5d397d645a0f4c65de0bfbc0eff38c61e
56+
* make call to functions like `max($T, $T) $T` allow built-in auto conversions between primitives for arguments
5757

5858
v2.4 COMPLETED:
5959
+ Standard Library Imports

0 commit comments

Comments
 (0)