Added stringify tests and $typefrom. Bump to 0.3.50.

This commit is contained in:
Christoffer Lerno
2022-09-18 20:28:03 +02:00
committed by Christoffer Lerno
parent 62e3b8063e
commit e7fad16d0f
14 changed files with 137 additions and 8 deletions

View File

@@ -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);

View File

@@ -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.

View File

@@ -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 },

View File

@@ -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);

View File

@@ -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:

View File

@@ -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)

View File

@@ -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:

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.3.49"
#define COMPILER_VERSION "0.3.50"

View 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

View 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

View 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
}

View 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

View 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

View 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
}