mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 03:51:18 +00:00
Compile time type assignment (eg $Foo = int) is no longer an expression.
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
- Allow generics over distinct types #2216.
|
||||
- Support distrinct types as the base type of bitstructs. #2218
|
||||
- Add hash::sha512 module to stdlib. #2227
|
||||
- Compile time type assignment (eg `$Foo = int`) is no longer an expression.
|
||||
|
||||
### Fixes
|
||||
- `-2147483648`, MIN literals work correctly.
|
||||
|
||||
@@ -772,6 +772,7 @@ static void c_emit_stmt(GenContext *c, Ast *stmt)
|
||||
case AST_CT_FOR_STMT:
|
||||
case AST_CT_IF_STMT:
|
||||
case AST_CT_SWITCH_STMT:
|
||||
case AST_CT_TYPE_ASSIGN_STMT:
|
||||
UNREACHABLE
|
||||
case AST_DECLARE_STMT:
|
||||
{
|
||||
|
||||
@@ -1359,6 +1359,12 @@ typedef struct
|
||||
} AstCtSwitchStmt;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *var_name;
|
||||
Expr *type_expr;
|
||||
} AstCtTypeAssignStmt;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DeclId index;
|
||||
@@ -1500,6 +1506,7 @@ typedef struct Ast_
|
||||
AstContractStmt contract_stmt; // 32
|
||||
AstDocFault contract_fault; // 24
|
||||
AstId ct_else_stmt; // 4
|
||||
AstCtTypeAssignStmt ct_type_assign_stmt;
|
||||
AstCtForeachStmt ct_foreach_stmt; // 40
|
||||
AstCtIfStmt ct_if_stmt; // 24
|
||||
AstCtSwitchStmt ct_switch_stmt; // 16
|
||||
|
||||
@@ -643,6 +643,9 @@ RETRY:
|
||||
{
|
||||
case AST_POISONED:
|
||||
break;
|
||||
case AST_CT_TYPE_ASSIGN_STMT:
|
||||
MACRO_COPY_EXPR(ast->ct_type_assign_stmt.type_expr);
|
||||
break;
|
||||
case AST_DECLS_STMT:
|
||||
MACRO_COPY_DECL_LIST(ast->decls_stmt);
|
||||
break;
|
||||
|
||||
@@ -208,6 +208,7 @@ typedef enum
|
||||
AST_CT_FOR_STMT,
|
||||
AST_CT_IF_STMT,
|
||||
AST_CT_SWITCH_STMT,
|
||||
AST_CT_TYPE_ASSIGN_STMT,
|
||||
AST_DECLARE_STMT,
|
||||
AST_DECLS_STMT,
|
||||
AST_DEFAULT_STMT,
|
||||
@@ -1629,7 +1630,7 @@ typedef enum
|
||||
#define CT_AST \
|
||||
AST_CT_ASSERT: case AST_CT_ECHO_STMT: case AST_CT_ELSE_STMT: \
|
||||
case AST_CT_FOREACH_STMT: case AST_CT_FOR_STMT: \
|
||||
case AST_CT_IF_STMT: case AST_CT_SWITCH_STMT
|
||||
case AST_CT_IF_STMT: case AST_CT_SWITCH_STMT: case AST_CT_TYPE_ASSIGN_STMT
|
||||
|
||||
// -- Decl helper macros
|
||||
#define NON_TYPE_DECLS DECL_IMPORT: case DECL_MACRO: \
|
||||
|
||||
@@ -965,9 +965,23 @@ static inline Ast *parse_expr_stmt(ParseContext *c)
|
||||
}
|
||||
|
||||
|
||||
static inline Ast *parse_ct_type_assign_stmt(ParseContext *c)
|
||||
{
|
||||
Ast *stmt = new_ast(AST_CT_TYPE_ASSIGN_STMT, c->span);
|
||||
stmt->ct_type_assign_stmt.var_name = symstr(c);
|
||||
advance_and_verify(c, TOKEN_CT_TYPE_IDENT);
|
||||
advance_and_verify(c, TOKEN_EQ);
|
||||
ASSIGN_EXPR_OR_RET(stmt->ct_type_assign_stmt.type_expr, parse_expr(c), poisoned_ast);
|
||||
CONSUME_EOS_OR_RET(poisoned_ast);
|
||||
return stmt;
|
||||
}
|
||||
|
||||
static inline Ast *parse_decl_or_expr_stmt(ParseContext *c)
|
||||
{
|
||||
if (tok_is(c, TOKEN_CT_TYPE_IDENT) && peek(c) == TOKEN_EQ)
|
||||
{
|
||||
return parse_ct_type_assign_stmt(c);
|
||||
}
|
||||
ASSIGN_EXPR_OR_RET(Expr *expr, parse_expr(c), poisoned_ast);
|
||||
// We might be parsing "int!"
|
||||
// If so we need to unwrap this.
|
||||
@@ -1275,9 +1289,9 @@ Ast *parse_stmt(ParseContext *c)
|
||||
return parse_decl_or_expr_stmt(c);
|
||||
case TOKEN_VAR:
|
||||
return parse_var_stmt(c);
|
||||
case TOKEN_TLOCAL: // Global means declaration!
|
||||
case TOKEN_TLOCAL: // Global means declaration!
|
||||
case TOKEN_STATIC: // Static means declaration!
|
||||
case TOKEN_CONST: // Const means declaration!
|
||||
case TOKEN_CONST: // Const means declaration!
|
||||
return parse_declaration_stmt(c);
|
||||
case TOKEN_RETURN:
|
||||
return parse_return_stmt(c);
|
||||
|
||||
@@ -4172,8 +4172,9 @@ static inline bool sema_check_body_const(SemaContext *context, Ast *body)
|
||||
case AST_CT_FOREACH_STMT:
|
||||
case AST_CT_FOR_STMT:
|
||||
case AST_CT_IF_STMT:
|
||||
case AST_CT_SWITCH_STMT:
|
||||
case AST_CT_ELSE_STMT:
|
||||
case AST_CT_SWITCH_STMT:
|
||||
case AST_CT_TYPE_ASSIGN_STMT:
|
||||
case AST_DECLARE_STMT:
|
||||
case AST_DECLS_STMT:
|
||||
case AST_NOP_STMT:
|
||||
|
||||
@@ -93,7 +93,6 @@ static bool sema_expr_check_shift_rhs(SemaContext *context, Expr *expr, Type *le
|
||||
static bool sema_expr_analyse_and_or(SemaContext *context, Expr *expr, Expr *left, Expr *right, bool *failed_ref);
|
||||
static bool sema_expr_analyse_slice_assign(SemaContext *context, Expr *expr, Type *left_type, Expr *right, bool *failed_ref);
|
||||
static bool sema_expr_analyse_ct_identifier_assign(SemaContext *context, Expr *expr, Expr *left, Expr *right);
|
||||
static bool sema_expr_analyse_ct_type_identifier_assign(SemaContext *context, Expr *expr, Expr *left, Expr *right);
|
||||
static bool sema_expr_analyse_assign(SemaContext *context, Expr *expr, Expr *left, Expr *right, bool *failed_ref);
|
||||
static bool sema_expr_analyse_comp(SemaContext *context, Expr *expr, Expr *left, Expr *right, bool *failed_ref);
|
||||
static bool sema_expr_analyse_op_assign(SemaContext *context, Expr *expr, Expr *left, Expr *right, BinaryOp operator);
|
||||
@@ -6364,30 +6363,6 @@ static bool sema_expr_analyse_ct_subscript_assign(SemaContext *context, Expr *ex
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool sema_expr_analyse_ct_type_identifier_assign(SemaContext *context, Expr *expr, Expr *left, Expr *right)
|
||||
{
|
||||
TypeInfo *info = left->type_expr;
|
||||
if (info->kind != TYPE_INFO_CT_IDENTIFIER)
|
||||
{
|
||||
RETURN_SEMA_ERROR(left, "A type cannot be assigned to.");
|
||||
}
|
||||
|
||||
if (!sema_analyse_expr_value(context, right)) return false;
|
||||
if (right->expr_kind == EXPR_TYPEINFO)
|
||||
{
|
||||
expr_rewrite_const_typeid(right, right->type_expr->type);
|
||||
}
|
||||
if (!expr_is_const_typeid(right)) RETURN_SEMA_ERROR(right, "Expected a type or constant typeid here.");
|
||||
|
||||
Decl *decl = sema_find_symbol(context, info->unresolved.name);
|
||||
if (!decl) RETURN_SEMA_ERROR(info, "'%s' is not defined in this scope yet.", info->unresolved.name);
|
||||
|
||||
decl->var.init_expr = right;
|
||||
expr->expr_kind = EXPR_NOP;
|
||||
expr->type = type_void;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool sema_expr_fold_hash(SemaContext *context, Expr *expr)
|
||||
{
|
||||
@@ -6414,13 +6389,6 @@ static bool sema_expr_fold_hash(SemaContext *context, Expr *expr)
|
||||
*/
|
||||
static bool sema_expr_analyse_assign(SemaContext *context, Expr *expr, Expr *left, Expr *right, bool *failed_ref)
|
||||
{
|
||||
// 1. Evaluate left side
|
||||
if (left->expr_kind == EXPR_TYPEINFO)
|
||||
{
|
||||
// Later make sure this can be handled in lvalue
|
||||
// $Foo = ...
|
||||
return sema_expr_analyse_ct_type_identifier_assign(context, expr, left, right);
|
||||
}
|
||||
if (!sema_analyse_expr_lvalue(context, left, failed_ref)) return false;
|
||||
switch (left->expr_kind)
|
||||
{
|
||||
|
||||
@@ -1187,6 +1187,24 @@ static inline bool sema_analyse_cond(SemaContext *context, Expr *expr, CondType
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool sema_analyse_ct_type_assign_stmt(SemaContext *context, Ast *statement)
|
||||
{
|
||||
Expr *right = statement->ct_type_assign_stmt.type_expr;
|
||||
if (!sema_analyse_expr_value(context, right)) return false;
|
||||
if (right->expr_kind == EXPR_TYPEINFO)
|
||||
{
|
||||
expr_rewrite_const_typeid(right, right->type_expr->type);
|
||||
}
|
||||
if (!expr_is_const_typeid(right)) RETURN_SEMA_ERROR(right, "Expected a type or constant typeid here.");
|
||||
|
||||
Decl *decl = sema_find_symbol(context, statement->ct_type_assign_stmt.var_name);
|
||||
if (!decl) RETURN_SEMA_ERROR(statement, "'%s' is not defined in this scope yet.", statement->ct_type_assign_stmt.var_name);
|
||||
|
||||
decl->var.init_expr = right;
|
||||
statement->ast_kind = AST_NOP_STMT;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool sema_analyse_decls_stmt(SemaContext *context, Ast *statement)
|
||||
{
|
||||
@@ -3044,6 +3062,8 @@ static inline bool sema_analyse_statement_inner(SemaContext *context, Ast *state
|
||||
case AST_ASM_LABEL:
|
||||
case AST_CONTRACT_FAULT:
|
||||
UNREACHABLE
|
||||
case AST_CT_TYPE_ASSIGN_STMT:
|
||||
return sema_analyse_ct_type_assign_stmt(context, statement);
|
||||
case AST_DECLS_STMT:
|
||||
return sema_analyse_decls_stmt(context, statement);
|
||||
case AST_ASM_BLOCK_STMT:
|
||||
|
||||
Reference in New Issue
Block a user