mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Remove $expand.
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user