- Introduce $vaarg[...] syntax and deprecate the old $vaarg(...).

- Similar change to `$vasplat`: `$vasplat` and `$vasplat[1..]`.
This commit is contained in:
Christoffer Lerno
2024-08-16 09:28:28 +02:00
parent 9fd9280132
commit edfea639cf
20 changed files with 119 additions and 74 deletions

View File

@@ -135,7 +135,7 @@ fn void panicf(String fmt, String file, String function, uint line, args...)
macro void unreachable(String string = "Unreachable statement reached.", ...) @builtin @noreturn macro void unreachable(String string = "Unreachable statement reached.", ...) @builtin @noreturn
{ {
$if env::COMPILER_SAFE_MODE: $if env::COMPILER_SAFE_MODE:
panicf(string, $$FILE, $$FUNC, $$LINE, $vasplat()); panicf(string, $$FILE, $$FUNC, $$LINE, $vasplat);
$endif; $endif;
$$unreachable(); $$unreachable();
} }
@@ -146,7 +146,7 @@ macro void unreachable(String string = "Unreachable statement reached.", ...) @b
**/ **/
macro void unsupported(String string = "Unsupported function invoked") @builtin @noreturn macro void unsupported(String string = "Unsupported function invoked") @builtin @noreturn
{ {
panicf(string, $$FILE, $$FUNC, $$LINE, $vasplat()); panicf(string, $$FILE, $$FUNC, $$LINE, $vasplat);
$$unreachable(); $$unreachable();
} }
@@ -291,12 +291,12 @@ macro @prefetch(void* ptr, PrefetchLocality $locality = VERY_NEAR, bool $write =
macro swizzle(v, ...) @builtin macro swizzle(v, ...) @builtin
{ {
return $$swizzle(v, $vasplat()); return $$swizzle(v, $vasplat);
} }
macro swizzle2(v, v2, ...) @builtin macro swizzle2(v, v2, ...) @builtin
{ {
return $$swizzle2(v, v2, $vasplat()); return $$swizzle2(v, v2, $vasplat);
} }
macro anyfault @catch(#expr) @builtin macro anyfault @catch(#expr) @builtin

View File

@@ -97,13 +97,13 @@ macro bool equals(a, b) @builtin
macro min(x, ...) @builtin macro min(x, ...) @builtin
{ {
$if $vacount == 1: $if $vacount == 1:
return less(x, $vaarg(0)) ? x : $vaarg(0); return less(x, $vaarg[0]) ? x : $vaarg[0];
$else $else
var result = x; var result = x;
$for (var $i = 0; $i < $vacount; $i++) $for (var $i = 0; $i < $vacount; $i++)
if (less($vaarg($i), result)) if (less($vaarg[$i], result))
{ {
result = $vaarg($i); result = $vaarg[$i];
} }
$endfor $endfor
return result; return result;
@@ -113,13 +113,13 @@ macro min(x, ...) @builtin
macro max(x, ...) @builtin macro max(x, ...) @builtin
{ {
$if $vacount == 1: $if $vacount == 1:
return greater(x, $vaarg(0)) ? x : $vaarg(0); return greater(x, $vaarg[0]) ? x : $vaarg[0];
$else $else
var result = x; var result = x;
$for (var $i = 0; $i < $vacount; $i++) $for (var $i = 0; $i < $vacount; $i++)
if (greater($vaarg($i), result)) if (greater($vaarg[$i], result))
{ {
result = $vaarg($i); result = $vaarg[$i];
} }
$endfor $endfor
return result; return result;

View File

@@ -591,7 +591,7 @@ fn void* tmalloc(usz size, usz alignment = 0) @builtin @inline @nodiscard
/** /**
* @require $vacount < 2 : "Too many arguments." * @require $vacount < 2 : "Too many arguments."
* @require $vacount == 0 ||| $assignable($vaexpr(0), $Type) : "The second argument must be an initializer for the type" * @require $vacount == 0 ||| $assignable($vaexpr[0], $Type) : "The second argument must be an initializer for the type"
* @require $Type.alignof <= DEFAULT_MEM_ALIGNMENT : "Types with alignment exceeding the default must use 'alloc_aligned' instead" * @require $Type.alignof <= DEFAULT_MEM_ALIGNMENT : "Types with alignment exceeding the default must use 'alloc_aligned' instead"
**/ **/
macro new($Type, ...) @nodiscard macro new($Type, ...) @nodiscard
@@ -600,7 +600,7 @@ macro new($Type, ...) @nodiscard
return ($Type*)calloc($Type.sizeof); return ($Type*)calloc($Type.sizeof);
$else $else
$Type* val = malloc($Type.sizeof); $Type* val = malloc($Type.sizeof);
*val = $vaexpr(0); *val = $vaexpr[0];
return val; return val;
$endif $endif
} }
@@ -609,7 +609,7 @@ macro new($Type, ...) @nodiscard
* Allocate using an aligned allocation. This is necessary for types with a default memory alignment * Allocate using an aligned allocation. This is necessary for types with a default memory alignment
* exceeding DEFAULT_MEM_ALIGNMENT. IMPORTANT! It must be freed using free_aligned. * exceeding DEFAULT_MEM_ALIGNMENT. IMPORTANT! It must be freed using free_aligned.
* @require $vacount < 2 : "Too many arguments." * @require $vacount < 2 : "Too many arguments."
* @require $vacount == 0 ||| $assignable($vaexpr(0), $Type) : "The second argument must be an initializer for the type" * @require $vacount == 0 ||| $assignable($vaexpr[0], $Type) : "The second argument must be an initializer for the type"
**/ **/
macro new_aligned($Type, ...) @nodiscard macro new_aligned($Type, ...) @nodiscard
{ {
@@ -617,7 +617,7 @@ macro new_aligned($Type, ...) @nodiscard
return ($Type*)calloc_aligned($Type.sizeof, $Type.alignof); return ($Type*)calloc_aligned($Type.sizeof, $Type.alignof);
$else $else
$Type* val = malloc_aligned($Type.sizeof, $Type.alignof); $Type* val = malloc_aligned($Type.sizeof, $Type.alignof);
*val = $vaexpr(0); *val = $vaexpr[0];
return val; return val;
$endif $endif
} }
@@ -641,7 +641,7 @@ macro alloc_aligned($Type) @nodiscard
/** /**
* @require $vacount < 2 : "Too many arguments." * @require $vacount < 2 : "Too many arguments."
* @require $vacount == 0 ||| $assignable($vaexpr(0), $Type) : "The second argument must be an initializer for the type" * @require $vacount == 0 ||| $assignable($vaexpr[0], $Type) : "The second argument must be an initializer for the type"
**/ **/
macro temp_new($Type, ...) @nodiscard macro temp_new($Type, ...) @nodiscard
{ {
@@ -649,7 +649,7 @@ macro temp_new($Type, ...) @nodiscard
return ($Type*)tcalloc($Type.sizeof) @inline; return ($Type*)tcalloc($Type.sizeof) @inline;
$else $else
$Type* val = tmalloc($Type.sizeof) @inline; $Type* val = tmalloc($Type.sizeof) @inline;
*val = $vaexpr(0); *val = $vaexpr[0];
return val; return val;
$endif $endif
} }

View File

@@ -149,7 +149,7 @@ macro void free_aligned(Allocator allocator, void* ptr)
/** /**
* @require $Type.alignof <= mem::DEFAULT_MEM_ALIGNMENT : "Types with alignment exceeding the default must use 'new_aligned' instead" * @require $Type.alignof <= mem::DEFAULT_MEM_ALIGNMENT : "Types with alignment exceeding the default must use 'new_aligned' instead"
* @require $vacount < 2 : "Too many arguments." * @require $vacount < 2 : "Too many arguments."
* @require $vacount == 0 ||| $assignable($vaexpr(0), $Type) : "The second argument must be an initializer for the type" * @require $vacount == 0 ||| $assignable($vaexpr[0], $Type) : "The second argument must be an initializer for the type"
**/ **/
macro new(Allocator allocator, $Type, ...) @nodiscard macro new(Allocator allocator, $Type, ...) @nodiscard
{ {
@@ -157,7 +157,7 @@ macro new(Allocator allocator, $Type, ...) @nodiscard
return ($Type*)calloc(allocator, $Type.sizeof); return ($Type*)calloc(allocator, $Type.sizeof);
$else $else
$Type* val = malloc(allocator, $Type.sizeof); $Type* val = malloc(allocator, $Type.sizeof);
*val = $vaexpr(0); *val = $vaexpr[0];
return val; return val;
$endif $endif
} }
@@ -165,7 +165,7 @@ macro new(Allocator allocator, $Type, ...) @nodiscard
/** /**
* @require $Type.alignof <= mem::DEFAULT_MEM_ALIGNMENT : "Types with alignment exceeding the default must use 'new_aligned' instead" * @require $Type.alignof <= mem::DEFAULT_MEM_ALIGNMENT : "Types with alignment exceeding the default must use 'new_aligned' instead"
* @require $vacount < 2 : "Too many arguments." * @require $vacount < 2 : "Too many arguments."
* @require $vacount == 0 ||| $assignable($vaexpr(0), $Type) : "The second argument must be an initializer for the type" * @require $vacount == 0 ||| $assignable($vaexpr[0], $Type) : "The second argument must be an initializer for the type"
**/ **/
macro new_try(Allocator allocator, $Type, ...) @nodiscard macro new_try(Allocator allocator, $Type, ...) @nodiscard
{ {
@@ -173,7 +173,7 @@ macro new_try(Allocator allocator, $Type, ...) @nodiscard
return ($Type*)calloc_try(allocator, $Type.sizeof); return ($Type*)calloc_try(allocator, $Type.sizeof);
$else $else
$Type* val = malloc_try(allocator, $Type.sizeof)!; $Type* val = malloc_try(allocator, $Type.sizeof)!;
*val = $vaexpr(0); *val = $vaexpr[0];
return val; return val;
$endif $endif
} }
@@ -182,7 +182,7 @@ macro new_try(Allocator allocator, $Type, ...) @nodiscard
* Allocate using an aligned allocation. This is necessary for types with a default memory alignment * Allocate using an aligned allocation. This is necessary for types with a default memory alignment
* exceeding DEFAULT_MEM_ALIGNMENT. IMPORTANT! It must be freed using free_aligned. * exceeding DEFAULT_MEM_ALIGNMENT. IMPORTANT! It must be freed using free_aligned.
* @require $vacount < 2 : "Too many arguments." * @require $vacount < 2 : "Too many arguments."
* @require $vacount == 0 ||| $assignable($vaexpr(0), $Type) : "The second argument must be an initializer for the type" * @require $vacount == 0 ||| $assignable($vaexpr[0], $Type) : "The second argument must be an initializer for the type"
**/ **/
macro new_aligned($Type, ...) @nodiscard macro new_aligned($Type, ...) @nodiscard
{ {
@@ -190,7 +190,7 @@ macro new_aligned($Type, ...) @nodiscard
return ($Type*)calloc_aligned(allocator, $Type.sizeof, $Type.alignof); return ($Type*)calloc_aligned(allocator, $Type.sizeof, $Type.alignof);
$else $else
$Type* val = malloc_aligned(allocator, $Type.sizeof, $Type.alignof); $Type* val = malloc_aligned(allocator, $Type.sizeof, $Type.alignof);
*val = $vaexpr(0); *val = $vaexpr[0];
return val; return val;
$endif $endif
} }

View File

@@ -40,7 +40,7 @@ fault NumberConversion
macro String tformat(String fmt, ...) macro String tformat(String fmt, ...)
{ {
DString str = dstring::temp_with_capacity(fmt.len + $vacount * 8); DString str = dstring::temp_with_capacity(fmt.len + $vacount * 8);
str.appendf(fmt, $vasplat()); str.appendf(fmt, $vasplat);
return str.str_view(); return str.str_view();
} }
@@ -52,7 +52,7 @@ macro String tformat(String fmt, ...)
macro ZString tformat_zstr(String fmt, ...) macro ZString tformat_zstr(String fmt, ...)
{ {
DString str = dstring::temp_with_capacity(fmt.len + $vacount * 8); DString str = dstring::temp_with_capacity(fmt.len + $vacount * 8);
str.appendf(fmt, $vasplat()); str.appendf(fmt, $vasplat);
return str.zstr_view(); return str.zstr_view();
} }
@@ -67,7 +67,7 @@ macro String new_format(String fmt, ..., Allocator allocator = allocator::heap()
@pool(allocator) @pool(allocator)
{ {
DString str = dstring::temp_with_capacity(fmt.len + $vacount * 8); DString str = dstring::temp_with_capacity(fmt.len + $vacount * 8);
str.appendf(fmt, $vasplat()); str.appendf(fmt, $vasplat);
return str.copy_str(allocator); return str.copy_str(allocator);
}; };
} }
@@ -83,7 +83,7 @@ macro ZString new_format_zstr(String fmt, ..., Allocator allocator = allocator::
@pool(allocator) @pool(allocator)
{ {
DString str = dstring::temp_with_capacity(fmt.len + $vacount * 8); DString str = dstring::temp_with_capacity(fmt.len + $vacount * 8);
str.appendf(fmt, $vasplat()); str.appendf(fmt, $vasplat);
return str.copy_zstr(allocator); return str.copy_zstr(allocator);
}; };
} }

View File

@@ -199,7 +199,7 @@ macro bool @has_same(#a, #b, ...) @const
return false; return false;
$endif $endif
$for (var $i = 0; $i < $vacount; $i++) $for (var $i = 0; $i < $vacount; $i++)
$if @typeid($vaexpr($i)) != $type_a: $if @typeid($vaexpr[$i]) != $type_a:
return false; return false;
$endif $endif
$endfor $endfor

View File

@@ -365,7 +365,7 @@ macro max(x, y, ...)
$else $else
var m = $$max(x, y); var m = $$max(x, y);
$for (var $i = 0; $i < $vacount; $i++) $for (var $i = 0; $i < $vacount; $i++)
m = $$max(m, $vaarg($i)); m = $$max(m, $vaarg[$i]);
$endfor $endfor
return m; return m;
$endif $endif
@@ -382,7 +382,7 @@ macro min(x, y, ...)
$else $else
var m = $$min(x, y); var m = $$min(x, y);
$for (var $i = 0; $i < $vacount; $i++) $for (var $i = 0; $i < $vacount; $i++)
m = $$min(m, $vaarg($i)); m = $$min(m, $vaarg[$i]);
$endfor $endfor
return m; return m;
$endif $endif

View File

@@ -33,6 +33,8 @@
- Add temp allocator scribble. - Add temp allocator scribble.
- Use PIC by default on Linux. - Use PIC by default on Linux.
- `$exec` may now provide a stdin parameter. - `$exec` may now provide a stdin parameter.
- Introduce `$vaarg[...]` syntax and deprecate the old `$vaarg(...)`.
- Similar change to `$vasplat`: `$vasplat` and `$vasplat[1..]`.
### Fixes ### Fixes

View File

@@ -19,7 +19,7 @@ macro @with_mode(String user, #action, ...)
@scope(context_user) @scope(context_user)
{ {
context_user = user; context_user = user;
return #action($vasplat()); return #action($vasplat);
}; };
} }

View File

@@ -40,7 +40,6 @@ int comment_level = 0;
"$alignof" { count(); return(CT_ALIGNOF); } "$alignof" { count(); return(CT_ALIGNOF); }
"$and" { count(); return(CT_AND); }
"$assert" { count(); return(CT_ASSERT); } "$assert" { count(); return(CT_ASSERT); }
"$assignable" { count(); return(CT_ASSIGNABLE); } "$assignable" { count(); return(CT_ASSIGNABLE); }
"$case" { count(); return(CT_CASE); } "$case" { count(); return(CT_CASE); }
@@ -55,6 +54,7 @@ int comment_level = 0;
"$error" { count(); return(CT_ERROR); } "$error" { count(); return(CT_ERROR); }
"$eval" { count(); return(CT_EVAL); } "$eval" { count(); return(CT_EVAL); }
"$evaltype" { count(); return(CT_EVALTYPE); } "$evaltype" { count(); return(CT_EVALTYPE); }
"$exec" { count(); return(CT_EXEC); }
"$extnameof" { count(); return(CT_EXTNAMEOF); } "$extnameof" { count(); return(CT_EXTNAMEOF); }
"$feature" { count(); return(CT_FEATURE); } "$feature" { count(); return(CT_FEATURE); }
"$for" { count(); return(CT_FOR); } "$for" { count(); return(CT_FOR); }
@@ -195,6 +195,9 @@ b64\`{B64}\` { count(); return(BYTES); }
"!!" { count(); return(BANGBANG); } "!!" { count(); return(BANGBANG); }
"..." { count(); return(ELLIPSIS); } "..." { count(); return(ELLIPSIS); }
".." { count(); return(DOTDOT); } ".." { count(); return(DOTDOT); }
"&&&" { count(); return(CT_AND_OP); }
"|||" { count(); return(CT_OR_OP); }
"+++" { count(); return(CT_CONCAT_OP); }
">>=" { count(); return(SHR_ASSIGN); } ">>=" { count(); return(SHR_ASSIGN); }
"<<=" { count(); return(SHL_ASSIGN); } "<<=" { count(); return(SHL_ASSIGN); }
"+=" { count(); return(ADD_ASSIGN); } "+=" { count(); return(ADD_ASSIGN); }

View File

@@ -14,6 +14,7 @@ void yyerror(const char *s);
%token TYPE_IDENT CT_TYPE_IDENT %token TYPE_IDENT CT_TYPE_IDENT
%token AT_TYPE_IDENT AT_IDENT CT_INCLUDE %token AT_TYPE_IDENT AT_IDENT CT_INCLUDE
%token STRING_LITERAL INTEGER %token STRING_LITERAL INTEGER
%token CT_AND_OP CT_OR_OP CT_CONCAT_OP CT_EXEC
%token INC_OP DEC_OP SHL_OP SHR_OP LE_OP GE_OP EQ_OP NE_OP %token INC_OP DEC_OP SHL_OP SHR_OP LE_OP GE_OP EQ_OP NE_OP
%token AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN %token AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
%token LGENPAR RGENPAR %token LGENPAR RGENPAR
@@ -90,7 +91,7 @@ ct_analyse
| CT_IS_CONST | CT_IS_CONST
; ;
ct_arg ct_vaarg
: CT_VACONST : CT_VACONST
| CT_VAARG | CT_VAARG
| CT_VAREF | CT_VAREF
@@ -146,11 +147,10 @@ base_expr_assignable
| '(' expr ')' | '(' expr ')'
| expr_block | expr_block
| ct_call '(' flat_path ')' | ct_call '(' flat_path ')'
| ct_arg '(' expr ')' | ct_vaarg '[' expr ']'
| ct_analyse '(' expression_list ')' | ct_analyse '(' expression_list ')'
| CT_VACOUNT | CT_VACOUNT
| CT_FEATURE '(' CONST_IDENT ')' | CT_FEATURE '(' CONST_IDENT ')'
| CT_AND '(' expression_list ')'
| ct_castable '(' expr ',' type ')' | ct_castable '(' expr ',' type ')'
| lambda_decl compound_statement | lambda_decl compound_statement
; ;
@@ -333,21 +333,25 @@ try_chain_expr
and_expr and_expr
: relational_expr : relational_expr
| and_expr AND_OP relational_expr | and_expr AND_OP relational_expr
| and_expr CT_AND_OP relational_expr
; ;
and_stmt_expr and_stmt_expr
: relational_stmt_expr : relational_stmt_expr
| and_stmt_expr AND_OP relational_expr | and_stmt_expr AND_OP relational_expr
| and_stmt_expr CT_AND_OP relational_expr
; ;
or_expr or_expr
: and_expr : and_expr
| or_expr OR_OP and_expr | or_expr OR_OP and_expr
| or_expr CT_OR_OP and_expr
; ;
or_stmt_expr or_stmt_expr
: and_stmt_expr : and_stmt_expr
| or_stmt_expr OR_OP and_expr | or_stmt_expr OR_OP and_expr
| or_stmt_expr CT_OR_OP and_expr
; ;
suffix_expr suffix_expr
@@ -445,8 +449,7 @@ arg
| type | type
| param_path '=' type | param_path '=' type
| expr | expr
| CT_VASPLAT '(' range_expr ')' | CT_VASPLAT '[' range_expr ']'
| CT_VASPLAT '(' ')'
| ELLIPSIS expr | ELLIPSIS expr
; ;
@@ -532,7 +535,7 @@ base_type
| CT_TYPE_IDENT | CT_TYPE_IDENT
| CT_TYPEOF '(' expr ')' | CT_TYPEOF '(' expr ')'
| CT_TYPEFROM '(' constant_expr ')' | CT_TYPEFROM '(' constant_expr ')'
| CT_VATYPE '(' constant_expr ')' | CT_VATYPE '[' constant_expr ']'
| CT_EVALTYPE '(' constant_expr ')' | CT_EVALTYPE '(' constant_expr ')'
; ;
@@ -1233,9 +1236,16 @@ opt_extern
| empty | empty
; ;
exec_decl
: CT_EXEC '(' expr ')' opt_attributes ';'
| CT_EXEC '(' expr ',' initializer_list ')' opt_attributes ';'
| CT_EXEC '(' expr ',' initializer_list ',' expr ')' opt_attributes ';'
;
top_level top_level
: module : module
| import_decl | import_decl
| exec_decl
| opt_extern func_definition | opt_extern func_definition
| opt_extern const_declaration | opt_extern const_declaration
| opt_extern global_declaration | opt_extern global_declaration

View File

@@ -110,7 +110,7 @@ void print_type(FILE *file, TypeInfo *type)
PRINTF("$typeof(%s)", scratch_buffer_to_string()); PRINTF("$typeof(%s)", scratch_buffer_to_string());
break; break;
case TYPE_INFO_VATYPE: case TYPE_INFO_VATYPE:
PRINTF("$vatype(...)"); PRINTF("$vatype[...]");
break; break;
case TYPE_INFO_EVALTYPE: case TYPE_INFO_EVALTYPE:
PRINTF("$evaltype(...)"); PRINTF("$evaltype(...)");

View File

@@ -449,18 +449,34 @@ static Expr *parse_lambda(ParseContext *c, Expr *left)
/** /**
* vasplat ::= CT_VASPLAT '(' range_expr ')' * vasplat ::= CT_VASPLAT '(' range_expr ')'
* -> TODO, this is the only one in 0.7
* vasplat ::= CT_VASPLAT ('[' range_expr ']')?
*/ */
Expr *parse_vasplat(ParseContext *c) Expr *parse_vasplat(ParseContext *c)
{ {
Expr *expr = EXPR_NEW_TOKEN(EXPR_VASPLAT); Expr *expr = EXPR_NEW_TOKEN(EXPR_VASPLAT);
advance_and_verify(c, TOKEN_CT_VASPLAT); advance_and_verify(c, TOKEN_CT_VASPLAT);
TRY_CONSUME_OR_RET(TOKEN_LPAREN, "'$vasplat' must be followed by '()'.", poisoned_expr); bool lparen = try_consume(c, TOKEN_LPAREN);
if (!try_consume(c, TOKEN_RPAREN)) if (lparen && try_consume(c, TOKEN_RPAREN)) goto END;
if (lparen || try_consume(c, TOKEN_LBRACKET))
{ {
if (!parse_range(c, &expr->vasplat_expr)) return poisoned_expr; if (!parse_range(c, &expr->vasplat_expr)) return poisoned_expr;
CONSUME_OR_RET(TOKEN_RPAREN, poisoned_expr); CONSUME_OR_RET(lparen ? TOKEN_RPAREN : TOKEN_RBRACKET, poisoned_expr);
} }
RANGE_EXTEND_PREV(expr); RANGE_EXTEND_PREV(expr);
END:
// TODO remove in 0.7
if (lparen && !compiler.context.silence_deprecation)
{
if (expr->vasplat_expr.end || expr->vasplat_expr.start)
{
SEMA_NOTE(expr, "'$vasplat(...)' is deprecated, use '$vasplat[...]' instead.");
}
else
{
SEMA_NOTE(expr, "'$vasplat()' is deprecated, use '$vasplat' instead.");
}
}
return expr; return expr;
} }
/** /**
@@ -1207,9 +1223,17 @@ static Expr *parse_ct_arg(ParseContext *c, Expr *left)
advance(c); advance(c);
if (type != TOKEN_CT_VACOUNT) if (type != TOKEN_CT_VACOUNT)
{ {
CONSUME_OR_RET(TOKEN_LPAREN, poisoned_expr); // TODO remove in 0.7
bool is_lparen = try_consume(c, TOKEN_LPAREN);
if (!is_lparen) CONSUME_OR_RET(TOKEN_LBRACKET, poisoned_expr);
ASSIGN_EXPRID_OR_RET(expr->ct_arg_expr.arg, parse_expr(c), poisoned_expr); ASSIGN_EXPRID_OR_RET(expr->ct_arg_expr.arg, parse_expr(c), poisoned_expr);
CONSUME_OR_RET(TOKEN_RPAREN, poisoned_expr); CONSUME_OR_RET(is_lparen ? TOKEN_RPAREN : TOKEN_RBRACKET, poisoned_expr);
// TODO remove in 0.7
if (is_lparen && !compiler.context.silence_deprecation)
{
SEMA_NOTE(expr, "'%s(...)' is deprecated, use '%s[...]' instead.",
token_type_to_string(type), token_type_to_string(type));
}
} }
RANGE_EXTEND_PREV(expr); RANGE_EXTEND_PREV(expr);
return expr; return expr;

View File

@@ -421,10 +421,16 @@ static inline TypeInfo *parse_base_type(ParseContext *c)
if (try_consume(c, TOKEN_CT_VATYPE)) if (try_consume(c, TOKEN_CT_VATYPE))
{ {
TypeInfo *type_info = type_info_new(TYPE_INFO_VATYPE, c->prev_span); TypeInfo *type_info = type_info_new(TYPE_INFO_VATYPE, c->prev_span);
CONSUME_OR_RET(TOKEN_LPAREN, poisoned_type_info); bool is_lparen = try_consume(c, TOKEN_LPAREN);
if (!is_lparen) CONSUME_OR_RET(TOKEN_LBRACKET, poisoned_type_info);
ASSIGN_EXPR_OR_RET(type_info->unresolved_type_expr, parse_expr(c), poisoned_type_info); ASSIGN_EXPR_OR_RET(type_info->unresolved_type_expr, parse_expr(c), poisoned_type_info);
CONSUME_OR_RET(TOKEN_RPAREN, poisoned_type_info); CONSUME_OR_RET(is_lparen ? TOKEN_RPAREN : TOKEN_RBRACKET, poisoned_type_info);
RANGE_EXTEND_PREV(type_info); RANGE_EXTEND_PREV(type_info);
// TODO remove in 0.7
if (is_lparen && !compiler.context.silence_deprecation)
{
SEMA_NOTE(type_info, "'$vatype(...)' is deprecated, use '$vatype[...]' instead.");
}
return type_info; return type_info;
} }
if (try_consume(c, TOKEN_CT_EVALTYPE)) if (try_consume(c, TOKEN_CT_EVALTYPE))

View File

@@ -4774,7 +4774,7 @@ static Expr **sema_vasplat_append(SemaContext *context, Expr **init_expressions,
{ {
if (!range->is_range) if (!range->is_range)
{ {
SEMA_ERROR(expr, "$vasplat() expected a range."); SEMA_ERROR(expr, "$vasplat expected a range.");
return NULL; return NULL;
} }
if (!sema_analyse_expr(context, start)) return NULL; if (!sema_analyse_expr(context, start)) return NULL;

View File

@@ -6,10 +6,10 @@ import std::io;
macro print_type_info(...) macro print_type_info(...)
{ {
$for (var $i = 0; $i < $vacount; $i++) $for (var $i = 0; $i < $vacount; $i++)
io::printfn("type: %s", $vatype($i).nameof); io::printfn("type: %s", $vatype[$i].nameof);
io::printfn("%s.sizeof = %d", $vatype($i).nameof, $vatype($i).sizeof); io::printfn("%s.sizeof = %d", $vatype[$i].nameof, $vatype[$i].sizeof);
io::printfn("%s.min = %s", $vatype($i).nameof, $vatype($i).min); io::printfn("%s.min = %s", $vatype[$i].nameof, $vatype[$i].min);
io::printfn("%s.max = %s\n", $vatype($i).nameof, $vatype($i).max); io::printfn("%s.max = %s\n", $vatype[$i].nameof, $vatype[$i].max);
$endfor; $endfor;
} }

View File

@@ -1,20 +1,20 @@
macro foo(...) macro foo(...)
{ {
$vaarg("hello"); // #error: Expected the argument index here $vaarg["hello"]; // #error: Expected the argument index here
int x; int x;
$vaarg(x); // #error: Vararg functions need a constant argument $vaarg[x]; // #error: Vararg functions need a constant argument
$vaarg(-1); // #error: negative $vaarg[-1]; // #error: negative
$vaarg(100); // #error: varargs exist $vaarg[100]; // #error: varargs exist
} }
macro foo2(...) macro foo2(...)
{ {
$vaconst(0); $vaconst[0];
} }
macro foo3(...) macro foo3(...)
{ {
$vatype(0) a; $vatype[0] a;
} }
fn void main() fn void main()
{ {

View File

@@ -6,10 +6,10 @@ import std::io;
macro @foo(...) macro @foo(...)
{ {
int i = $vaarg(1) + $vaarg(1); int i = $vaarg[1] + $vaarg[1];
int j = $vaexpr(2) + $vaexpr(2); int j = $vaexpr[2] + $vaexpr[2];
$for (var $i = 0; $i < $vacount; $i++) $for (var $i = 0; $i < $vacount; $i++)
io::printfn("%d", $vaarg($i)); io::printfn("%d", $vaarg[$i]);
$endfor; $endfor;
} }
@@ -17,9 +17,9 @@ macro foo2(...)
{ {
$for (var $i = 0; $i < $vacount; $i++) $for (var $i = 0; $i < $vacount; $i++)
{ {
$vatype($i) x; $vatype[$i] x;
} }
io::printfn("%s", $vatype($i).nameof); io::printfn("%s", $vatype[$i].nameof);
$endfor; $endfor;
} }
@@ -34,9 +34,9 @@ macro foo3(...)
macro @foo4(...) macro @foo4(...)
{ {
$typeof(*$varef(0)) a = *$varef(0); $typeof(*$varef[0]) a = *$varef[0];
*$varef(0) = *$varef(1); *$varef[0] = *$varef[1];
*$varef(1) = a; *$varef[1] = a;
} }
fn int ping(int val) fn int ping(int val)
{ {

View File

@@ -4,47 +4,47 @@ import std::io;
macro @hello(...) macro @hello(...)
{ {
int[*] a = { 1, $vasplat(), 3 }; int[*] a = { 1, $vasplat, 3 };
foreach (i, x : a) io::printfn("%d: %d", i, x); foreach (i, x : a) io::printfn("%d: %d", i, x);
} }
macro @hello1(...) macro @hello1(...)
{ {
int[*] a = { 1, $vasplat() }; int[*] a = { 1, $vasplat };
foreach (i, x : a) io::printfn("x:%d: %d", i, x); foreach (i, x : a) io::printfn("x:%d: %d", i, x);
} }
macro @hello2(...) macro @hello2(...)
{ {
int[*] a = { $vasplat(), 888 }; int[*] a = { $vasplat, 888 };
foreach (i, x : a) io::printfn("x:%d: %d", i, x); foreach (i, x : a) io::printfn("x:%d: %d", i, x);
} }
macro @hello3(...) macro @hello3(...)
{ {
int[*] a = { $vasplat() }; int[*] a = { $vasplat };
foreach (i, x : a) io::printfn("x:%d: %d", i, x); foreach (i, x : a) io::printfn("x:%d: %d", i, x);
} }
macro @hello4(...) macro @hello4(...)
{ {
int[*] a = { 5, $vasplat(2..4), 77 }; int[*] a = { 5, $vasplat[2..4], 77 };
foreach (i, x : a) io::printfn("y:%d: %d", i, x); foreach (i, x : a) io::printfn("y:%d: %d", i, x);
} }
macro @hello5(...) macro @hello5(...)
{ {
int[*] a = { 5, $vasplat(2..), 77 }; int[*] a = { 5, $vasplat[2..], 77 };
foreach (i, x : a) io::printfn("y:%d: %d", i, x); foreach (i, x : a) io::printfn("y:%d: %d", i, x);
int[*] b = { 55, $vasplat(2..^2), 88 }; int[*] b = { 55, $vasplat[2..^2], 88 };
foreach (i, x : b) io::printfn("z:%d: %d", i, x); foreach (i, x : b) io::printfn("z:%d: %d", i, x);
int[*] c = { 55, $vasplat(0:^2), 88 }; int[*] c = { 55, $vasplat[0:^2], 88 };
foreach (i, x : c) io::printfn("zz:%d: %d", i, x); foreach (i, x : c) io::printfn("zz:%d: %d", i, x);
} }
macro @hello6(...) macro @hello6(...)
{ {
@hello(66, $vasplat()); @hello(66, $vasplat);
} }
fn void main() fn void main()
{ {

View File

@@ -5,7 +5,7 @@ import std::io;
macro test(start, ...) macro test(start, ...)
{ {
$for (var $i = 0; $i < $vacount; $i++) $for (var $i = 0; $i < $vacount; $i++)
for ($vatype($i) i = ($vatype($i))start; i < 5; i+=2) for ($vatype[$i] i = ($vatype[$i])start; i < 5; i+=2)
{ {
assert(math::is_even(i)); assert(math::is_even(i));
assert(i.is_even()); assert(i.is_even());