Assigning to $Type now works.

This commit is contained in:
Christoffer Lerno
2021-07-20 23:36:53 +02:00
parent c149f14a1f
commit 46e39f883c
7 changed files with 59 additions and 3 deletions

View File

@@ -115,19 +115,19 @@ to C3 and compiled with the c3c compiler:
- [x] CT only macros evaluating to constants
- [x] range initializers e.g. `{ [1..2] = 2 }`
- [x] Trailing body macros e.g. `@foo(1, 100; int a) { bar(a); };`
- [x] Complex macros
- [ ] Anonymous structs
- [ ] Complete C ABI conformance *in progress*
- [ ] Debug info *in progress*
- [ ] Virtual type *in progress*
- [ ] Enum associated data support
- [ ] Windows support
- [ ] All attributes
- [ ] Windows support *in progress*
- [ ] All attributes *in progress*
- [ ] Associative array literals
- [ ] CT type constants
- [ ] Reflection methods
- [ ] LTO/ThinLTO setup
- [ ] `global` / `shared` for globals
- [ ] Complex macros
- [ ] Escape macros
- [ ] Implicit capturing macros
- [ ] Subarray initializers

View File

@@ -581,6 +581,9 @@ void fprint_expr_recursive(Context *context, FILE *file, Expr *expr, int indent)
if (!expr) return;
switch (expr->expr_kind)
{
case EXPR_NOP:
DUMP("(nop)");
return;
case EXPR_FLATPATH:
DUMP("(idents)");
return;

View File

@@ -75,6 +75,7 @@ Expr *copy_expr(Expr *source_expr)
UNREACHABLE
case EXPR_FLATPATH:
case EXPR_UNDEF:
case EXPR_NOP:
return expr;
case EXPR_CT_CALL:
MACRO_COPY_EXPR_LIST(expr->ct_call_expr.arguments);

View File

@@ -214,6 +214,7 @@ typedef enum
EXPR_UNARY,
EXPR_UNDEF,
EXPR_CT_CALL,
EXPR_NOP,
} ExprKind;
typedef enum

View File

@@ -3177,6 +3177,8 @@ void llvm_emit_expr(GenContext *c, BEValue *value, Expr *expr)
case EXPR_CATCH:
gencontext_emit_trycatch_expr(c, value, expr);
return;
case EXPR_NOP:
return;
case EXPR_ELSE:
gencontext_emit_else_expr(c, value, expr);
return;

View File

@@ -3357,6 +3357,43 @@ static bool sema_expr_analyse_ct_identifier_assign(Context *context, Expr *expr,
return true;
}
static bool sema_expr_analyse_ct_type_identifier_assign(Context *context, Expr *expr, Expr *left, Expr *right)
{
TypeInfo *info = left->type_expr;
if (info->kind != TYPE_INFO_IDENTIFIER || info->unresolved.path || TOKTYPE(info->unresolved.name_loc) != TOKEN_CT_TYPE_IDENT)
{
SEMA_ERROR(left, "A type cannot be assigned to.");
return false;
}
TokenId token = info->unresolved.name_loc;
if (!sema_analyse_expr_value(context, NULL, right)) return false;
if (right->expr_kind != EXPR_TYPEINFO)
{
SEMA_ERROR(right, "Expected a type here.");
return false;
}
Decl *decl = sema_resolve_normal_symbol(context, token, NULL, false);
if (!decl)
{
decl = decl_new(DECL_VAR, token, VISIBLE_LOCAL);
decl->var.kind = VARDECL_LOCAL_CT_TYPE;
if (!sema_add_local(context, decl)) return false;
}
decl = sema_resolve_normal_symbol(context, token, NULL, true);
decl->var.init_expr = right;
expr->expr_kind = EXPR_NOP;
expr->type = type_void;
return true;
}
/**
* Analyse a = b
@@ -3372,6 +3409,11 @@ static bool sema_expr_analyse_assign(Context *context, Expr *expr, Expr *left, E
{
return sema_expr_analyse_ct_identifier_assign(context, expr, left, right);
}
if (left->expr_kind == EXPR_TYPEINFO)
{
return sema_expr_analyse_ct_type_identifier_assign(context, expr, left, right);
}
if (!sema_analyse_expr_value(context, NULL, left)) return false;
// 2. Check assignability
@@ -3442,6 +3484,7 @@ static bool sema_expr_analyse_common_assign(Context *context, Expr *expr, Expr *
{
return sema_expr_analyse_ct_common_assign(context, expr, left);
}
// 1. Analyse left side.
if (!sema_analyse_expr_value(context, NULL, left)) return false;
@@ -5690,6 +5733,7 @@ static inline bool sema_analyse_expr_dispatch(Context *context, Type *to, Expr *
case EXPR_DESIGNATOR:
case EXPR_MACRO_BODY_EXPANSION:
case EXPR_FLATPATH:
case EXPR_NOP:
UNREACHABLE
case EXPR_CT_CALL:
return sema_expr_analyse_ct_call(context, to, expr);

View File

@@ -31,3 +31,8 @@ func void test21()
int b = 2;
a++ = b++; // #error: Expression is not assignable
}
func void test22()
{
$Type = int;
}