Skip to content

Commit 734abf6

Browse files
committed
Built initial foundation for polymorphism
1 parent 4803a7c commit 734abf6

File tree

21 files changed

+296
-27
lines changed

21 files changed

+296
-27
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ CFLAGS=-c -Wall -I"include" $(LLVM_INCLUDE_FLAGS) -std=c99 -O0 -DNDEBUG # -fmax-
8484
ADDITIONAL_DEBUG_CFLAGS=-DENABLE_DEBUG_FEATURES -g # -fprofile-instr-generate -fcoverage-mapping
8585
LDFLAGS=$(LLVM_LINKER_FLAGS) # -fprofile-instr-generate
8686
SOURCES= src/AST/ast_expr.c src/AST/ast_type.c src/AST/ast.c src/AST/meta_directives.c src/BKEND/backend.c src/BKEND/ir_to_llvm.c src/BRIDGE/any.c src/BRIDGE/bridge.c src/BRIDGE/type_table.c \
87-
src/BRIDGE/rtti.c src/DRVR/compiler.c src/DRVR/main.c src/DRVR/object.c src/INFER/infer.c src/IR/ir_pool.c src/IR/ir_type.c src/IR/ir.c src/IRGEN/ir_builder.c \
87+
src/BRIDGE/rtti.c src/DRVR/compiler.c src/DRVR/main.c src/DRVR/object.c src/INFER/infer.c src/IR/ir_pool.c src/IR/ir_type_var.c src/IR/ir_type.c src/IR/ir.c src/IRGEN/ir_builder.c \
8888
src/IRGEN/ir_gen_expr.c src/IRGEN/ir_gen_find.c src/IRGEN/ir_gen_stmt.c src/IRGEN/ir_gen_type.c src/IRGEN/ir_gen.c \
8989
src/LEX/lex.c src/LEX/pkg.c src/LEX/token.c src/PARSE/parse_alias.c src/PARSE/parse_ctx.c src/PARSE/parse_dependency.c src/PARSE/parse_enum.c src/PARSE/parse_expr.c src/PARSE/parse_func.c src/PARSE/parse_global.c src/PARSE/parse_meta.c src/PARSE/parse_pragma.c \
9090
src/PARSE/parse_stmt.c src/PARSE/parse_struct.c src/PARSE/parse_type.c src/PARSE/parse_util.c src/PARSE/parse.c src/UTIL/color.c src/UTIL/builtin_type.c src/UTIL/filename.c src/UTIL/levenshtein.c src/UTIL/memory.c src/UTIL/search.c src/UTIL/util.c

include/AST/ast.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,11 @@ typedef struct {
4040
#define AST_FUNC_ARG_TYPE_TRAIT_POD TRAIT_1
4141

4242
// Possible AST function traits
43-
#define AST_FUNC_FOREIGN TRAIT_1
44-
#define AST_FUNC_VARARG TRAIT_2
45-
#define AST_FUNC_MAIN TRAIT_3
46-
#define AST_FUNC_STDCALL TRAIT_4
43+
#define AST_FUNC_FOREIGN TRAIT_1
44+
#define AST_FUNC_VARARG TRAIT_2
45+
#define AST_FUNC_MAIN TRAIT_3
46+
#define AST_FUNC_STDCALL TRAIT_4
47+
#define AST_FUNC_POLYMORPHIC TRAIT_5
4748

4849
// ---------------- ast_struct_t ----------------
4950
// A structure within the root AST
@@ -180,6 +181,10 @@ void ast_dump_enums(FILE *file, ast_enum_t *enums, length_t enums_length);
180181
// Fills out a blank template for a new function
181182
void ast_func_create_template(ast_func_t *func, strong_cstr_t name, bool is_stdcall, bool is_foreign, source_t source);
182183

184+
// ---------------- ast_func_is_polymorphic ----------------
185+
// Returns whether an AST function has polymorphic arguments
186+
bool ast_func_is_polymorphic(ast_func_t *func);
187+
183188
// ---------------- ast_struct_init ----------------
184189
// Initializes an AST struct
185190
void ast_struct_init(ast_struct_t *structure, strong_cstr_t name, strong_cstr_t *names, ast_type_t *types,

include/AST/ast_type.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ extern "C" {
2929
#define AST_ELEM_GENERIC_INT 0x05
3030
#define AST_ELEM_GENERIC_FLOAT 0x06
3131
#define AST_ELEM_FUNC 0x07
32+
#define AST_ELEM_POLYMORPH 0x08
3233

3334
// Possible data flow patterns
3435
#define FLOW_NONE 0x00
@@ -94,6 +95,14 @@ typedef struct {
9495
bool ownership; // Whether or not we own our members
9596
} ast_elem_func_t;
9697

98+
// ---------------- ast_elem_polymorph_t ----------------
99+
// Type element for a polymorphic type variable
100+
typedef struct {
101+
unsigned int id;
102+
source_t source;
103+
strong_cstr_t name;
104+
} ast_elem_polymorph_t;
105+
97106
// ---------------- ast_unnamed_arg_t ----------------
98107
// Data structure for an unnamed argument
99108
typedef struct {
@@ -180,6 +189,10 @@ bool ast_type_is_base_ptr_of(const ast_type_t *type, const char *base);
180189
// Returns whether an AST type is a pointer to another AST type
181190
bool ast_type_is_pointer_to(const ast_type_t *type, const ast_type_t *to);
182191

192+
// ---------------- ast_type_has_polymorph ----------------
193+
// Returns whether an AST type contains a polymorphic type
194+
bool ast_type_has_polymorph(const ast_type_t *type);
195+
183196
#ifdef __cplusplus
184197
}
185198
#endif

include/IR/ir.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "BRIDGE/bridge.h"
1515
#include "IR/ir_pool.h"
1616
#include "IR/ir_type.h"
17+
#include "IR/ir_type_var.h"
1718

1819
// =============================================================
1920
// ---------------- Possible IR instruction IDs ----------------
@@ -412,9 +413,10 @@ typedef struct {
412413
} ir_func_t;
413414

414415
// Possible traits for ir_func_t
415-
#define IR_FUNC_FOREIGN TRAIT_1
416-
#define IR_FUNC_VARARG TRAIT_2
417-
#define IR_FUNC_STDCALL TRAIT_3
416+
#define IR_FUNC_FOREIGN TRAIT_1
417+
#define IR_FUNC_VARARG TRAIT_2
418+
#define IR_FUNC_STDCALL TRAIT_3
419+
#define IR_FUNC_POLYMORPHIC TRAIT_4
418420

419421
// ---------------- ir_func_mapping_t ----------------
420422
// Mapping for a name or id to AST & IR function
@@ -469,7 +471,7 @@ typedef struct {
469471
// ---------------- ir_shared_common_t ----------------
470472
// General data that can be directly accessed by the
471473
// entire IR module
472-
// 'ir_funcptr_type' -> type used for function pointer implementation
474+
// 'ir_funcptr' -> type used for function pointer implementation
473475
typedef struct {
474476
ir_type_t *ir_funcptr;
475477
ir_type_t *ir_usize;
@@ -496,6 +498,7 @@ typedef struct {
496498
ir_anon_global_t *anon_globals;
497499
length_t anon_globals_length;
498500
length_t anon_globals_capacity;
501+
ir_type_var_stack_t type_var_stack;
499502
} ir_module_t;
500503

501504
// ---------------- ir_value_str ----------------
@@ -536,5 +539,4 @@ void ir_module_free(ir_module_t *ir_module);
536539
// Frees data within each IR function in a list
537540
void ir_module_free_funcs(ir_func_t *funcs, length_t funcs_length);
538541

539-
540542
#endif // IR_H

include/IR/ir_type.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ typedef struct ir_type_t ir_type_t;
3737

3838
struct ir_type_t {
3939
unsigned int kind;
40-
void *extra; //
40+
void *extra;
4141
};
4242

4343
// ---------------- ir_type_extra_composite_t ----------------

include/IR/ir_type_var.h

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
2+
#ifndef IR_TYPE_VAR_H
3+
#define IR_TYPE_VAR_H
4+
5+
#include "IR/ir_type.h"
6+
#include "UTIL/ground.h"
7+
8+
// ---------------- ir_type_var_t ----------------
9+
// Polymorphic type variable
10+
typedef struct {
11+
weak_cstr_t name;
12+
ir_type_t *type;
13+
} ir_type_var_t;
14+
15+
// ---------------- ir_type_var_frame_t ----------------
16+
// Polymorphic type variable stack frame
17+
typedef struct {
18+
ir_type_var_t *type_vars;
19+
length_t type_vars_length;
20+
length_t type_vars_capacity;
21+
} ir_type_var_frame_t;
22+
23+
// ---------------- ir_type_var_stack_t ----------------
24+
// Polymorphic type variable stack
25+
typedef struct {
26+
ir_type_var_frame_t *frames;
27+
length_t frames_length;
28+
length_t frames_capacity;
29+
} ir_type_var_stack_t;
30+
31+
// ---------------- ir_type_var_stack_init ----------------
32+
// Initializes a type variable stack
33+
void ir_type_var_stack_init(ir_type_var_stack_t *stack);
34+
35+
// ---------------- ir_type_var_stack_free ----------------
36+
// Frees a type variable stack
37+
void ir_type_var_stack_free(ir_type_var_stack_t *stack);
38+
39+
// ---------------- ir_type_var_stack_open ----------------
40+
// Opens a new frame in a type variable stack
41+
void ir_type_var_stack_open(ir_type_var_stack_t *stack);
42+
43+
// ---------------- ir_type_var_stack_close ----------------
44+
// Closes the previous frame in a type variable stack
45+
void ir_type_var_stack_close(ir_type_var_stack_t *stack);
46+
47+
// ---------------- ir_type_var_stack_add ----------------
48+
// Adds a type variable to the current stack frame
49+
// NOTE: Returns successful if there weren't any name collisions within
50+
// the current stack frame and the type was added successfully
51+
successful_t ir_type_var_stack_add(ir_type_var_stack_t *stack, ir_type_var_t type_var);
52+
53+
// ---------------- ir_type_var_frame_find ----------------
54+
// Finds a type variable within a single stack frame
55+
// NOTE: Returns NULL if non-existent
56+
ir_type_var_t *ir_type_var_frame_find(ir_type_var_frame_t *frame, weak_cstr_t name);
57+
58+
// ---------------- ir_type_var_stack_find ----------------
59+
// Finds a type variable within a type variable stack
60+
// NOTE: Returns NULL if non-existent
61+
ir_type_var_t *ir_type_var_stack_find(ir_type_var_stack_t *stack, weak_cstr_t name);
62+
63+
#endif // IR_TYPE_VAR_H

include/LEX/lex.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ typedef struct {
5252
#define LEX_STATE_UBEROR 0x00000013
5353
#define LEX_STATE_COLON 0x00000014
5454
#define LEX_STATE_META 0x00000015
55+
#define LEX_STATE_POLYMORPH 0x00000016
5556

5657
// ---------------- lex ----------------
5758
// Entry point for lexical analysis

include/LEX/token.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ extern "C" {
2222
or other cases where it is necessary to break off into a new interation version.
2323
(Used for compatibility checking with pre-lexed libraries)
2424
*/
25-
#define TOKEN_ITERATION_VERSION 0x0000000C
25+
#define TOKEN_ITERATION_VERSION 0x0000000D
2626

2727
typedef unsigned short tokenid_t;
2828

@@ -124,7 +124,8 @@ extern const char *global_token_name_table[];
124124
#define TOKEN_BIT_LGC_RSHIFT 0x00000037
125125
#define TOKEN_NAMESPACE 0x00000038
126126
#define TOKEN_META 0x00000039
127-
// 3A..3F
127+
#define TOKEN_POLYMORPH 0x0000003A
128+
// 3B..3F
128129

129130
// NOTE: 0x00000040 .. 0x0000006F reserved for keywords
130131
// Keywords are organized as such that 0x00000040 + the id of

src/AST/ast.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,13 @@ void ast_func_create_template(ast_func_t *func, strong_cstr_t name, bool is_stdc
489489
if(is_foreign) func->traits |= AST_FUNC_FOREIGN;
490490
}
491491

492+
bool ast_func_is_polymorphic(ast_func_t *func){
493+
for(length_t i = 0; i != func->arity; i++){
494+
if(ast_type_has_polymorph(&func->arg_types[i])) return true;
495+
}
496+
return false;
497+
}
498+
492499
void ast_struct_init(ast_struct_t *structure, strong_cstr_t name, strong_cstr_t *names, ast_type_t *types,
493500
length_t length, trait_t traits, source_t source){
494501
structure->name = name;

src/AST/ast_type.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,17 @@ ast_type_t ast_type_clone(const ast_type_t *original){
5959
((ast_elem_func_t*) new.elements[i])->traits = ((ast_elem_func_t*) original->elements[i])->traits;
6060
((ast_elem_func_t*) new.elements[i])->ownership = false;
6161
break;
62+
case AST_ELEM_POLYMORPH: {
63+
char *original_name = ((ast_elem_polymorph_t*) original->elements[i])->name;
64+
length_t original_name_length = strlen(original_name);
65+
char *new_name = malloc(original_name_length + 1);
66+
memcpy(new_name, original_name, original_name_length + 1);
67+
new.elements[i] = malloc(sizeof(ast_elem_polymorph_t));
68+
((ast_elem_polymorph_t*) new.elements[i])->id = AST_ELEM_POLYMORPH;
69+
((ast_elem_polymorph_t*) new.elements[i])->source = original->elements[i]->source;
70+
((ast_elem_polymorph_t*) new.elements[i])->name = new_name;
71+
break;
72+
}
6273
default:
6374
redprintf("INTERNAL ERROR: Encountered unexpected type element id when cloning ast_type_t, a crash will probably follow...\n");
6475
}
@@ -91,6 +102,10 @@ void ast_type_free(ast_type_t *type){
91102
}
92103
free(type->elements[i]);
93104
break;
105+
case AST_ELEM_POLYMORPH:
106+
free(((ast_elem_polymorph_t*) type->elements[i])->name);
107+
free(type->elements[i]);
108+
break;
94109
default:
95110
redprintf("INTERNAL ERROR: Encountered unexpected type element id when freeing ast_type_t\n");
96111
}
@@ -180,6 +195,18 @@ void ast_type_prepend_ptr(ast_type_t *type){
180195
type->elements_length++;
181196
}
182197

198+
void ast_type_make_polymorph(ast_type_t *type, strong_cstr_t name){
199+
ast_elem_polymorph_t *elem = malloc(sizeof(ast_elem_polymorph_t));
200+
elem->id = AST_ELEM_POLYMORPH;
201+
elem->name = name;
202+
elem->source = NULL_SOURCE;
203+
204+
type->elements = malloc(sizeof(ast_elem_t*));
205+
type->elements[0] = (ast_elem_t*) elem;
206+
type->elements_length = 1;
207+
type->source = NULL_SOURCE;
208+
}
209+
183210
void ast_type_make_generic_int(ast_type_t *type){
184211
ast_elem_base_t *elem = malloc(sizeof(ast_elem_t));
185212
elem->id = AST_ELEM_GENERIC_INT;
@@ -307,6 +334,15 @@ strong_cstr_t ast_type_str(const ast_type_t *type){
307334
free(type_str);
308335
}
309336
break;
337+
case AST_ELEM_POLYMORPH: {
338+
const char *polyname = ((ast_elem_polymorph_t*) type->elements[i])->name;
339+
length_t polyname_length = strlen(polyname);
340+
EXTEND_NAME_MACRO(polyname_length + 1);
341+
name[name_length] = '$';
342+
memcpy(&name[name_length + 1], polyname, polyname_length + 1);
343+
name_length += polyname_length + 1;
344+
}
345+
break;
310346
default:
311347
printf("INTERNAL ERROR: Encountered unexpected element type 0x%08X when converting ast_type_t to a string\n", type->elements[i]->id);
312348
return NULL;
@@ -415,3 +451,29 @@ bool ast_type_is_pointer_to(const ast_type_t *type, const ast_type_t *to){
415451

416452
return ast_types_identical(&stripped, to);
417453
}
454+
455+
bool ast_type_has_polymorph(const ast_type_t *type){
456+
for(length_t i = 0; i != type->elements_length; i++){
457+
switch(type->elements[i]->id){
458+
case AST_ELEM_BASE:
459+
case AST_ELEM_POINTER:
460+
case AST_ELEM_GENERIC_INT:
461+
case AST_ELEM_GENERIC_FLOAT:
462+
case AST_ELEM_FIXED_ARRAY:
463+
break;
464+
case AST_ELEM_FUNC: {
465+
ast_elem_func_t *func_elem = (ast_elem_func_t*) type->elements[i];
466+
for(length_t i = 0; i != func_elem->arity; i++){
467+
if(ast_type_has_polymorph(&func_elem->arg_types[i])) return true;
468+
}
469+
if(ast_type_has_polymorph(func_elem->return_type)) return true;
470+
}
471+
break;
472+
case AST_ELEM_POLYMORPH:
473+
return true;
474+
default:
475+
redprintf("INTERNAL ERROR: ast_type_has_polymorph encountered unknown element id 0x%8X", type->elements[i]->id);
476+
}
477+
}
478+
return false;
479+
}

0 commit comments

Comments
 (0)