Baby steps struct polymorphs

This commit is contained in:
Krzosa Karol
2023-03-29 21:36:26 +02:00
parent 58a46b46e6
commit 21c8ceff03
6 changed files with 85 additions and 33 deletions

View File

@@ -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;
}