mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Dev (#404)
Remove 'errtype' name and reduce Expr / TypeInfo memory footprint.
This commit is contained in:
committed by
GitHub
parent
069a2d40cb
commit
322d714305
@@ -2,7 +2,7 @@ module base64;
|
|||||||
// Based on the C2 version.
|
// Based on the C2 version.
|
||||||
|
|
||||||
|
|
||||||
errtype DecodingError
|
optenum DecodingError
|
||||||
{
|
{
|
||||||
INVALID_CHARACTER
|
INVALID_CHARACTER
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ const char *decl_to_name(Decl *decl)
|
|||||||
case DECL_OPTVALUE:
|
case DECL_OPTVALUE:
|
||||||
return "err value";
|
return "err value";
|
||||||
case DECL_OPTENUM:
|
case DECL_OPTENUM:
|
||||||
return "errtype";
|
return "optenum";
|
||||||
case DECL_FUNC:
|
case DECL_FUNC:
|
||||||
return "function";
|
return "function";
|
||||||
case DECL_GENERIC:
|
case DECL_GENERIC:
|
||||||
|
|||||||
@@ -14,9 +14,6 @@ BuildTarget active_target;
|
|||||||
|
|
||||||
Vmem ast_arena;
|
Vmem ast_arena;
|
||||||
Vmem expr_arena;
|
Vmem expr_arena;
|
||||||
Vmem sourceloc_arena;
|
|
||||||
Vmem toktype_arena;
|
|
||||||
Vmem tokdata_arena;
|
|
||||||
Vmem decl_arena;
|
Vmem decl_arena;
|
||||||
Vmem type_info_arena;
|
Vmem type_info_arena;
|
||||||
|
|
||||||
@@ -40,9 +37,6 @@ void compiler_init(const char *std_lib_dir)
|
|||||||
vmem_init(&ast_arena, 4 * 1024);
|
vmem_init(&ast_arena, 4 * 1024);
|
||||||
vmem_init(&expr_arena, 4 * 1024);
|
vmem_init(&expr_arena, 4 * 1024);
|
||||||
vmem_init(&decl_arena, 1024);
|
vmem_init(&decl_arena, 1024);
|
||||||
vmem_init(&sourceloc_arena, 4 * 1024);
|
|
||||||
vmem_init(&toktype_arena, 4 * 1024);
|
|
||||||
vmem_init(&tokdata_arena, 4 * 1024);
|
|
||||||
vmem_init(&type_info_arena, 1024);
|
vmem_init(&type_info_arena, 1024);
|
||||||
// Create zero index value.
|
// Create zero index value.
|
||||||
if (std_lib_dir)
|
if (std_lib_dir)
|
||||||
@@ -129,14 +123,24 @@ static void free_arenas(void)
|
|||||||
{
|
{
|
||||||
if (debug_stats)
|
if (debug_stats)
|
||||||
{
|
{
|
||||||
printf("-- AST/EXPR INFO -- \n");
|
printf("-- AST/EXPR/TYPE INFO -- \n");
|
||||||
printf(" * Ast memory use: %llukb\n", (unsigned long long)ast_arena.allocated / 1024);
|
printf(" * Ast size: %u bytes\n", (unsigned)sizeof(Ast));
|
||||||
printf(" * Decl memory use: %llukb\n", (unsigned long long)decl_arena.allocated / 1024);
|
printf(" * Decl size: %u bytes\n", (unsigned)sizeof(Decl));
|
||||||
printf(" * Expr memory use: %llukb\n", (unsigned long long)expr_arena.allocated / 1024);
|
printf(" * Expr size: %u bytes\n", (unsigned)sizeof(Expr));
|
||||||
printf(" * TypeInfo memory use: %llukb\n", (unsigned long long)type_info_arena.allocated / 1024);
|
printf(" * TypeInfo size: %u bytes\n", (unsigned)sizeof(TypeInfo));
|
||||||
printf(" * Token memory use: %llukb\n", (unsigned long long)(toktype_arena.allocated) / 1024);
|
printf(" * Ast memory use: %llukb (%u elements)\n",
|
||||||
printf(" * Sourceloc memory use: %llukb\n", (unsigned long long)(sourceloc_arena.allocated) / 1024);
|
(unsigned long long)ast_arena.allocated / 1024,
|
||||||
printf(" * Token data memory use: %llukb\n", (unsigned long long)(tokdata_arena.allocated) / 1024);
|
(unsigned)(ast_arena.allocated / sizeof(Ast)));
|
||||||
|
printf(" * Decl memory use: %llukb (%u elements)\n",
|
||||||
|
(unsigned long long)decl_arena.allocated / 1024,
|
||||||
|
(unsigned)(decl_arena.allocated / sizeof(Decl)));
|
||||||
|
printf(" * Expr memory use: %llukb (%u elements)\n",
|
||||||
|
(unsigned long long)expr_arena.allocated / 1024,
|
||||||
|
(unsigned)(expr_arena.allocated / sizeof(Expr)));
|
||||||
|
printf(" * TypeInfo memory use: %llukb (%u elements)\n",
|
||||||
|
(unsigned long long)type_info_arena.allocated / 1024,
|
||||||
|
(unsigned)(type_info_arena.allocated / sizeof(TypeInfo)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_arena_free();
|
ast_arena_free();
|
||||||
|
|||||||
@@ -214,12 +214,6 @@ typedef struct
|
|||||||
unsigned pref_alignment : 8;
|
unsigned pref_alignment : 8;
|
||||||
} TypeBuiltin;
|
} TypeBuiltin;
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
const char *name;
|
|
||||||
SourceSpan span;
|
|
||||||
Path *path;
|
|
||||||
} TypeUnresolved;
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -265,13 +259,18 @@ struct Type_
|
|||||||
struct TypeInfo_
|
struct TypeInfo_
|
||||||
{
|
{
|
||||||
ResolveStatus resolve_status : 3;
|
ResolveStatus resolve_status : 3;
|
||||||
|
TypeInfoKind kind : 6;
|
||||||
bool failable : 1;
|
bool failable : 1;
|
||||||
Type *type;
|
Type *type;
|
||||||
TypeInfoKind kind;
|
|
||||||
SourceSpan span;
|
SourceSpan span;
|
||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
TypeUnresolved unresolved;
|
struct
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
Path *path;
|
||||||
|
} unresolved;
|
||||||
Expr *unresolved_type_expr;
|
Expr *unresolved_type_expr;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
@@ -287,7 +286,7 @@ typedef struct
|
|||||||
{
|
{
|
||||||
Path *path;
|
Path *path;
|
||||||
const char *name;
|
const char *name;
|
||||||
SourceSpan name_span;
|
SourceSpan span;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
Expr *expr;
|
Expr *expr;
|
||||||
@@ -607,7 +606,7 @@ typedef struct Decl_
|
|||||||
Decl **methods;
|
Decl **methods;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
// Unions, Errtype and Struct use strukt
|
// Unions, Optenum and Struct use strukt
|
||||||
StructDecl strukt;
|
StructDecl strukt;
|
||||||
EnumDecl enums;
|
EnumDecl enums;
|
||||||
DistinctDecl distinct_decl;
|
DistinctDecl distinct_decl;
|
||||||
@@ -693,7 +692,6 @@ typedef struct
|
|||||||
};
|
};
|
||||||
Expr **arguments;
|
Expr **arguments;
|
||||||
Decl **body_arguments;
|
Decl **body_arguments;
|
||||||
Attr **attributes;
|
|
||||||
} ExprCall;
|
} ExprCall;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -926,9 +924,9 @@ typedef struct
|
|||||||
|
|
||||||
struct Expr_
|
struct Expr_
|
||||||
{
|
{
|
||||||
|
SourceSpan span;
|
||||||
ExprKind expr_kind : 8;
|
ExprKind expr_kind : 8;
|
||||||
ResolveStatus resolve_status : 4;
|
ResolveStatus resolve_status : 4;
|
||||||
SourceSpan span;
|
|
||||||
Type *type;
|
Type *type;
|
||||||
union {
|
union {
|
||||||
ExprVariantSwitch variant_switch; // 32
|
ExprVariantSwitch variant_switch; // 32
|
||||||
@@ -946,7 +944,7 @@ struct Expr_
|
|||||||
ExprUnary unary_expr; // 16
|
ExprUnary unary_expr; // 16
|
||||||
Expr** try_unwrap_chain_expr; // 8
|
Expr** try_unwrap_chain_expr; // 8
|
||||||
ExprTryUnwrap try_unwrap_expr; // 24
|
ExprTryUnwrap try_unwrap_expr; // 24
|
||||||
ExprCall call_expr; // 40
|
ExprCall call_expr; // 32
|
||||||
ExprSlice slice_expr; // 32
|
ExprSlice slice_expr; // 32
|
||||||
Expr *inner_expr; // 8
|
Expr *inner_expr; // 8
|
||||||
ExprCatchUnwrap catch_unwrap_expr; // 24
|
ExprCatchUnwrap catch_unwrap_expr; // 24
|
||||||
@@ -972,9 +970,9 @@ struct Expr_
|
|||||||
ExprBuiltin builtin_expr; // 16
|
ExprBuiltin builtin_expr; // 16
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
static_assert(sizeof(ExprCall) == 40, "Ooops");
|
//static_assert(sizeof(ExprCall) == 32, "Ooops");
|
||||||
|
|
||||||
static_assert(sizeof(Expr) == 64, "Ooops");
|
//static_assert(sizeof(Expr) == 56, "Ooops");
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -1599,6 +1597,7 @@ extern const char *kw_elementref;
|
|||||||
extern const char *kw_elementset;
|
extern const char *kw_elementset;
|
||||||
extern const char *kw_len;
|
extern const char *kw_len;
|
||||||
extern const char *kw_nan;
|
extern const char *kw_nan;
|
||||||
|
extern const char *kw_noinline;
|
||||||
extern const char *kw_main;
|
extern const char *kw_main;
|
||||||
extern const char *kw_ordinal;
|
extern const char *kw_ordinal;
|
||||||
extern const char *kw_reqparse;
|
extern const char *kw_reqparse;
|
||||||
|
|||||||
@@ -287,7 +287,6 @@ Expr *copy_expr(CopyStruct *c, Expr *source_expr)
|
|||||||
MACRO_COPY_ASTID(expr->call_expr.body);
|
MACRO_COPY_ASTID(expr->call_expr.body);
|
||||||
MACRO_COPY_DECL_LIST(expr->call_expr.body_arguments);
|
MACRO_COPY_DECL_LIST(expr->call_expr.body_arguments);
|
||||||
MACRO_COPY_EXPR_LIST(expr->call_expr.arguments);
|
MACRO_COPY_EXPR_LIST(expr->call_expr.arguments);
|
||||||
if (expr->call_expr.attributes) REMINDER("Copy attributes?");
|
|
||||||
return expr;
|
return expr;
|
||||||
case EXPR_SUBSCRIPT:
|
case EXPR_SUBSCRIPT:
|
||||||
case EXPR_SUBSCRIPT_ADDR:
|
case EXPR_SUBSCRIPT_ADDR:
|
||||||
|
|||||||
@@ -438,7 +438,6 @@ typedef enum
|
|||||||
TOKEN_DO,
|
TOKEN_DO,
|
||||||
TOKEN_ELSE,
|
TOKEN_ELSE,
|
||||||
TOKEN_ENUM,
|
TOKEN_ENUM,
|
||||||
TOKEN_ERRTYPE,
|
|
||||||
TOKEN_EXTERN,
|
TOKEN_EXTERN,
|
||||||
TOKEN_FALSE,
|
TOKEN_FALSE,
|
||||||
TOKEN_FOR,
|
TOKEN_FOR,
|
||||||
@@ -467,7 +466,6 @@ typedef enum
|
|||||||
TOKEN_ERRNUM,
|
TOKEN_ERRNUM,
|
||||||
TOKEN_OPTNUM,
|
TOKEN_OPTNUM,
|
||||||
TOKEN_OPTENUM,
|
TOKEN_OPTENUM,
|
||||||
TOKEN_RESNUM,
|
|
||||||
|
|
||||||
TOKEN_CT_ALIGNOF, // $alignof
|
TOKEN_CT_ALIGNOF, // $alignof
|
||||||
TOKEN_CT_ASSERT, // $assert
|
TOKEN_CT_ASSERT, // $assert
|
||||||
|
|||||||
@@ -711,7 +711,34 @@ static Expr *parse_call_expr(ParseContext *c, Expr *left)
|
|||||||
{
|
{
|
||||||
ASSIGN_ASTID_OR_RET(call->call_expr.body, parse_compound_stmt(c), poisoned_expr);
|
ASSIGN_ASTID_OR_RET(call->call_expr.body, parse_compound_stmt(c), poisoned_expr);
|
||||||
}
|
}
|
||||||
if (!parse_attributes(c, &call->call_expr.attributes)) return false;
|
Attr *attr;
|
||||||
|
int force_inline = -1;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (!parse_attribute(c, &attr)) return poisoned_expr;
|
||||||
|
if (!attr) break;
|
||||||
|
if (attr->name != kw_inline && attr->name != kw_noinline)
|
||||||
|
{
|
||||||
|
SEMA_ERROR(attr, "Only '@inline' and '@noinline' are valid attributes for calls.");
|
||||||
|
return poisoned_expr;
|
||||||
|
}
|
||||||
|
int new_inline = attr->name == kw_inline;
|
||||||
|
if (new_inline == force_inline)
|
||||||
|
{
|
||||||
|
SEMA_ERROR(attr, "Repeat of the same attribute is not allowed.");
|
||||||
|
return poisoned_expr;
|
||||||
|
}
|
||||||
|
if (force_inline != -1)
|
||||||
|
{
|
||||||
|
SEMA_ERROR(attr, "@inline and @noinline cannot be combined");
|
||||||
|
}
|
||||||
|
force_inline = new_inline;
|
||||||
|
}
|
||||||
|
if (force_inline != -1)
|
||||||
|
{
|
||||||
|
call->call_expr.force_inline = force_inline == 1;
|
||||||
|
call->call_expr.force_noinline = force_inline == 0;
|
||||||
|
}
|
||||||
return call;
|
return call;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -909,7 +936,6 @@ static Expr *parse_type_or_expression_with_path(ParseContext *c, Path *path, Typ
|
|||||||
{
|
{
|
||||||
type = type_info_new(TYPE_INFO_IDENTIFIER, path->span);
|
type = type_info_new(TYPE_INFO_IDENTIFIER, path->span);
|
||||||
type->unresolved.path = path;
|
type->unresolved.path = path;
|
||||||
type->unresolved.span = c->span;
|
|
||||||
type->unresolved.name = symstr(c);
|
type->unresolved.name = symstr(c);
|
||||||
advance_and_verify(c, TOKEN_TYPE_IDENT);
|
advance_and_verify(c, TOKEN_TYPE_IDENT);
|
||||||
RANGE_EXTEND_PREV(type);
|
RANGE_EXTEND_PREV(type);
|
||||||
@@ -1654,7 +1680,6 @@ Expr *parse_type_expression_with_path(ParseContext *c, Path *path)
|
|||||||
{
|
{
|
||||||
type = type_info_new(TYPE_INFO_IDENTIFIER, path->span);
|
type = type_info_new(TYPE_INFO_IDENTIFIER, path->span);
|
||||||
type->unresolved.path = path;
|
type->unresolved.path = path;
|
||||||
type->unresolved.span = c->span;
|
|
||||||
type->unresolved.name = symstr(c);
|
type->unresolved.name = symstr(c);
|
||||||
advance_and_verify(c, TOKEN_TYPE_IDENT);
|
advance_and_verify(c, TOKEN_TYPE_IDENT);
|
||||||
RANGE_EXTEND_PREV(type);
|
RANGE_EXTEND_PREV(type);
|
||||||
|
|||||||
@@ -38,11 +38,9 @@ void recover_top_level(ParseContext *c)
|
|||||||
case TOKEN_ENUM:
|
case TOKEN_ENUM:
|
||||||
case TOKEN_GENERIC:
|
case TOKEN_GENERIC:
|
||||||
case TOKEN_DEFINE:
|
case TOKEN_DEFINE:
|
||||||
case TOKEN_ERRTYPE:
|
|
||||||
case TOKEN_OPTENUM:
|
case TOKEN_OPTENUM:
|
||||||
case TOKEN_OPTNUM:
|
case TOKEN_OPTNUM:
|
||||||
case TOKEN_ERRNUM:
|
case TOKEN_ERRNUM:
|
||||||
case TOKEN_RESNUM:
|
|
||||||
return;
|
return;
|
||||||
case TOKEN_IDENT: // Incr arrays only
|
case TOKEN_IDENT: // Incr arrays only
|
||||||
case TOKEN_CONST:
|
case TOKEN_CONST:
|
||||||
@@ -514,7 +512,6 @@ static inline TypeInfo *parse_base_type(ParseContext *c)
|
|||||||
TypeInfo *type_info = type_info_new(TYPE_INFO_IDENTIFIER, range);
|
TypeInfo *type_info = type_info_new(TYPE_INFO_IDENTIFIER, range);
|
||||||
type_info->unresolved.path = path;
|
type_info->unresolved.path = path;
|
||||||
type_info->unresolved.name = symstr(c);
|
type_info->unresolved.name = symstr(c);
|
||||||
type_info->unresolved.span = c->span;
|
|
||||||
if (!consume_type_name(c, "type")) return poisoned_type_info;
|
if (!consume_type_name(c, "type")) return poisoned_type_info;
|
||||||
RANGE_EXTEND_PREV(type_info);
|
RANGE_EXTEND_PREV(type_info);
|
||||||
return type_info;
|
return type_info;
|
||||||
@@ -527,12 +524,10 @@ static inline TypeInfo *parse_base_type(ParseContext *c)
|
|||||||
case TOKEN_TYPE_IDENT:
|
case TOKEN_TYPE_IDENT:
|
||||||
type_info = type_info_new_curr(c, TYPE_INFO_IDENTIFIER);
|
type_info = type_info_new_curr(c, TYPE_INFO_IDENTIFIER);
|
||||||
type_info->unresolved.name = symstr(c);
|
type_info->unresolved.name = symstr(c);
|
||||||
type_info->unresolved.span = c->span;
|
|
||||||
break;
|
break;
|
||||||
case TOKEN_CT_TYPE_IDENT:
|
case TOKEN_CT_TYPE_IDENT:
|
||||||
type_info = type_info_new_curr(c, TYPE_INFO_CT_IDENTIFIER);
|
type_info = type_info_new_curr(c, TYPE_INFO_CT_IDENTIFIER);
|
||||||
type_info->unresolved.name = symstr(c);
|
type_info->unresolved.name = symstr(c);
|
||||||
type_info->unresolved.span = c->span;
|
|
||||||
break;
|
break;
|
||||||
case TYPE_TOKENS:
|
case TYPE_TOKENS:
|
||||||
type_found = type_from_token(c->tok);
|
type_found = type_from_token(c->tok);
|
||||||
@@ -819,7 +814,40 @@ Decl *parse_var_decl(ParseContext *c)
|
|||||||
|
|
||||||
// --- Parse parameters & throws & attributes
|
// --- Parse parameters & throws & attributes
|
||||||
|
|
||||||
|
bool parse_attribute(ParseContext *c, Attr **attribute_ref)
|
||||||
|
{
|
||||||
|
if (!try_consume(c, TOKEN_AT))
|
||||||
|
{
|
||||||
|
*attribute_ref = NULL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool had_error;
|
||||||
|
Path *path = parse_path_prefix(c, &had_error);
|
||||||
|
if (had_error) return false;
|
||||||
|
|
||||||
|
Attr *attr = CALLOCS(Attr);
|
||||||
|
|
||||||
|
attr->name = symstr(c);
|
||||||
|
attr->span = c->span;
|
||||||
|
attr->path = path;
|
||||||
|
|
||||||
|
if (tok_is(c, TOKEN_TYPE_IDENT) || tok_is(c, TOKEN_TYPE_IDENT))
|
||||||
|
{
|
||||||
|
advance(c);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TRY_CONSUME_OR_RET(TOKEN_IDENT, "Expected an attribute", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tok_is(c, TOKEN_LPAREN))
|
||||||
|
{
|
||||||
|
ASSIGN_EXPR_OR_RET(attr->expr, parse_const_paren_expr(c), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
*attribute_ref = attr;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* attribute_list
|
* attribute_list
|
||||||
* : attribute
|
* : attribute
|
||||||
@@ -839,38 +867,18 @@ bool parse_attributes(ParseContext *c, Attr ***attributes_ref)
|
|||||||
{
|
{
|
||||||
*attributes_ref = NULL;
|
*attributes_ref = NULL;
|
||||||
|
|
||||||
while (try_consume(c, TOKEN_AT))
|
while (1)
|
||||||
{
|
{
|
||||||
bool had_error;
|
Attr *attr;
|
||||||
Path *path = parse_path_prefix(c, &had_error);
|
if (!parse_attribute(c, &attr)) return false;
|
||||||
if (had_error) return false;
|
if (!attr) return true;
|
||||||
|
|
||||||
Attr *attr = CALLOCS(Attr);
|
|
||||||
|
|
||||||
attr->name = symstr(c);
|
|
||||||
attr->name_span = c->span;
|
|
||||||
attr->path = path;
|
|
||||||
|
|
||||||
if (tok_is(c, TOKEN_TYPE_IDENT) || tok_is(c, TOKEN_TYPE_IDENT))
|
|
||||||
{
|
|
||||||
advance(c);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TRY_CONSUME_OR_RET(TOKEN_IDENT, "Expected an attribute", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tok_is(c, TOKEN_LPAREN))
|
|
||||||
{
|
|
||||||
ASSIGN_EXPR_OR_RET(attr->expr, parse_const_paren_expr(c), false);
|
|
||||||
}
|
|
||||||
const char *name = attr->name;
|
const char *name = attr->name;
|
||||||
VECEACH(*attributes_ref, i)
|
VECEACH(*attributes_ref, i)
|
||||||
{
|
{
|
||||||
Attr *other_attr = *attributes_ref[i];
|
Attr *other_attr = *attributes_ref[i];
|
||||||
if (other_attr->name == name)
|
if (other_attr->name == name)
|
||||||
{
|
{
|
||||||
sema_error_at(attr->name_span, "Repeat of attribute '%s' here.", name);
|
SEMA_ERROR(attr, "Repeat of attribute '%s' here.", name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1734,8 +1742,8 @@ static inline Decl *parse_macro_declaration(ParseContext *c, Visibility visibili
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* error_declaration
|
* error_declaration
|
||||||
* : ERRTYPE TYPE_IDENT ';'
|
* : OPTENUM TYPE_IDENT ';'
|
||||||
* | ERRTYPE TYPE_IDENT '{' error_data '}'
|
* | OPTENUM TYPE_IDENT '{' error_data '}'
|
||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
static inline Decl *parse_optenum_declaration(ParseContext *c, Visibility visibility)
|
static inline Decl *parse_optenum_declaration(ParseContext *c, Visibility visibility)
|
||||||
@@ -2336,8 +2344,6 @@ Decl *parse_top_level_statement(ParseContext *c)
|
|||||||
case TOKEN_OPTENUM:
|
case TOKEN_OPTENUM:
|
||||||
case TOKEN_OPTNUM:
|
case TOKEN_OPTNUM:
|
||||||
case TOKEN_ERRNUM:
|
case TOKEN_ERRNUM:
|
||||||
case TOKEN_RESNUM:
|
|
||||||
case TOKEN_ERRTYPE:
|
|
||||||
{
|
{
|
||||||
ASSIGN_DECL_OR_RET(decl, parse_optenum_declaration(c, visibility), poisoned_decl);
|
ASSIGN_DECL_OR_RET(decl, parse_optenum_declaration(c, visibility), poisoned_decl);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -994,11 +994,9 @@ Ast *parse_stmt(ParseContext *c)
|
|||||||
case TOKEN_MODULE:
|
case TOKEN_MODULE:
|
||||||
case TOKEN_EXTERN:
|
case TOKEN_EXTERN:
|
||||||
case TOKEN_STRUCT:
|
case TOKEN_STRUCT:
|
||||||
case TOKEN_ERRTYPE:
|
|
||||||
case TOKEN_OPTENUM:
|
case TOKEN_OPTENUM:
|
||||||
case TOKEN_OPTNUM:
|
case TOKEN_OPTNUM:
|
||||||
case TOKEN_ERRNUM:
|
case TOKEN_ERRNUM:
|
||||||
case TOKEN_RESNUM:
|
|
||||||
case TOKEN_UNION:
|
case TOKEN_UNION:
|
||||||
case TOKEN_DEFINE:
|
case TOKEN_DEFINE:
|
||||||
case TOKEN_DOCS_START:
|
case TOKEN_DOCS_START:
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ Expr *parse_cond(ParseContext *c);
|
|||||||
Expr *parse_assert_expr(ParseContext *c);
|
Expr *parse_assert_expr(ParseContext *c);
|
||||||
Ast* parse_compound_stmt(ParseContext *c);
|
Ast* parse_compound_stmt(ParseContext *c);
|
||||||
Ast *parse_jump_stmt_no_eos(ParseContext *c);
|
Ast *parse_jump_stmt_no_eos(ParseContext *c);
|
||||||
|
bool parse_attribute(ParseContext *c, Attr **attribute_ref);
|
||||||
bool parse_attributes(ParseContext *c, Attr ***attributes_ref);
|
bool parse_attributes(ParseContext *c, Attr ***attributes_ref);
|
||||||
bool parse_switch_body(ParseContext *c, Ast ***cases, TokenType case_type, TokenType default_type,
|
bool parse_switch_body(ParseContext *c, Ast ***cases, TokenType case_type, TokenType default_type,
|
||||||
bool allow_multiple_values);
|
bool allow_multiple_values);
|
||||||
|
|||||||
@@ -395,7 +395,7 @@ static bool sema_analyse_struct_union(SemaContext *context, Decl *decl)
|
|||||||
#undef SET_ATTR
|
#undef SET_ATTR
|
||||||
if (had)
|
if (had)
|
||||||
{
|
{
|
||||||
sema_error_at(attr->name_span, "Attribute occurred twice, please remove one.");
|
sema_error_at(attr->span, "Attribute occurred twice, please remove one.");
|
||||||
return decl_poison(decl);
|
return decl_poison(decl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -549,14 +549,14 @@ static bool sema_analyse_bitstruct(SemaContext *context, Decl *decl)
|
|||||||
case ATTRIBUTE_BIGENDIAN:
|
case ATTRIBUTE_BIGENDIAN:
|
||||||
if (decl->bitstruct.little_endian)
|
if (decl->bitstruct.little_endian)
|
||||||
{
|
{
|
||||||
sema_error_at(attr->name_span, "Attribute cannot be combined with @littleendian");
|
sema_error_at(attr->span, "Attribute cannot be combined with @littleendian");
|
||||||
return decl_poison(decl);
|
return decl_poison(decl);
|
||||||
}
|
}
|
||||||
SET_ATTR(big_endian);
|
SET_ATTR(big_endian);
|
||||||
case ATTRIBUTE_LITTLEENDIAN:
|
case ATTRIBUTE_LITTLEENDIAN:
|
||||||
if (decl->bitstruct.big_endian)
|
if (decl->bitstruct.big_endian)
|
||||||
{
|
{
|
||||||
sema_error_at(attr->name_span, "Attribute cannot be combined with @bigendian");
|
sema_error_at(attr->span, "Attribute cannot be combined with @bigendian");
|
||||||
return decl_poison(decl);
|
return decl_poison(decl);
|
||||||
}
|
}
|
||||||
SET_ATTR(little_endian);
|
SET_ATTR(little_endian);
|
||||||
@@ -566,7 +566,7 @@ static bool sema_analyse_bitstruct(SemaContext *context, Decl *decl)
|
|||||||
#undef SET_ATTR
|
#undef SET_ATTR
|
||||||
if (had)
|
if (had)
|
||||||
{
|
{
|
||||||
sema_error_at(attr->name_span, "Attribute occurred twice, please remove one.");
|
sema_error_at(attr->span, "Attribute occurred twice, please remove one.");
|
||||||
return decl_poison(decl);
|
return decl_poison(decl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1154,7 +1154,7 @@ AttributeType sema_analyse_attribute(SemaContext *context, Attr *attr, Attribute
|
|||||||
AttributeType type = attribute_by_name(attr);
|
AttributeType type = attribute_by_name(attr);
|
||||||
if (type == ATTRIBUTE_NONE)
|
if (type == ATTRIBUTE_NONE)
|
||||||
{
|
{
|
||||||
sema_error_at(attr->name_span, "There is no attribute with the name '%s', did you mistype?", attr->name);
|
sema_error_at(attr->span, "There is no attribute with the name '%s', did you mistype?", attr->name);
|
||||||
return ATTRIBUTE_NONE;
|
return ATTRIBUTE_NONE;
|
||||||
}
|
}
|
||||||
static AttributeDomain attribute_domain[NUMBER_OF_ATTRIBUTES] = {
|
static AttributeDomain attribute_domain[NUMBER_OF_ATTRIBUTES] = {
|
||||||
@@ -1185,7 +1185,7 @@ AttributeType sema_analyse_attribute(SemaContext *context, Attr *attr, Attribute
|
|||||||
|
|
||||||
if ((attribute_domain[type] & domain) != domain)
|
if ((attribute_domain[type] & domain) != domain)
|
||||||
{
|
{
|
||||||
sema_error_at(attr->name_span, "'%s' is not a valid %s attribute.", attr->name, attribute_domain_to_string(domain));
|
sema_error_at(attr->span, "'%s' is not a valid %s attribute.", attr->name, attribute_domain_to_string(domain));
|
||||||
return ATTRIBUTE_NONE;
|
return ATTRIBUTE_NONE;
|
||||||
}
|
}
|
||||||
switch (type)
|
switch (type)
|
||||||
@@ -1230,7 +1230,7 @@ AttributeType sema_analyse_attribute(SemaContext *context, Attr *attr, Attribute
|
|||||||
case ATTRIBUTE_ALIGN:
|
case ATTRIBUTE_ALIGN:
|
||||||
if (!attr->expr)
|
if (!attr->expr)
|
||||||
{
|
{
|
||||||
sema_error_at(attr->name_span, "'align' requires an power-of-2 argument, e.g. align(8).");
|
sema_error_at(attr->span, "'align' requires an power-of-2 argument, e.g. align(8).");
|
||||||
return ATTRIBUTE_NONE;
|
return ATTRIBUTE_NONE;
|
||||||
}
|
}
|
||||||
if (!sema_analyse_expr(context, attr->expr)) return false;
|
if (!sema_analyse_expr(context, attr->expr)) return false;
|
||||||
@@ -1264,12 +1264,12 @@ AttributeType sema_analyse_attribute(SemaContext *context, Attr *attr, Attribute
|
|||||||
case ATTRIBUTE_EXTNAME:
|
case ATTRIBUTE_EXTNAME:
|
||||||
if (context->unit->module->is_generic)
|
if (context->unit->module->is_generic)
|
||||||
{
|
{
|
||||||
sema_error_at(attr->name_span, "'extname' attributes are not allowed in generic modules.");
|
sema_error_at(attr->span, "'extname' attributes are not allowed in generic modules.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!attr->expr)
|
if (!attr->expr)
|
||||||
{
|
{
|
||||||
sema_error_at(attr->name_span, "'%s' requires a string argument, e.g. %s(\"foo\").", attr->name, attr->name);
|
sema_error_at(attr->span, "'%s' requires a string argument, e.g. %s(\"foo\").", attr->name, attr->name);
|
||||||
return ATTRIBUTE_NONE;
|
return ATTRIBUTE_NONE;
|
||||||
}
|
}
|
||||||
if (!sema_analyse_expr(context, attr->expr)) return false;
|
if (!sema_analyse_expr(context, attr->expr)) return false;
|
||||||
@@ -1579,12 +1579,12 @@ static inline bool sema_analyse_func(SemaContext *context, Decl *decl)
|
|||||||
#undef SET_ATTR
|
#undef SET_ATTR
|
||||||
if (had)
|
if (had)
|
||||||
{
|
{
|
||||||
sema_error_at(attr->name_span, "Attribute occurred twice, please remove one.");
|
sema_error_at(attr->span, "Attribute occurred twice, please remove one.");
|
||||||
return decl_poison(decl);
|
return decl_poison(decl);
|
||||||
}
|
}
|
||||||
if (decl->func_decl.attr_inline && decl->func_decl.attr_noinline)
|
if (decl->func_decl.attr_inline && decl->func_decl.attr_noinline)
|
||||||
{
|
{
|
||||||
sema_error_at(attr->name_span, "A function cannot be 'inline' and 'noinline' at the same time.");
|
sema_error_at(attr->span, "A function cannot be 'inline' and 'noinline' at the same time.");
|
||||||
return decl_poison(decl);
|
return decl_poison(decl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1679,7 +1679,7 @@ static inline bool sema_analyse_macro(SemaContext *context, Decl *decl)
|
|||||||
}
|
}
|
||||||
if (had)
|
if (had)
|
||||||
{
|
{
|
||||||
sema_error_at(attr->name_span, "Attribute occurred twice, please remove one.");
|
sema_error_at(attr->span, "Attribute occurred twice, please remove one.");
|
||||||
return decl_poison(decl);
|
return decl_poison(decl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1828,7 +1828,7 @@ static bool sema_analyse_attributes_for_var(SemaContext *context, Decl *decl)
|
|||||||
#undef SET_ATTR
|
#undef SET_ATTR
|
||||||
if (had)
|
if (had)
|
||||||
{
|
{
|
||||||
sema_error_at(attr->name_span, "Attribute occurred twice, please remove one.");
|
sema_error_at(attr->span, "Attribute occurred twice, please remove one.");
|
||||||
return decl_poison(decl);
|
return decl_poison(decl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2098,7 +2098,7 @@ static bool sema_analyse_parameterized_define(SemaContext *c, Decl *decl)
|
|||||||
}
|
}
|
||||||
decl_path = define_type->unresolved.path;
|
decl_path = define_type->unresolved.path;
|
||||||
name = define_type->unresolved.name;
|
name = define_type->unresolved.name;
|
||||||
span = define_type->unresolved.span;
|
span = define_type->span;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DEFINE_ATTRIBUTE:
|
case DEFINE_ATTRIBUTE:
|
||||||
|
|||||||
@@ -667,7 +667,7 @@ static inline bool sema_cast_ident_rvalue(SemaContext *context, Expr *expr)
|
|||||||
SEMA_ERROR(expr, "Expected enum name followed by '.' and an enum value.");
|
SEMA_ERROR(expr, "Expected enum name followed by '.' and an enum value.");
|
||||||
return expr_poison(expr);
|
return expr_poison(expr);
|
||||||
case DECL_OPTENUM:
|
case DECL_OPTENUM:
|
||||||
SEMA_ERROR(expr, "Expected errtype name followed by '.' and an error value.");
|
SEMA_ERROR(expr, "Expected optenum name followed by '.' and an error value.");
|
||||||
return expr_poison(expr);
|
return expr_poison(expr);
|
||||||
case DECL_IMPORT:
|
case DECL_IMPORT:
|
||||||
case DECL_CT_IF:
|
case DECL_CT_IF:
|
||||||
@@ -2117,47 +2117,9 @@ static bool sema_analyse_body_expansion(SemaContext *macro_context, Expr *call)
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool sema_analyse_call_attributes(SemaContext *context, Decl *decl, Expr *call_expr)
|
|
||||||
{
|
|
||||||
Attr **attributes = call_expr->call_expr.attributes;
|
|
||||||
int force_inline = -1;
|
|
||||||
VECEACH(attributes, i)
|
|
||||||
{
|
|
||||||
Attr *attr = attributes[i];
|
|
||||||
AttributeType attribute = sema_analyse_attribute(context, attr, ATTR_CALL);
|
|
||||||
if (attribute == ATTRIBUTE_NONE) return false;
|
|
||||||
switch (attribute)
|
|
||||||
{
|
|
||||||
case ATTRIBUTE_INLINE:
|
|
||||||
case ATTRIBUTE_NOINLINE:
|
|
||||||
if (decl && decl->decl_kind != DECL_FUNC)
|
|
||||||
{
|
|
||||||
sema_error_at(attr->name_span,
|
|
||||||
"Inline / noinline attribute is only allowed for direct function/method calls");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (force_inline != -1)
|
|
||||||
{
|
|
||||||
sema_error_at(attr->name_span, "Only a single inline / noinline attribute is allowed on a call.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
force_inline = attribute == ATTRIBUTE_INLINE ? 1 : 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
UNREACHABLE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (force_inline != -1)
|
|
||||||
{
|
|
||||||
call_expr->call_expr.force_inline = force_inline == 1;
|
|
||||||
call_expr->call_expr.force_noinline = force_inline == 0;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool sema_expr_analyse_general_call(SemaContext *context, Expr *expr, Decl *decl, Expr *struct_var, bool is_macro, bool failable)
|
bool sema_expr_analyse_general_call(SemaContext *context, Expr *expr, Decl *decl, Expr *struct_var, bool is_macro, bool failable)
|
||||||
{
|
{
|
||||||
expr->call_expr.is_type_method = struct_var != NULL;
|
expr->call_expr.is_type_method = struct_var != NULL;
|
||||||
if (!sema_analyse_call_attributes(context, decl, expr)) return expr_poison(expr);
|
|
||||||
if (decl == NULL)
|
if (decl == NULL)
|
||||||
{
|
{
|
||||||
return sema_expr_analyse_var_call(context, expr, type_flatten_distinct_failable(exprptr(expr->call_expr.function)->type), failable);
|
return sema_expr_analyse_var_call(context, expr, type_flatten_distinct_failable(exprptr(expr->call_expr.function)->type), failable);
|
||||||
@@ -6633,7 +6595,7 @@ RETRY:
|
|||||||
{
|
{
|
||||||
case TOKEN_TYPE_IDENT:
|
case TOKEN_TYPE_IDENT:
|
||||||
type_info->unresolved.name = ident;
|
type_info->unresolved.name = ident;
|
||||||
type_info->unresolved.span = expr->span;
|
type_info->span = expr->span;
|
||||||
type_info->unresolved.path = path;
|
type_info->unresolved.path = path;
|
||||||
type_info->kind = TYPE_INFO_IDENTIFIER;
|
type_info->kind = TYPE_INFO_IDENTIFIER;
|
||||||
goto RETRY;
|
goto RETRY;
|
||||||
|
|||||||
@@ -768,16 +768,21 @@ static inline bool sema_analyse_for_cond(SemaContext *context, ExprId *cond_ref,
|
|||||||
cond = context_pop_defers_and_wrap_expr(context, cond);
|
cond = context_pop_defers_and_wrap_expr(context, cond);
|
||||||
|
|
||||||
// If this is const true, then set this to infinite and remove the expression.
|
// If this is const true, then set this to infinite and remove the expression.
|
||||||
if (cond->expr_kind == EXPR_CONST && cond->const_expr.b)
|
Expr *cond_last = cond->expr_kind == EXPR_COND ? VECLAST(cond->cond_expr) : cond;
|
||||||
|
assert(cond_last);
|
||||||
|
if (cond_last->expr_kind == EXPR_CONST && cond_last->const_expr.b)
|
||||||
{
|
{
|
||||||
cond = NULL;
|
if (cond->expr_kind != EXPR_COND || vec_size(cond->cond_expr) == 1)
|
||||||
|
{
|
||||||
|
cond = NULL;
|
||||||
|
}
|
||||||
*infinite = true;
|
*infinite = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*infinite = false;
|
*infinite = false;
|
||||||
}
|
}
|
||||||
*cond_ref = exprid(cond);
|
*cond_ref = cond ? exprid(cond) : 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
static inline bool sema_analyse_for_stmt(SemaContext *context, Ast *statement)
|
static inline bool sema_analyse_for_stmt(SemaContext *context, Ast *statement)
|
||||||
@@ -809,8 +814,8 @@ static inline bool sema_analyse_for_stmt(SemaContext *context, Ast *statement)
|
|||||||
Ast *body = astptr(statement->for_stmt.body);
|
Ast *body = astptr(statement->for_stmt.body);
|
||||||
|
|
||||||
PUSH_BREAKCONT(statement);
|
PUSH_BREAKCONT(statement);
|
||||||
success = sema_analyse_statement(context, body);
|
success = sema_analyse_statement(context, body);
|
||||||
statement->for_stmt.flow.no_exit = context->active_scope.jump_end;
|
statement->for_stmt.flow.no_exit = context->active_scope.jump_end;
|
||||||
POP_BREAKCONT();
|
POP_BREAKCONT();
|
||||||
|
|
||||||
// End for body scope
|
// End for body scope
|
||||||
@@ -846,7 +851,7 @@ static inline bool sema_analyse_for_stmt(SemaContext *context, Ast *statement)
|
|||||||
|
|
||||||
SCOPE_OUTER_END;
|
SCOPE_OUTER_END;
|
||||||
|
|
||||||
if (statement->for_stmt.flow.no_exit && is_infinite && !statement->for_stmt.flow.has_break)
|
if (statement->for_stmt.flow.no_exit || (is_infinite && !statement->for_stmt.flow.has_break))
|
||||||
{
|
{
|
||||||
context->active_scope.jump_end = true;
|
context->active_scope.jump_end = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ static inline bool sema_resolve_array_type(SemaContext *context, TypeInfo *type,
|
|||||||
|
|
||||||
static bool sema_resolve_type_identifier(SemaContext *context, TypeInfo *type_info)
|
static bool sema_resolve_type_identifier(SemaContext *context, TypeInfo *type_info)
|
||||||
{
|
{
|
||||||
Decl *decl = sema_resolve_symbol(context, type_info->unresolved.name, type_info->unresolved.path, type_info->unresolved.span);
|
Decl *decl = sema_resolve_symbol(context, type_info->unresolved.name, type_info->unresolved.path, type_info->span);
|
||||||
|
|
||||||
// Already handled
|
// Already handled
|
||||||
if (!decl_ok(decl))
|
if (!decl_ok(decl))
|
||||||
@@ -172,7 +172,7 @@ static bool sema_resolve_type_identifier(SemaContext *context, TypeInfo *type_in
|
|||||||
case DECL_GENERIC:
|
case DECL_GENERIC:
|
||||||
case DECL_LABEL:
|
case DECL_LABEL:
|
||||||
case DECL_ATTRIBUTE:
|
case DECL_ATTRIBUTE:
|
||||||
SEMA_ERROR(&type_info->unresolved, "This is not a type.");
|
SEMA_ERROR(type_info, "This is not a type.");
|
||||||
return type_info_poison(type_info);
|
return type_info_poison(type_info);
|
||||||
case DECL_CT_ELSE:
|
case DECL_CT_ELSE:
|
||||||
case DECL_CT_IF:
|
case DECL_CT_IF:
|
||||||
@@ -235,7 +235,7 @@ bool sema_resolve_type_shallow(SemaContext *context, TypeInfo *type_info, bool a
|
|||||||
if (type_info->resolve_status == RESOLVE_RUNNING)
|
if (type_info->resolve_status == RESOLVE_RUNNING)
|
||||||
{
|
{
|
||||||
// TODO this is incorrect for unresolved expressions
|
// TODO this is incorrect for unresolved expressions
|
||||||
SEMA_ERROR(&type_info->unresolved,
|
SEMA_ERROR(type_info,
|
||||||
"Circular dependency resolving type '%s'.",
|
"Circular dependency resolving type '%s'.",
|
||||||
type_info->unresolved.name);
|
type_info->unresolved.name);
|
||||||
return type_info_poison(type_info);
|
return type_info_poison(type_info);
|
||||||
@@ -262,7 +262,7 @@ RETRY:
|
|||||||
{
|
{
|
||||||
case TOKEN_TYPE_IDENT:
|
case TOKEN_TYPE_IDENT:
|
||||||
type_info->unresolved.name = ident;
|
type_info->unresolved.name = ident;
|
||||||
type_info->unresolved.span = expr->span;
|
type_info->span = expr->span;
|
||||||
type_info->unresolved.path = path;
|
type_info->unresolved.path = path;
|
||||||
type_info->kind = TYPE_INFO_IDENTIFIER;
|
type_info->kind = TYPE_INFO_IDENTIFIER;
|
||||||
goto RETRY;
|
goto RETRY;
|
||||||
@@ -273,7 +273,7 @@ RETRY:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
type_info->type = type_from_token(type);
|
type_info->type = type_from_token(type);
|
||||||
return true;
|
goto APPEND_QUALIFIERS;
|
||||||
default:
|
default:
|
||||||
SEMA_ERROR(expr, "Only type names may be resolved with $evaltype.");
|
SEMA_ERROR(expr, "Only type names may be resolved with $evaltype.");
|
||||||
return type_info_poison(type_info);
|
return type_info_poison(type_info);
|
||||||
@@ -289,7 +289,7 @@ RETRY:
|
|||||||
type_info->type = expr->type;
|
type_info->type = expr->type;
|
||||||
type_info->resolve_status = RESOLVE_DONE;
|
type_info->resolve_status = RESOLVE_DONE;
|
||||||
assert(!type_info->failable);
|
assert(!type_info->failable);
|
||||||
return true;
|
goto APPEND_QUALIFIERS;
|
||||||
}
|
}
|
||||||
case TYPE_INFO_INFERRED_ARRAY:
|
case TYPE_INFO_INFERRED_ARRAY:
|
||||||
if (!allow_inferred_type)
|
if (!allow_inferred_type)
|
||||||
@@ -307,9 +307,11 @@ RETRY:
|
|||||||
if (!sema_resolve_ptr_type(context, type_info)) return false;
|
if (!sema_resolve_ptr_type(context, type_info)) return false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
APPEND_QUALIFIERS:
|
||||||
if (type_info->failable)
|
if (type_info->failable)
|
||||||
{
|
{
|
||||||
type_info->type = type_get_failable(type_info->type);
|
Type *type = type_info->type;
|
||||||
|
if (!type_is_failable(type)) type_info->type = type_get_failable(type);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ const char *kw_main;
|
|||||||
const char *kw_max;
|
const char *kw_max;
|
||||||
const char *kw_min;
|
const char *kw_min;
|
||||||
const char *kw_nan;
|
const char *kw_nan;
|
||||||
|
const char *kw_noinline;
|
||||||
const char *kw_ordinal;
|
const char *kw_ordinal;
|
||||||
const char *kw_param;
|
const char *kw_param;
|
||||||
const char *kw_ptr;
|
const char *kw_ptr;
|
||||||
@@ -162,6 +163,7 @@ void symtab_init(uint32_t capacity)
|
|||||||
kw_max = KW_DEF("max");
|
kw_max = KW_DEF("max");
|
||||||
kw_min = KW_DEF("min");
|
kw_min = KW_DEF("min");
|
||||||
kw_nan = KW_DEF("nan");
|
kw_nan = KW_DEF("nan");
|
||||||
|
kw_noinline = KW_DEF("noinline");
|
||||||
kw_ordinal = KW_DEF("ordinal");
|
kw_ordinal = KW_DEF("ordinal");
|
||||||
kw_param = KW_DEF("param");
|
kw_param = KW_DEF("param");
|
||||||
kw_ptr = KW_DEF("ptr");
|
kw_ptr = KW_DEF("ptr");
|
||||||
@@ -203,7 +205,7 @@ void symtab_init(uint32_t capacity)
|
|||||||
}
|
}
|
||||||
|
|
||||||
attribute_list[ATTRIBUTE_INLINE] = kw_inline;
|
attribute_list[ATTRIBUTE_INLINE] = kw_inline;
|
||||||
attribute_list[ATTRIBUTE_NOINLINE] = KW_DEF("noinline");
|
attribute_list[ATTRIBUTE_NOINLINE] = kw_noinline;
|
||||||
attribute_list[ATTRIBUTE_BIGENDIAN] = KW_DEF("bigendian");
|
attribute_list[ATTRIBUTE_BIGENDIAN] = KW_DEF("bigendian");
|
||||||
attribute_list[ATTRIBUTE_LITTLEENDIAN] = KW_DEF("littleendian");
|
attribute_list[ATTRIBUTE_LITTLEENDIAN] = KW_DEF("littleendian");
|
||||||
attribute_list[ATTRIBUTE_NORETURN] = KW_DEF("noreturn");
|
attribute_list[ATTRIBUTE_NORETURN] = KW_DEF("noreturn");
|
||||||
|
|||||||
@@ -216,8 +216,6 @@ const char *token_type_to_string(TokenType type)
|
|||||||
return "enum";
|
return "enum";
|
||||||
case TOKEN_EXTERN:
|
case TOKEN_EXTERN:
|
||||||
return "extern";
|
return "extern";
|
||||||
case TOKEN_ERRTYPE:
|
|
||||||
return "errtype";
|
|
||||||
case TOKEN_FALSE:
|
case TOKEN_FALSE:
|
||||||
return "false";
|
return "false";
|
||||||
case TOKEN_FOR:
|
case TOKEN_FOR:
|
||||||
@@ -273,9 +271,6 @@ const char *token_type_to_string(TokenType type)
|
|||||||
return "optnum";
|
return "optnum";
|
||||||
case TOKEN_ERRNUM:
|
case TOKEN_ERRNUM:
|
||||||
return "errnum";
|
return "errnum";
|
||||||
case TOKEN_RESNUM:
|
|
||||||
return "resnum";
|
|
||||||
|
|
||||||
|
|
||||||
// Named types
|
// Named types
|
||||||
case TOKEN_VOID:
|
case TOKEN_VOID:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
errtype MyErr
|
optenum MyErr
|
||||||
{
|
{
|
||||||
FOO
|
FOO
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
errtype Error
|
optenum Error
|
||||||
{}
|
{}
|
||||||
|
|
||||||
define Foo1 = distinct Error; // #error: You cannot create a distinct type from an error
|
define Foo1 = distinct Error; // #error: You cannot create a distinct type from an error
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
errtype MyError
|
optenum MyError
|
||||||
{
|
{
|
||||||
FOO,
|
FOO,
|
||||||
BAR
|
BAR
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
module errors;
|
module errors;
|
||||||
|
|
||||||
errtype TheError
|
optenum TheError
|
||||||
{
|
{
|
||||||
A
|
A
|
||||||
}
|
}
|
||||||
|
|
||||||
errtype TheError2
|
optenum TheError2
|
||||||
{
|
{
|
||||||
A,
|
A,
|
||||||
B
|
B
|
||||||
}
|
}
|
||||||
|
|
||||||
errtype TheError3
|
optenum TheError3
|
||||||
{
|
{
|
||||||
C, D
|
C, D
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
module test;
|
module test;
|
||||||
import std::io;
|
import std::io;
|
||||||
errtype Foo
|
optenum Foo
|
||||||
{
|
{
|
||||||
MY_VAL1,
|
MY_VAL1,
|
||||||
MY_VAL2,
|
MY_VAL2,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ struct Foo
|
|||||||
int x, y;
|
int x, y;
|
||||||
}
|
}
|
||||||
|
|
||||||
errtype MyErr
|
optenum MyErr
|
||||||
{
|
{
|
||||||
FOO
|
FOO
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
module foo;
|
module foo;
|
||||||
import std::io;
|
import std::io;
|
||||||
|
|
||||||
errtype Foo
|
optenum Foo
|
||||||
{
|
{
|
||||||
X,
|
X,
|
||||||
Y,
|
Y,
|
||||||
@@ -12,7 +12,7 @@ errtype Foo
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
errtype Foob
|
optenum Foob
|
||||||
{
|
{
|
||||||
X1,
|
X1,
|
||||||
Y2
|
Y2
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
module foo;
|
module foo;
|
||||||
|
|
||||||
errtype Blurg
|
optenum Blurg
|
||||||
{
|
{
|
||||||
Y
|
Y
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// #target: x64-darwin
|
// #target: x64-darwin
|
||||||
|
|
||||||
extern fn int! err();
|
extern fn int! err();
|
||||||
errtype FooErr { QBERT }
|
optenum FooErr { QBERT }
|
||||||
extern fn int printf(char* fmt, ...);
|
extern fn int printf(char* fmt, ...);
|
||||||
|
|
||||||
fn void main()
|
fn void main()
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ fn int! tester()
|
|||||||
return 222;
|
return 222;
|
||||||
}
|
}
|
||||||
|
|
||||||
errtype Foo
|
optenum Foo
|
||||||
{
|
{
|
||||||
A
|
A
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
extern fn int printf(char* fmt, ...);
|
extern fn int printf(char* fmt, ...);
|
||||||
|
|
||||||
extern fn int! err();
|
extern fn int! err();
|
||||||
errtype FooErr
|
optenum FooErr
|
||||||
{
|
{
|
||||||
X
|
X
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ fn int! tester()
|
|||||||
return 222;
|
return 222;
|
||||||
}
|
}
|
||||||
|
|
||||||
errtype Foo
|
optenum Foo
|
||||||
{
|
{
|
||||||
A
|
A
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ fn void test6()
|
|||||||
|
|
||||||
define Baz = Foo;
|
define Baz = Foo;
|
||||||
define Bar = distinct int;
|
define Bar = distinct int;
|
||||||
errtype Err { FOO }
|
optenum Err { FOO }
|
||||||
union Un { int x; }
|
union Un { int x; }
|
||||||
enum MyEnum { BAR }
|
enum MyEnum { BAR }
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
errtype MyErr
|
optenum MyErr
|
||||||
{
|
{
|
||||||
FOO
|
FOO
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
module demo;
|
module demo;
|
||||||
import std::io;
|
import std::io;
|
||||||
|
|
||||||
errtype MathError
|
optenum MathError
|
||||||
{
|
{
|
||||||
DIVISION_BY_ZERO
|
DIVISION_BY_ZERO
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
int z;
|
int z;
|
||||||
|
|
||||||
errtype MyError
|
optenum MyError
|
||||||
{
|
{
|
||||||
FOO,
|
FOO,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ fn Type getMult(Type a)
|
|||||||
}
|
}
|
||||||
Type argh = 234;
|
Type argh = 234;
|
||||||
|
|
||||||
errtype MyErr
|
optenum MyErr
|
||||||
{
|
{
|
||||||
X,
|
X,
|
||||||
Y
|
Y
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
module foo;
|
module foo;
|
||||||
import std::io;
|
import std::io;
|
||||||
|
|
||||||
errtype Foo
|
optenum Foo
|
||||||
{
|
{
|
||||||
X
|
X
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ fn void test_missing_no_cases(Baz x)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
errtype MathError
|
optenum MathError
|
||||||
{
|
{
|
||||||
DIVISION_BY_ZERO
|
DIVISION_BY_ZERO
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ module mymodule;
|
|||||||
|
|
||||||
extern fn void printf(char *, ...);
|
extern fn void printf(char *, ...);
|
||||||
|
|
||||||
errtype HelloErr
|
optenum HelloErr
|
||||||
{
|
{
|
||||||
FOO,
|
FOO,
|
||||||
}
|
}
|
||||||
errtype ByeErr
|
optenum ByeErr
|
||||||
{
|
{
|
||||||
BAR,
|
BAR,
|
||||||
BAZ
|
BAZ
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
errtype MyError
|
optenum MyError
|
||||||
{
|
{
|
||||||
FOO
|
FOO
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user