mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
- Introduce $vaarg[...] syntax and deprecate the old $vaarg(...).
- Similar change to `$vasplat`: `$vasplat` and `$vasplat[1..]`.
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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); }
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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(...)");
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|||||||
Reference in New Issue
Block a user