diff --git a/releasenotes.md b/releasenotes.md index 90e17b138..7ffeff338 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -17,7 +17,6 @@ - Permit foreach values to be optional. - Add `--show-backtrace` option to disable backtrace for even smaller binary. - Untested Xtensa support. -- `$expand` macro, to expand a string into code. - && doesn't work correctly with lambdas #1279. - Fix incorrect override of optimization levels when using projects. - Add experimental `@noalias` attribute. diff --git a/src/compiler/ast.c b/src/compiler/ast.c index 3e76609b2..7a69225db 100644 --- a/src/compiler/ast.c +++ b/src/compiler/ast.c @@ -113,7 +113,6 @@ const char *decl_to_a_name(Decl *decl) case DECL_CT_ASSERT: return "a compile time assert"; case DECL_CT_ECHO: return "a compile time echo"; case DECL_CT_EXEC: return "compile time exec include"; - case DECL_CT_EXPAND: return "compile time expand"; case DECL_CT_INCLUDE: return "an include"; case DECL_DECLARRAY: return "a declarray"; case DECL_DEFINE: case DECL_TYPEDEF: return "a define"; diff --git a/src/compiler/context.c b/src/compiler/context.c index d78bc0f44..963a57d8c 100644 --- a/src/compiler/context.c +++ b/src/compiler/context.c @@ -126,7 +126,6 @@ void decl_register(Decl *decl) case DECL_CT_ASSERT: case DECL_CT_ECHO: case DECL_CT_EXEC: - case DECL_CT_EXPAND: case DECL_ENUM_CONSTANT: case DECL_FAULTVALUE: case DECL_IMPORT: @@ -234,7 +233,6 @@ void unit_register_global_decl(CompilationUnit *unit, Decl *decl) UNREACHABLE case DECL_CT_EXEC: case DECL_CT_INCLUDE: - case DECL_CT_EXPAND: vec_add(unit->ct_includes, decl); return; case DECL_CT_ECHO: diff --git a/src/compiler/copying.c b/src/compiler/copying.c index b74be6275..4e5b58c1b 100644 --- a/src/compiler/copying.c +++ b/src/compiler/copying.c @@ -575,9 +575,6 @@ RETRY: case AST_DECLS_STMT: MACRO_COPY_DECL_LIST(ast->decls_stmt); break; - case AST_CT_EXPAND_STMT: - MACRO_COPY_EXPR(ast->expr_stmt); - break; case AST_CONTRACT_FAULT: if (ast->contract_fault.resolved) { @@ -894,9 +891,6 @@ Decl *copy_decl(CopyStruct *c, Decl *decl) MACRO_COPY_DECL_LIST(copy->methods); MACRO_COPY_DECL_LIST(copy->interface_methods); break; - case DECL_CT_EXPAND: - MACRO_COPY_EXPR(copy->expand_decl); - break; case DECL_CT_EXEC: MACRO_COPY_EXPR(copy->exec_decl.filename); MACRO_COPY_EXPR_LIST(copy->exec_decl.args); diff --git a/src/compiler/enums.h b/src/compiler/enums.h index 4baecc060..99cca3fff 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -69,7 +69,6 @@ typedef enum AST_CT_ASSERT, AST_CT_ECHO_STMT, AST_CT_ELSE_STMT, - AST_CT_EXPAND_STMT, AST_CT_FOREACH_STMT, AST_CT_FOR_STMT, AST_CT_IF_STMT, @@ -94,7 +93,7 @@ typedef enum #define CT_AST \ AST_CT_ASSERT: case AST_CT_ECHO_STMT: case AST_CT_ELSE_STMT: \ - case AST_CT_EXPAND_STMT: case AST_CT_FOREACH_STMT: case AST_CT_FOR_STMT: \ + case AST_CT_FOREACH_STMT: case AST_CT_FOR_STMT: \ case AST_CT_IF_STMT: case AST_CT_SWITCH_STMT typedef enum @@ -152,7 +151,6 @@ typedef enum DECL_CT_ASSERT, DECL_CT_ECHO, DECL_CT_EXEC, - DECL_CT_EXPAND, DECL_CT_INCLUDE, DECL_DECLARRAY, DECL_DEFINE, @@ -180,7 +178,8 @@ typedef enum case DECL_DEFINE: case DECL_CT_ASSERT: case DECL_CT_EXEC: \ case DECL_CT_ECHO: case DECL_CT_INCLUDE: case DECL_GLOBALS: \ case DECL_BODYPARAM: case DECL_VAR: case DECL_ENUM_CONSTANT: case DECL_FAULTVALUE: \ - case DECL_POISONED: case DECL_CT_EXPAND + case DECL_POISONED + #define NON_RUNTIME_EXPR EXPR_DESIGNATOR: case EXPR_POISONED: \ case EXPR_CT_DEFINED: case EXPR_CT_AND_OR:\ @@ -607,7 +606,6 @@ typedef enum TOKEN_CT_EVALTYPE, // $evaltype TOKEN_CT_ERROR, // $error TOKEN_CT_EXEC, // $exec - TOKEN_CT_EXPAND, // $expand TOKEN_CT_EXTNAMEOF, // $extnameof TOKEN_CT_FEATURE, // $feature TOKEN_CT_FOR, // $for diff --git a/src/compiler/json_output.c b/src/compiler/json_output.c index f38f60892..f85146b0b 100644 --- a/src/compiler/json_output.c +++ b/src/compiler/json_output.c @@ -42,7 +42,6 @@ static inline const char *decl_type_to_string(Decl *type) case DECL_CT_ASSERT: return "$assert"; case DECL_CT_ECHO: return "$echo"; case DECL_CT_EXEC: return "$exec"; - case DECL_CT_EXPAND: return "$expand"; case DECL_CT_INCLUDE: return "$include"; case DECL_DEFINE: return "def"; case DECL_DISTINCT: return "distinct"; diff --git a/src/compiler/llvm_codegen.c b/src/compiler/llvm_codegen.c index 5bb5c14e6..18ce6a105 100644 --- a/src/compiler/llvm_codegen.c +++ b/src/compiler/llvm_codegen.c @@ -1267,7 +1267,6 @@ LLVMValueRef llvm_get_ref(GenContext *c, Decl *decl) case DECL_BODYPARAM: case DECL_CT_ECHO: case DECL_CT_EXEC: - case DECL_CT_EXPAND: case DECL_CT_INCLUDE: case DECL_GLOBALS: case DECL_INTERFACE: diff --git a/src/compiler/parse_global.c b/src/compiler/parse_global.c index fd830aa38..0151a7699 100644 --- a/src/compiler/parse_global.c +++ b/src/compiler/parse_global.c @@ -2636,18 +2636,6 @@ static Decl *parse_include(ParseContext *c) return decl; } -static Decl *parse_expand(ParseContext *c) -{ - SourceSpan loc = c->span; - Decl *decl = decl_new(DECL_CT_EXPAND, NULL, loc); - advance_and_verify(c, TOKEN_CT_EXPAND); - CONSUME_OR_RET(TOKEN_LPAREN, poisoned_decl); - ASSIGN_EXPR_OR_RET(decl->expand_decl, parse_constant_expr(c), poisoned_decl); - CONSUME_OR_RET(TOKEN_RPAREN, poisoned_decl); - if (!parse_attributes_for_global(c, decl)) return poisoned_decl; - CONSUME_EOS_OR_RET(poisoned_decl); - return decl; -} static Decl *parse_exec(ParseContext *c) { SourceSpan loc = c->span; @@ -2784,10 +2772,6 @@ Decl *parse_top_level_statement(ParseContext *c, ParseContext **c_ref) if (contracts) goto CONTRACT_NOT_ALLOWED; decl = parse_exec(c); break; - case TOKEN_CT_EXPAND: - if (contracts) goto CONTRACT_NOT_ALLOWED; - decl = parse_expand(c); - break; case TOKEN_BITSTRUCT: if (contracts) goto CONTRACT_NOT_ALLOWED; decl = parse_bitstruct_declaration(c); diff --git a/src/compiler/parse_stmt.c b/src/compiler/parse_stmt.c index c237150b2..1b14f19f3 100644 --- a/src/compiler/parse_stmt.c +++ b/src/compiler/parse_stmt.c @@ -1029,19 +1029,6 @@ static inline Ast *parse_return_stmt(ParseContext *c) return ast; } -/** - * ct_expand_stmt :: CT_EXPAND '(' expr ')' - */ -static inline Ast* parse_ct_expand_stmt(ParseContext *c) -{ - Ast *ast = ast_new_curr(c, AST_CT_EXPAND_STMT); - advance_and_verify(c, TOKEN_CT_EXPAND); - CONSUME_OR_RET(TOKEN_LPAREN, poisoned_ast); - ASSIGN_EXPR_OR_RET(ast->expand_stmt, parse_expr(c), poisoned_ast); - CONSUME_OR_RET(TOKEN_RPAREN, poisoned_ast); - CONSUME_EOS_OR_RET(poisoned_ast); - return ast; -} /** * ct_foreach_stmt ::= CT_FOREACH '(' CT_IDENT (',' CT_IDENT)? ':' expr ')' statement* CT_ENDFOREACH */ @@ -1292,8 +1279,6 @@ Ast *parse_stmt(ParseContext *c) return parse_ct_if_stmt(c); case TOKEN_CT_SWITCH: return parse_ct_switch_stmt(c); - case TOKEN_CT_EXPAND: - return parse_ct_expand_stmt(c); case TOKEN_CT_FOREACH: return parse_ct_foreach_stmt(c); case TOKEN_CT_FOR: diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index e7cf216ea..ed10468d6 100644 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -3434,7 +3434,6 @@ static inline bool sema_analyse_macro(SemaContext *context, Decl *decl, bool *er { case AST_CT_ASSERT: case AST_CT_ECHO_STMT: - case AST_CT_EXPAND_STMT: case AST_CT_FOREACH_STMT: case AST_CT_FOR_STMT: case AST_CT_IF_STMT: @@ -4346,7 +4345,6 @@ bool sema_analyse_decl(SemaContext *context, Decl *decl) case DECL_BODYPARAM: case DECL_CT_INCLUDE: case DECL_CT_EXEC: - case DECL_CT_EXPAND: case DECL_GLOBALS: UNREACHABLE } diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 372debbca..cfa204b3b 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -779,7 +779,11 @@ static inline bool sema_cast_ident_rvalue(SemaContext *context, Expr *expr) case DECL_CT_EXEC: case DECL_GLOBALS: case DECL_ERASED: - case DECL_CT_EXPAND: + case DECL_IMPORT: + case DECL_ATTRIBUTE: + case DECL_CT_ASSERT: + case DECL_DEFINE: + case DECL_CT_ECHO: UNREACHABLE case DECL_POISONED: return expr_poison(expr); @@ -804,12 +808,6 @@ static inline bool sema_cast_ident_rvalue(SemaContext *context, Expr *expr) case DECL_FAULT: SEMA_ERROR(expr, "Expected fault name followed by '.' and a fault value."); return expr_poison(expr); - case DECL_IMPORT: - case DECL_ATTRIBUTE: - case DECL_CT_ASSERT: - case DECL_DEFINE: - case DECL_CT_ECHO: - UNREACHABLE } switch (decl->var.kind) { @@ -7626,7 +7624,6 @@ static inline bool sema_expr_analyse_ct_nameof(SemaContext *context, Expr *expr) case DECL_CT_ASSERT: case DECL_CT_ECHO: case DECL_CT_EXEC: - case DECL_CT_EXPAND: case DECL_CT_INCLUDE: case DECL_DECLARRAY: case DECL_ERASED: diff --git a/src/compiler/sema_liveness.c b/src/compiler/sema_liveness.c index cbfe2756d..1e45a681d 100644 --- a/src/compiler/sema_liveness.c +++ b/src/compiler/sema_liveness.c @@ -561,7 +561,6 @@ RETRY: case DECL_CT_ASSERT: case DECL_CT_ECHO: case DECL_CT_EXEC: - case DECL_CT_EXPAND: case DECL_IMPORT: case DECL_CT_INCLUDE: case DECL_LABEL: diff --git a/src/compiler/sema_passes.c b/src/compiler/sema_passes.c index 3f7e8fd36..76ef613d2 100644 --- a/src/compiler/sema_passes.c +++ b/src/compiler/sema_passes.c @@ -184,33 +184,6 @@ static Decl **sema_load_include(CompilationUnit *unit, Decl *decl) return parse_include_file(file, unit); } -static Decl **sema_interpret_expand(CompilationUnit *unit, Decl *decl) -{ - SemaContext context; - sema_context_init(&context, unit); - FOREACH(Attr *, attr, decl->attributes) - { - if (attr->attr_kind != ATTRIBUTE_IF) - { - RETURN_PRINT_ERROR_AT(NULL, attr, "Invalid attribute for '$expand'."); - } - } - Expr *string = decl->expand_decl; - bool success = sema_analyse_ct_expr(&context, string); - sema_context_destroy(&context); - if (!success) return NULL; - if (!expr_is_const_string(string)) - { - RETURN_PRINT_ERROR_AT(NULL, string, "Expected a constant string for '$expand'."); - } - scratch_buffer_clear(); - scratch_buffer_printf("%s.%d", unit->file->full_path, string->span.row); - File *file = source_file_text_load(scratch_buffer_to_string(), string->const_expr.bytes.ptr); - ParseContext parse_context = { .tok = TOKEN_INVALID_TOKEN }; - ParseContext *c = &parse_context; - c->unit = unit; - return parse_include_file(file, unit); -} static Decl **sema_run_exec(CompilationUnit *unit, Decl *decl) { @@ -336,9 +309,6 @@ INLINE void register_includes(CompilationUnit *unit, Decl **decls) case DECL_CT_INCLUDE: include_decls = sema_load_include(unit, include); break; - case DECL_CT_EXPAND: - include_decls = sema_interpret_expand(unit, include); - break; default: UNREACHABLE } diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index 456203869..2a683fde2 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -2851,21 +2851,6 @@ bool sema_analyse_ct_assert_stmt(SemaContext *context, Ast *statement) return true; } -bool sema_analyse_ct_expand_stmt(SemaContext *context, Ast *stmt) -{ - Expr *string = stmt->expand_stmt; - if (!sema_analyse_ct_expr(context, string)) return false; - if (!expr_is_const_string(string)) RETURN_SEMA_ERROR(string, "Expected a constant string to '$expand'."); - scratch_buffer_clear(); - scratch_buffer_printf("%s.%d", context->unit->file->full_path, string->span.row); - File *file = source_file_text_load(scratch_buffer_to_string(), string->const_expr.bytes.ptr); - Ast *result = parse_include_file_stmts(file, context->unit); - stmt->ast_kind = AST_NOP_STMT; - if (!result) return true; - if (!ast_ok(result)) return ast_poison(stmt); - return sema_analyse_then_overwrite(context, stmt, astid(result)); -} - bool sema_analyse_ct_echo_stmt(SemaContext *context, Ast *statement) { Expr *message = statement->expr_stmt; @@ -3027,8 +3012,6 @@ static inline bool sema_analyse_statement_inner(SemaContext *context, Ast *state return sema_analyse_ct_echo_stmt(context, statement); case AST_DECLARE_STMT: return sema_analyse_declare_stmt(context, statement); - case AST_CT_EXPAND_STMT: - return sema_analyse_ct_expand_stmt(context, statement); case AST_DEFAULT_STMT: RETURN_SEMA_ERROR(statement, "Unexpected 'default' outside of switch"); case AST_DEFER_STMT: diff --git a/src/compiler/sema_types.c b/src/compiler/sema_types.c index d17c62983..83b73fdaf 100644 --- a/src/compiler/sema_types.c +++ b/src/compiler/sema_types.c @@ -262,7 +262,6 @@ static bool sema_resolve_type_identifier(SemaContext *context, TypeInfo *type_in case DECL_DECLARRAY: case DECL_BODYPARAM: case DECL_CT_INCLUDE: - case DECL_CT_EXPAND: case DECL_CT_EXEC: case DECL_GLOBALS: UNREACHABLE diff --git a/src/compiler/semantic_analyser.c b/src/compiler/semantic_analyser.c index daf170aa7..c6a24f7b3 100644 --- a/src/compiler/semantic_analyser.c +++ b/src/compiler/semantic_analyser.c @@ -206,7 +206,6 @@ static void register_generic_decls(CompilationUnit *unit, Decl **decls) case DECL_FNTYPE: case DECL_CT_INCLUDE: case DECL_CT_EXEC: - case DECL_CT_EXPAND: continue; case DECL_ATTRIBUTE: break; diff --git a/src/compiler/tokens.c b/src/compiler/tokens.c index 080c3da40..eb3916f2c 100644 --- a/src/compiler/tokens.c +++ b/src/compiler/tokens.c @@ -362,8 +362,6 @@ const char *token_type_to_string(TokenType type) return "$error"; case TOKEN_CT_EXEC: return "$exec"; - case TOKEN_CT_EXPAND: - return "$expand"; case TOKEN_CT_EXTNAMEOF: return "$extnameof"; case TOKEN_CT_FEATURE: diff --git a/test/test_suite/compile_time/ct_expand.c3t b/test/test_suite/compile_time/ct_expand.c3t deleted file mode 100644 index 9ceebce8d..000000000 --- a/test/test_suite/compile_time/ct_expand.c3t +++ /dev/null @@ -1,42 +0,0 @@ -// #target: macos-x64 -module test; -import std; - -$expand(test()); - -struct Foo -{ - int a; - int b; -} -macro test() -{ - var $out = "struct Copy {"; - $foreach ($member : Foo.membersof) - $out = $concat($out, " ", $member.typeid.nameof, " ", $member.nameof, ";"); - $endforeach; - return $concat($out, "}"); -} - -fn void main() -{ - var $a = "a = 4;"; - $expand($concat("int a = 1;", $a)); - Copy x = { 1, 3 }; - x.a = 4; -} - -/* #expect: test.ll - -%Copy = type { i32, i32 } - -define void @test.main() #0 { -entry: - %a = alloca i32, align 4 - %x = alloca %Copy, align 4 - store i32 1, ptr %a, align 4 - store i32 4, ptr %a, align 4 - call void @llvm.memcpy.p0.p0.i32(ptr align 4 %x, ptr align 4 @.__const, i32 8, i1 false) - store i32 4, ptr %x, align 4 - ret void -}