mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Added stringify tests and $typefrom. Bump to 0.3.50.
This commit is contained in:
committed by
Christoffer Lerno
parent
62e3b8063e
commit
e7fad16d0f
@@ -583,8 +583,9 @@ TypeInfo *copy_type_info(CopyStruct *c, TypeInfo *source)
|
||||
case TYPE_INFO_CT_IDENTIFIER:
|
||||
case TYPE_INFO_IDENTIFIER:
|
||||
return copy;
|
||||
case TYPE_INFO_TYPEFROM:
|
||||
case TYPE_INFO_EVALTYPE:
|
||||
case TYPE_INFO_EXPRESSION:
|
||||
case TYPE_INFO_TYPEOF:
|
||||
case TYPE_INFO_VATYPE:
|
||||
assert(source->resolve_status == RESOLVE_NOT_DONE);
|
||||
copy->unresolved_type_expr = copy_expr(c, source->unresolved_type_expr);
|
||||
|
||||
@@ -359,9 +359,10 @@ typedef enum
|
||||
TYPE_INFO_POISON,
|
||||
TYPE_INFO_IDENTIFIER,
|
||||
TYPE_INFO_CT_IDENTIFIER,
|
||||
TYPE_INFO_EXPRESSION,
|
||||
TYPE_INFO_TYPEOF,
|
||||
TYPE_INFO_VATYPE,
|
||||
TYPE_INFO_EVALTYPE,
|
||||
TYPE_INFO_TYPEFROM,
|
||||
TYPE_INFO_ARRAY,
|
||||
TYPE_INFO_VECTOR,
|
||||
TYPE_INFO_INFERRED_ARRAY,
|
||||
@@ -563,6 +564,7 @@ typedef enum
|
||||
TOKEN_CT_SIZEOF, // $sizeof
|
||||
TOKEN_CT_STRINGIFY, // $stringify
|
||||
TOKEN_CT_SWITCH, // $switch
|
||||
TOKEN_CT_TYPEFROM, // $typefrom
|
||||
TOKEN_CT_TYPEOF, // $typeof
|
||||
TOKEN_CT_CONVERTIBLE, // $convertible
|
||||
TOKEN_CT_CASTABLE, // $castable
|
||||
@@ -592,7 +594,7 @@ typedef enum
|
||||
#define TYPE_TOKENS NON_VOID_TYPE_TOKENS: case TOKEN_VOID
|
||||
#define TYPELIKE_TOKENS TYPE_TOKENS: case TOKEN_TYPE_IDENT: \
|
||||
case TOKEN_CT_TYPE_IDENT: case TOKEN_CT_TYPEOF: case TOKEN_CT_EVALTYPE: \
|
||||
case TOKEN_CT_VATYPE
|
||||
case TOKEN_CT_VATYPE: case TOKEN_CT_TYPEFROM
|
||||
|
||||
// Note that ordering matters here. If ordering is changed,
|
||||
// So must type_find_max_type and friends.
|
||||
|
||||
@@ -875,7 +875,7 @@ static Expr *parse_ct_sizeof(ParseContext *c, Expr *left)
|
||||
ASSIGN_EXPR_OR_RET(Expr *inner, parse_expr(c), poisoned_expr);
|
||||
CONSUME_OR_RET(TOKEN_RPAREN, poisoned_expr);
|
||||
Expr *typeof_expr = expr_new(EXPR_TYPEINFO, inner->span);
|
||||
TypeInfo *type_info = type_info_new(TYPE_INFO_EXPRESSION, inner->span);
|
||||
TypeInfo *type_info = type_info_new(TYPE_INFO_TYPEOF, inner->span);
|
||||
type_info->unresolved_type_expr = inner;
|
||||
typeof_expr->type_expr = type_info;
|
||||
access->access_expr.parent = typeof_expr;
|
||||
@@ -1767,6 +1767,7 @@ ParseRule rules[TOKEN_EOF + 1] = {
|
||||
[TOKEN_CT_OFFSETOF] = { parse_ct_call, NULL, PREC_NONE },
|
||||
[TOKEN_CT_NAMEOF] = { parse_ct_call, NULL, PREC_NONE },
|
||||
[TOKEN_CT_QNAMEOF] = { parse_ct_call, NULL, PREC_NONE },
|
||||
[TOKEN_CT_TYPEFROM] = { parse_type_expr, NULL, PREC_NONE },
|
||||
[TOKEN_CT_TYPEOF] = { parse_type_expr, NULL, PREC_NONE },
|
||||
[TOKEN_CT_STRINGIFY] = { parse_ct_stringify, NULL, PREC_NONE },
|
||||
[TOKEN_CT_EVALTYPE] = { parse_type_expr, NULL, PREC_NONE },
|
||||
|
||||
@@ -482,9 +482,18 @@ Path *parse_path_prefix(ParseContext *c, bool *had_error)
|
||||
*/
|
||||
static inline TypeInfo *parse_base_type(ParseContext *c)
|
||||
{
|
||||
if (try_consume(c, TOKEN_CT_TYPEFROM))
|
||||
{
|
||||
TypeInfo *type_info = type_info_new(TYPE_INFO_TYPEFROM, c->prev_span);
|
||||
CONSUME_OR_RET(TOKEN_LPAREN, 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);
|
||||
RANGE_EXTEND_PREV(type_info);
|
||||
return type_info;
|
||||
}
|
||||
if (try_consume(c, TOKEN_CT_TYPEOF))
|
||||
{
|
||||
TypeInfo *type_info = type_info_new(TYPE_INFO_EXPRESSION, c->prev_span);
|
||||
TypeInfo *type_info = type_info_new(TYPE_INFO_TYPEOF, c->prev_span);
|
||||
CONSUME_OR_RET(TOKEN_LPAREN, 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);
|
||||
|
||||
@@ -7857,7 +7857,8 @@ RETRY:
|
||||
case TYPE_INFO_VATYPE:
|
||||
if (!sema_resolve_type_info(context, type_info)) return poisoned_type;
|
||||
return type_info->type->canonical;
|
||||
case TYPE_INFO_EXPRESSION:
|
||||
case TYPE_INFO_TYPEFROM:
|
||||
case TYPE_INFO_TYPEOF:
|
||||
if (!sema_resolve_type_info(context, type_info)) return poisoned_type;
|
||||
return type_info->type;
|
||||
case TYPE_INFO_EVALTYPE:
|
||||
|
||||
@@ -308,7 +308,7 @@ RETRY:
|
||||
return type_info_poison(type_info);
|
||||
}
|
||||
}
|
||||
case TYPE_INFO_EXPRESSION:
|
||||
case TYPE_INFO_TYPEOF:
|
||||
{
|
||||
Expr *expr = type_info->unresolved_type_expr;
|
||||
if (!sema_analyse_expr(context, expr))
|
||||
@@ -320,6 +320,23 @@ RETRY:
|
||||
assert(!type_info->failable);
|
||||
goto APPEND_QUALIFIERS;
|
||||
}
|
||||
case TYPE_INFO_TYPEFROM:
|
||||
{
|
||||
Expr *expr = type_info->unresolved_type_expr;
|
||||
if (!sema_analyse_expr(context, expr))
|
||||
{
|
||||
return type_info_poison(type_info);
|
||||
}
|
||||
if (!expr_is_const(expr) || expr->const_expr.const_kind != CONST_TYPEID)
|
||||
{
|
||||
SEMA_ERROR(expr, "Expected a constant typeid value.");
|
||||
return type_info_poison(type_info);
|
||||
}
|
||||
type_info->type = expr->const_expr.typeid;
|
||||
type_info->resolve_status = RESOLVE_DONE;
|
||||
assert(!type_info->failable);
|
||||
goto APPEND_QUALIFIERS;
|
||||
}
|
||||
case TYPE_INFO_INFERRED_ARRAY:
|
||||
case TYPE_INFO_INFERRED_VECTOR:
|
||||
if (!allow_inferred_type)
|
||||
|
||||
@@ -382,6 +382,8 @@ const char *token_type_to_string(TokenType type)
|
||||
return "$sizeof";
|
||||
case TOKEN_CT_SWITCH:
|
||||
return "$switch";
|
||||
case TOKEN_CT_TYPEFROM:
|
||||
return "$typefrom";
|
||||
case TOKEN_CT_TYPEOF:
|
||||
return "$typeof";
|
||||
case TOKEN_CT_CONVERTIBLE:
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define COMPILER_VERSION "0.3.49"
|
||||
#define COMPILER_VERSION "0.3.50"
|
||||
20
test/test_suite/compile_time/stringify2.c3t
Normal file
20
test/test_suite/compile_time/stringify2.c3t
Normal file
@@ -0,0 +1,20 @@
|
||||
// #target: macos-x64
|
||||
module test;
|
||||
import std::io;
|
||||
|
||||
fn void main()
|
||||
{
|
||||
var $s1 = $stringify(1 + 2);
|
||||
char[*] s2 = $stringify($s1);
|
||||
char[] s3 = $s1;
|
||||
|
||||
io::printfln("$s1 == %s", $s1);
|
||||
io::printfln("s2 == %s", &s2);
|
||||
io::printfln("s3 == %s", s3);
|
||||
}
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
c"$s1\00", align 1
|
||||
c"1 + 2\00", align 1
|
||||
c"1 + 2\00", align 1
|
||||
15
test/test_suite/compile_time/typefrom.c3t
Normal file
15
test/test_suite/compile_time/typefrom.c3t
Normal file
@@ -0,0 +1,15 @@
|
||||
// #target: macos-x64
|
||||
|
||||
module test;
|
||||
|
||||
|
||||
fn int main()
|
||||
{
|
||||
var $foo = double.typeid;
|
||||
$typefrom($foo) a = 123.0;
|
||||
return (int)a;
|
||||
}
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
%a = alloca double, align 8
|
||||
13
test/test_suite/compile_time/typefrom_errors.c3t
Normal file
13
test/test_suite/compile_time/typefrom_errors.c3t
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
fn void test()
|
||||
{
|
||||
typeid x;
|
||||
$typefrom(2 > 1 ? int.typeid : double.typeid) xf;
|
||||
$typefrom(x) a; // #error: Expected a constant
|
||||
}
|
||||
|
||||
fn void test2()
|
||||
{
|
||||
var $x = 1;
|
||||
$typefrom($x) a; // #error: Expected a constant
|
||||
}
|
||||
20
test/test_suite2/compile_time/stringify2.c3t
Normal file
20
test/test_suite2/compile_time/stringify2.c3t
Normal file
@@ -0,0 +1,20 @@
|
||||
// #target: macos-x64
|
||||
module test;
|
||||
import std::io;
|
||||
|
||||
fn void main()
|
||||
{
|
||||
var $s1 = $stringify(1 + 2);
|
||||
char[*] s2 = $stringify($s1);
|
||||
char[] s3 = $s1;
|
||||
|
||||
io::printfln("$s1 == %s", $s1);
|
||||
io::printfln("s2 == %s", &s2);
|
||||
io::printfln("s3 == %s", s3);
|
||||
}
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
c"$s1\00", align 1
|
||||
c"1 + 2\00", align 1
|
||||
c"1 + 2\00", align 1
|
||||
15
test/test_suite2/compile_time/typefrom.c3t
Normal file
15
test/test_suite2/compile_time/typefrom.c3t
Normal file
@@ -0,0 +1,15 @@
|
||||
// #target: macos-x64
|
||||
|
||||
module test;
|
||||
|
||||
|
||||
fn int main()
|
||||
{
|
||||
var $foo = double.typeid;
|
||||
$typefrom($foo) a = 123.0;
|
||||
return (int)a;
|
||||
}
|
||||
|
||||
/* #expect: test.ll
|
||||
|
||||
%a = alloca double, align 8
|
||||
13
test/test_suite2/compile_time/typefrom_errors.c3t
Normal file
13
test/test_suite2/compile_time/typefrom_errors.c3t
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
fn void test()
|
||||
{
|
||||
typeid x;
|
||||
$typefrom(2 > 1 ? int.typeid : double.typeid) xf;
|
||||
$typefrom(x) a; // #error: Expected a constant
|
||||
}
|
||||
|
||||
fn void test2()
|
||||
{
|
||||
var $x = 1;
|
||||
$typefrom($x) a; // #error: Expected a constant
|
||||
}
|
||||
Reference in New Issue
Block a user