Remove $expand.

This commit is contained in:
Christoffer Lerno
2024-08-03 12:46:51 +02:00
parent 0ec1c80221
commit 43ea05aad2
18 changed files with 8 additions and 152 deletions

View File

@@ -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.

View File

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

View File

@@ -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:

View File

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

View File

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

View File

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

View File

@@ -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:

View File

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

View File

@@ -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:

View File

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

View File

@@ -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:

View File

@@ -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:

View File

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

View File

@@ -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:

View File

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

View File

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

View File

@@ -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:

View File

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