Some refactoring of ranges. env::AUTHORS and env::AUTHOR_EMAILS

This commit is contained in:
Christoffer Lerno
2025-07-16 12:23:24 +02:00
parent 078ce38c57
commit 379d16abe7
16 changed files with 86 additions and 15 deletions

View File

@@ -198,6 +198,7 @@ macro bool os_is_posix() @const
return false;
$endswitch
}
const String[] AUTHORS = $$AUTHORS;
const String[] AUTHOR_EMAILS = $$AUTHOR_EMAILS;
const BUILTIN_EXPECT_IS_DISABLED = $feature(DISABLE_BUILTIN_EXPECT);
const BUILTIN_PREFETCH_IS_DISABLED = $feature(DISABLE_BUILTIN_PREFETCH);

View File

@@ -18,6 +18,7 @@
- `$is_const` is deprecated in favour of `@is_const` based on `$defined`.
- Multiline contract comments #2113
- Removed the use of temp allocator in backtrace printing.
- `env::AUTHORS` and `env::AUTHOR_EMAILS` added.
### Fixes
- mkdir/rmdir would not work properly with substring paths on non-windows platforms.

View File

@@ -3,6 +3,8 @@ import std;
import bar;
import clib;
import clib2;
import std::core::env;
fn int test_doubler(int x) @if(env::WIN32) => x * x;
extern fn int test_doubler(int) @if(!env::WIN32);
@@ -11,6 +13,11 @@ extern fn void printf(char *, ...);
fn int main()
{
printf("Hello World!\n");
printf("Authors:");
io::printn(env::AUTHORS);
printf("Author emails:");
io::printn(env::AUTHOR_EMAILS);
bar::test();
printf("Hello double: %d\n", test_doubler(11));
if ($feature(ABCD)) io::printn("ABCD");

View File

@@ -599,6 +599,12 @@ typedef struct BuildOptions_
bool testing;
} BuildOptions;
typedef struct
{
const char *author;
const char *email;
} AuthorEntry;
typedef struct
{
struct Library__ *parent;
@@ -728,6 +734,7 @@ typedef struct
const char **csources;
const char **cinclude_dirs;
const char **exec;
AuthorEntry *authors;
const char **feature_list;
const char *custom_linker_path;
struct

View File

@@ -184,7 +184,29 @@ static void load_into_build_target(BuildParseContext context, JSONObject *json,
error_exit("Error reading %s: output extension '%s' must start with a '.'", context.file, target->extension);
}
}
else
{
const char **authors = get_optional_string_array(context, json, "authors");
AuthorEntry *author_list = NULL;
FOREACH(const char *, author, authors)
{
const char *email_start = strstr(author, "<");
if (email_start)
{
const char *end = strstr(email_start + 1, ">");
if (!end || end[1] != 0 || email_start + 1 == end) error_exit("Error reading %s: invalid author format '%s'", author);
const char *email = str_trim(str_copy(email_start + 1, end - email_start - 1));
AuthorEntry entry = { str_trim(str_copy(author, email_start - author)), email };
vec_add(author_list, entry);
}
else
{
AuthorEntry entry = { str_trim(str_dup(author)), NULL };
vec_add(author_list, entry);
}
}
target->authors = author_list;
}
// "Before compilation" execution
APPEND_STRING_LIST(&target->exec, "exec");

View File

@@ -1489,7 +1489,22 @@ void compile()
setup_bool_define("THREAD_SANITIZER", compiler.build.feature.sanitize_thread);
setup_string_define("BUILD_HASH", GIT_HASH);
setup_string_define("BUILD_DATE", compiler_date_to_iso());
Expr *expr_names = expr_new(EXPR_CONST, INVALID_SPAN);
Expr *expr_emails = expr_new(EXPR_CONST, INVALID_SPAN);
expr_names->const_expr.const_kind = CONST_UNTYPED_LIST;
expr_emails->const_expr.const_kind = CONST_UNTYPED_LIST;
expr_names->type = type_untypedlist;
expr_emails->type = type_untypedlist;
expr_names->resolve_status = expr_names->resolve_status = RESOLVE_DONE;
FOREACH(AuthorEntry, entry, compiler.build.authors)
{
Expr *const_name = expr_new_const_string(INVALID_SPAN, entry.author); // NOLINT
Expr *const_email = expr_new_const_string(INVALID_SPAN, entry.email ? entry.email : ""); // NOLINT
vec_add(expr_names->const_expr.untyped_list, const_name);
vec_add(expr_emails->const_expr.untyped_list, const_email);
}
setup_define("AUTHORS", expr_names);
setup_define("AUTHOR_EMAILS", expr_emails);
type_init_cint();
compiler_init_time = bench_mark();

View File

@@ -710,8 +710,10 @@ typedef enum RangeType
RANGE_CONST_END,
RANGE_CONST_LEN,
RANGE_CONST_RANGE,
RANGE_SINGLE_ELEMENT,
} RangeType;
typedef struct
{
ResolveStatus status : 3;
@@ -719,7 +721,6 @@ typedef struct
bool start_from_end : 1;
bool end_from_end : 1;
bool is_len : 1;
bool is_range : 1;
bool is_optional : 1;
union
{

View File

@@ -195,6 +195,8 @@ void copy_range(CopyStruct *c, Range *range)
{
switch (range->range_type)
{
case RANGE_SINGLE_ELEMENT:
UNREACHABLE
case RANGE_CONST_LEN:
case RANGE_CONST_END:
MACRO_COPY_EXPRID(range->start);

View File

@@ -904,6 +904,8 @@ bool expr_is_pure(Expr *expr)
if (!exprid_is_pure(expr->slice_expr.expr)) return false;
switch (expr->slice_expr.range.range_type)
{
case RANGE_SINGLE_ELEMENT:
UNREACHABLE
case RANGE_CONST_RANGE:
return true;
case RANGE_CONST_END:

View File

@@ -2611,6 +2611,8 @@ static void llvm_emit_slice_values(GenContext *c, Expr *slice, BEValue *parent_r
BEValue start_index;
switch (range.range_type)
{
case RANGE_SINGLE_ELEMENT:
UNREACHABLE
case RANGE_DYNAMIC:
case RANGE_CONST_LEN:
case RANGE_CONST_END:
@@ -2680,6 +2682,8 @@ static void llvm_emit_slice_values(GenContext *c, Expr *slice, BEValue *parent_r
// Get the index.
switch (range.range_type)
{
case RANGE_SINGLE_ELEMENT:
UNREACHABLE
case RANGE_DYNAMIC:
llvm_emit_exprid(c, &end_index, range.end);
llvm_value_rvalue(c, &end_index);

View File

@@ -50,12 +50,10 @@ bool parse_range(ParseContext *c, Range *range)
bool is_len_range = range->is_len = try_consume(c, TOKEN_COLON);
if (!is_len_range && !try_consume(c, TOKEN_DOTDOT))
{
// Otherwise this is not a range.
range->is_range = false;
// Otherwise this is a single element
range->range_type = RANGE_SINGLE_ELEMENT;
return true;
}
range->is_range = true;
// Is there an expression next?
range->end_from_end = try_consume(c, TOKEN_BIT_XOR);
if (range->end_from_end || parse_current_is_expr(c))
@@ -443,6 +441,11 @@ Expr *parse_vasplat(ParseContext *c)
if (try_consume(c, TOKEN_LBRACKET))
{
if (!parse_range(c, &expr->vasplat_expr)) return poisoned_expr;
if (expr->vasplat_expr.range_type == RANGE_SINGLE_ELEMENT)
{
PRINT_ERROR_AT(expr, "$vasplat expected a range.");
return poisoned_expr;
}
CONSUME_OR_RET(TOKEN_RBRACKET, poisoned_expr);
}
RANGE_EXTEND_PREV(expr);
@@ -1052,7 +1055,7 @@ static Expr *parse_subscript_expr(ParseContext *c, Expr *left, SourceSpan lhs_st
Range range = { .range_type = RANGE_DYNAMIC };
if (!parse_range(c, &range)) return poisoned_expr;
CONSUME_OR_RET(TOKEN_RBRACKET, poisoned_expr);
if (!range.is_range)
if (range.range_type == RANGE_SINGLE_ELEMENT)
{
subs_expr->subscript_expr.index = (SubscriptIndex) {
.expr = range.start,

View File

@@ -1146,7 +1146,8 @@ static inline bool sema_identifier_find_possible_inferred(SemaContext *context,
static inline bool sema_expr_analyse_identifier(SemaContext *context, Type *to, Expr *expr)
{
ASSERT_SPAN(expr, expr && expr->unresolved_ident_expr.ident);
ASSERT(expr);
ASSERT_SPAN(expr, expr->unresolved_ident_expr.ident);
DEBUG_LOG("Resolving identifier '%s'", expr->unresolved_ident_expr.ident);
ASSERT_SPAN(expr, expr->resolve_status != RESOLVE_DONE);
@@ -6212,11 +6213,6 @@ static Expr **sema_vasplat_insert(SemaContext *context, Expr **init_expressions,
unsigned start_idx = 0;
if (start)
{
if (!range->is_range)
{
SEMA_ERROR(expr, "$vasplat expected a range.");
return NULL;
}
if (!sema_analyse_expr(context, start)) return NULL;
if (!expr_is_const_int(start))
{

View File

@@ -190,6 +190,8 @@ static inline IndexDiff range_const_len(Range *range)
{
switch (range->range_type)
{
case RANGE_SINGLE_ELEMENT:
UNREACHABLE;
case RANGE_CONST_LEN:
return range->const_end;
case RANGE_CONST_END:

View File

@@ -453,6 +453,8 @@ RETRY:
sema_trace_expr_liveness(exprptr(expr->slice_expr.expr));
switch (expr->slice_expr.range.range_type)
{
case RANGE_SINGLE_ELEMENT:
UNREACHABLE
case RANGE_CONST_RANGE:
return;
case RANGE_DYNAMIC:

View File

@@ -157,6 +157,7 @@ bool str_is_integer(const char *string);
bool str_has_no_uppercase(const char *string);
bool str_is_valid_module_name(const char *name);
char *str_copy(const char *start, size_t str_len);
char *str_dup(const char *str);
StringSlice slice_next_token(StringSlice *slice, char separator);
static inline bool slice_strcmp(StringSlice slice, const char *other);

View File

@@ -332,6 +332,11 @@ char *str_cat(const char *a, const char *b)
return buffer;
}
char *str_dup(const char *str)
{
return str_copy(str, strlen(str));
}
char *str_copy(const char *start, size_t str_len)
{
char *dst = calloc_string(str_len + 1);