mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Assigning to $Type now works.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -214,6 +214,7 @@ typedef enum
|
||||
EXPR_UNARY,
|
||||
EXPR_UNDEF,
|
||||
EXPR_CT_CALL,
|
||||
EXPR_NOP,
|
||||
} ExprKind;
|
||||
|
||||
typedef enum
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -31,3 +31,8 @@ func void test21()
|
||||
int b = 2;
|
||||
a++ = b++; // #error: Expression is not assignable
|
||||
}
|
||||
|
||||
func void test22()
|
||||
{
|
||||
$Type = int;
|
||||
}
|
||||
Reference in New Issue
Block a user