Baby steps struct polymorphs
This commit is contained in:
@@ -302,7 +302,7 @@ intern_string(Intern_Table *t, String string) {
|
||||
//-----------------------------------------------------------------------------
|
||||
// Array List
|
||||
//-----------------------------------------------------------------------------
|
||||
const int LIST_DEFAULT_BLOCK_SIZE = 32;
|
||||
const int LIST_DEFAULT_BLOCK_SIZE = 16;
|
||||
const int LIST_DEFAULT_ALLOCATION_MUL = 2;
|
||||
|
||||
template <class T>
|
||||
|
||||
15
core_ast.cpp
15
core_ast.cpp
@@ -20,6 +20,17 @@ _ast_new(size_t size, Ast_Kind kind, Token *pos, Ast_Flag flags = 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
CORE_Static void
|
||||
propagate_polymorphic(Ast *to, Ast *from) {
|
||||
if (is_flag_set(from->flags, AST_IDENT_POLYMORPH)) set_flag(to->flags, AST_IDENT_POLYMORPH);
|
||||
if (is_flag_set(from->flags, AST_TYPE_POLYMORPH)) set_flag(to->flags, AST_TYPE_POLYMORPH);
|
||||
}
|
||||
|
||||
CORE_Static void
|
||||
propagate_polymorphic(Ast *to, Token *from) {
|
||||
if (from->kind == TK_Polymorph) set_flag(to->flags, AST_IDENT_POLYMORPH);
|
||||
}
|
||||
|
||||
CORE_Static Ast_Atom *
|
||||
ast_str(Token *pos, Intern_String string) {
|
||||
AST_NEW(Atom, VALUE, pos, AST_EXPR | AST_ATOM);
|
||||
@@ -214,11 +225,13 @@ finalize_stmt_scope(Ast_Scope *scope) {
|
||||
}
|
||||
|
||||
CORE_Static Ast_Decl *
|
||||
ast_struct(Token *pos, Ast_Scope *scope, Ast_Kind kind = AST_STRUCT) {
|
||||
ast_struct(Token *pos, Ast_Scope *scope, Ast_Kind kind, Array<Ast_Decl *> polymorph_parameters) {
|
||||
assert(kind == AST_STRUCT || kind == AST_UNION);
|
||||
AST_NEW(Decl, STRUCT, pos, AST_DECL | AST_AGGREGATE);
|
||||
result->kind = kind;
|
||||
result->scope = scope;
|
||||
result->polymorph_parameters = polymorph_parameters;
|
||||
if (polymorph_parameters.len) set_flag(result->flags, AST_POLYMORPH);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -348,19 +348,22 @@ enum Ast_Kind : uint32_t {
|
||||
|
||||
typedef uint32_t Ast_Flag;
|
||||
enum {
|
||||
AST_EXPR = 1ull << 1,
|
||||
AST_STMT = 1ull << 2,
|
||||
AST_STRICT = 1ull << 3,
|
||||
AST_AGGREGATE = 1ull << 4,
|
||||
AST_AGGREGATE_CHILD = 1ull << 5,
|
||||
AST_ATOM = 1ull << 7,
|
||||
AST_FOREIGN = 1ull << 8,
|
||||
AST_DECL = 1ull << 9,
|
||||
AST_GLOBAL = 1ull << 10,
|
||||
AST_FLAG = 1ull << 11,
|
||||
AST_VAR_IS_CONST = 1ull << 12,
|
||||
AST_OPERATOR_OVERLOAD = 1ull << 13,
|
||||
AST_IS_LVALUE = 1ull << 14,
|
||||
AST_EXPR = 1 << 1,
|
||||
AST_STMT = 1 << 2,
|
||||
AST_STRICT = 1 << 3,
|
||||
AST_AGGREGATE = 1 << 4,
|
||||
AST_AGGREGATE_CHILD = 1 << 5,
|
||||
AST_ATOM = 1 << 7,
|
||||
AST_FOREIGN = 1 << 8,
|
||||
AST_DECL = 1 << 9,
|
||||
AST_GLOBAL = 1 << 10,
|
||||
AST_FLAG = 1 << 11,
|
||||
AST_VAR_IS_CONST = 1 << 12,
|
||||
AST_OPERATOR_OVERLOAD = 1 << 13,
|
||||
AST_IS_LVALUE = 1 << 14,
|
||||
AST_IDENT_POLYMORPH = 1 << 15,
|
||||
AST_TYPE_POLYMORPH = 1 << 16,
|
||||
AST_POLYMORPH = AST_IDENT_POLYMORPH | AST_TYPE_POLYMORPH,
|
||||
};
|
||||
|
||||
struct Ast {
|
||||
@@ -599,6 +602,7 @@ struct Ast_Decl : Ast {
|
||||
|
||||
uint64_t operator_overload_arguments_hash;
|
||||
Ast_Operator_Info *overload_op_info;
|
||||
Array<Ast_Decl *> polymorph_parameters;
|
||||
|
||||
Ast_Scope *scope;
|
||||
Ast_Expr *typespec;
|
||||
|
||||
@@ -457,22 +457,26 @@ parse_stmt_scope(Ast_Scope *scope_defined_outside = 0) {
|
||||
return scope;
|
||||
}
|
||||
|
||||
CORE_Static Ast_Lambda *
|
||||
parse_lambda(Token *token) {
|
||||
Scratch_Scope scratch(pctx->scratch);
|
||||
|
||||
Array<Ast_Decl *> params = {scratch.arena};
|
||||
CORE_Static Array<Ast_Decl *>
|
||||
parse_parameter_list(Arena *arena) {
|
||||
Array<Ast_Decl *> params = {arena};
|
||||
if (!token_is(TK_CloseParen)) {
|
||||
for (;;) {
|
||||
Token *name = token_get();
|
||||
if (token_match(TK_Identifier)) {
|
||||
if (name->kind == TK_Identifier || name->kind == TK_Polymorph) {
|
||||
token_next();
|
||||
token_expect(TK_Colon);
|
||||
|
||||
Ast_Decl *param = ast_new(Ast_Decl, AST_VAR, name, AST_DECL);
|
||||
param->name = name->intern_val;
|
||||
|
||||
param->typespec = parse_expr();
|
||||
if (token_match(TK_Assign))
|
||||
|
||||
propagate_polymorphic(param, param->typespec);
|
||||
propagate_polymorphic(param, name);
|
||||
|
||||
if (token_match(TK_Assign)) {
|
||||
param->expr = parse_expr();
|
||||
}
|
||||
|
||||
params.add(param);
|
||||
}
|
||||
@@ -483,7 +487,14 @@ parse_lambda(Token *token) {
|
||||
}
|
||||
}
|
||||
token_expect(TK_CloseParen);
|
||||
return params;
|
||||
}
|
||||
|
||||
CORE_Static Ast_Lambda *
|
||||
parse_lambda(Token *token) {
|
||||
Scratch_Scope scratch(pctx->scratch);
|
||||
|
||||
Array<Ast_Decl *> params = parse_parameter_list(scratch.arena);
|
||||
Array<Ast_Expr *> ret = {scratch.arena};
|
||||
if (token_match(TK_Colon)) {
|
||||
do {
|
||||
@@ -588,18 +599,26 @@ parse_expr(S64 min_bp) {
|
||||
switch (token->kind) {
|
||||
case TK_StringLit: left = ast_str(token, token->intern_val); break;
|
||||
case TK_Identifier: left = ast_ident(token, token->intern_val); break;
|
||||
case TK_Polymorph: left = ast_ident(token, token->intern_val); break;
|
||||
case TK_Integer: left = ast_int(token, token->int_val); break;
|
||||
case TK_UnicodeLit: left = ast_int(token, token->unicode); break;
|
||||
case TK_Float: left = ast_float(token, token->f64_val); break;
|
||||
case TK_Pointer: left = ast_expr_unary(token, TK_Pointer, parse_expr(prefix_bp.right)); break;
|
||||
case TK_Dereference: left = ast_expr_unary(token, TK_Dereference, parse_expr(prefix_bp.right)); break;
|
||||
case TK_Sub: left = ast_expr_unary(token, TK_Sub, parse_expr(prefix_bp.right)); break;
|
||||
case TK_Add: left = ast_expr_unary(token, TK_Add, parse_expr(prefix_bp.right)); break;
|
||||
case TK_Not: left = ast_expr_unary(token, TK_Not, parse_expr(prefix_bp.right)); break;
|
||||
case TK_Neg: left = ast_expr_unary(token, TK_Neg, parse_expr(prefix_bp.right)); break;
|
||||
case TK_Increment: left = ast_expr_unary(token, TK_Increment, parse_expr(prefix_bp.right)); break;
|
||||
case TK_Decrement: left = ast_expr_unary(token, TK_Decrement, parse_expr(prefix_bp.right)); break;
|
||||
case TK_Dereference: left = ast_expr_unary(token, TK_Dereference, parse_expr(prefix_bp.right)); break;
|
||||
|
||||
// Pointer typespec
|
||||
case TK_Pointer: {
|
||||
left = ast_expr_unary(token, TK_Pointer, parse_expr(prefix_bp.right));
|
||||
auto unary = (Ast_Unary *)left;
|
||||
propagate_polymorphic(unary, unary->expr);
|
||||
} break;
|
||||
|
||||
// Array typespec
|
||||
case TK_OpenBracket: {
|
||||
Ast_Expr *expr = 0;
|
||||
if (!token_is(TK_CloseBracket))
|
||||
@@ -608,14 +627,17 @@ parse_expr(S64 min_bp) {
|
||||
Ast_Array *result = ast_array(token, expr);
|
||||
token_expect(TK_CloseBracket);
|
||||
result->base = parse_expr(prefix_bp.right);
|
||||
propagate_polymorphic(result, result->base);
|
||||
left = result;
|
||||
} break;
|
||||
|
||||
// Compound expression
|
||||
case TK_OpenBrace: {
|
||||
left = parse_expr_call(0, TK_CloseBrace);
|
||||
left->kind = AST_COMPOUND;
|
||||
} break;
|
||||
|
||||
// True, False
|
||||
case TK_Keyword: {
|
||||
if (token->intern_val == pctx->keyword_true)
|
||||
left = ast_bool(token, 1);
|
||||
@@ -695,8 +717,18 @@ CORE_Static Ast_Decl *
|
||||
parse_struct(Token *pos, Ast_Kind kind) {
|
||||
Scratch_Scope scratch(pctx->scratch);
|
||||
|
||||
token_match(OPEN_SCOPE);
|
||||
Array<Ast_Decl *> params = {};
|
||||
if (token_match(TK_OpenParen)) {
|
||||
params = parse_parameter_list(scratch.arena);
|
||||
For(params) {
|
||||
if (!is_flag_set(it->flags, AST_POLYMORPH)) {
|
||||
compiler_error(it->pos, "All struct arguments are required to be polymorphic");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ast_Scope *scope = begin_decl_scope(scratch.arena, token_get());
|
||||
token_match(OPEN_SCOPE);
|
||||
do {
|
||||
Token *token = token_expect(TK_Identifier);
|
||||
token_expect(TK_Colon);
|
||||
@@ -711,7 +743,7 @@ parse_struct(Token *pos, Ast_Kind kind) {
|
||||
token_expect(CLOSE_SCOPE);
|
||||
|
||||
finalize_decl_scope(scope);
|
||||
Ast_Decl *result = ast_struct(pos, scope, kind);
|
||||
Ast_Decl *result = ast_struct(pos, scope, kind, params);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -1141,6 +1141,10 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_and_const_str
|
||||
Ast_Scope *scope = field_access_scope ? field_access_scope : node->parent_scope;
|
||||
Search_Flag flag = field_access_scope ? SEARCH_ONLY_CURRENT_SCOPE : 0;
|
||||
|
||||
if (!string_compare(ast->pos->file.s, "Language.core"_s)) { // @debug
|
||||
int a = 10;
|
||||
}
|
||||
|
||||
Ast_Decl *decl = resolve_name(scope, node->pos, node->intern_val, flag | RESOLVE_NAME_MAKE_SURE_OPERATOR_OVERLOAD_IS_NOT_EVER_CALLED);
|
||||
|
||||
// Substitute lambda alias
|
||||
|
||||
@@ -5,11 +5,6 @@ PushStruct :: (a: *MA.Arena, $T: Type): *$T
|
||||
result := PushSize(a, size)
|
||||
return result
|
||||
|
||||
Array :: struct($T: Type)
|
||||
data: *T
|
||||
len: int
|
||||
cap: int
|
||||
|
||||
Array(int)
|
||||
|
||||
QueueAddSLL(list: $List, node: $Node, first: #Identifier = first, last: #Identifier = last, next: #Identifier = next)
|
||||
@@ -24,6 +19,10 @@ QueueAddSLL(list: $List, node: $Node, $first = first, $last = last, $next = next
|
||||
|
||||
*/
|
||||
|
||||
Array :: struct($T: Type)
|
||||
data: *T
|
||||
len: int
|
||||
cap: int
|
||||
|
||||
main :: (argc: int, argv: **char): int
|
||||
$i := 10
|
||||
return 0
|
||||
Reference in New Issue
Block a user