Allow imports anywhere in the module outside of ct statements.

This commit is contained in:
Christoffer Lerno
2022-10-20 23:54:36 +02:00
parent e6a5f98606
commit bd0e8f1ef1
6 changed files with 31 additions and 24 deletions

View File

@@ -90,7 +90,8 @@ static inline bool parse_top_level_block(ParseContext *c, Decl ***decls, TokenTy
CONSUME_OR_RET(TOKEN_COLON, false);
while (!tok_is(c, end1) && !tok_is(c, end2) && !tok_is(c, end3) && !tok_is(c, TOKEN_EOF))
{
Decl *decl = parse_top_level_statement(c);
Decl *decl = parse_top_level_statement(c, false);
if (!decl) continue;
assert(decl);
if (decl_ok(decl))
{
@@ -172,7 +173,7 @@ static inline Decl *parse_ct_case(ParseContext *c)
{
TokenType type = c->tok;
if (type == TOKEN_CT_DEFAULT || type == TOKEN_CT_CASE || type == TOKEN_CT_ENDSWITCH) break;
ASSIGN_DECL_OR_RET(Decl * stmt, parse_top_level_statement(c), poisoned_decl);
ASSIGN_DECL_OR_RET(Decl * stmt, parse_top_level_statement(c, false), poisoned_decl);
vec_add(decl->ct_case_decl.body, stmt);
}
return decl;
@@ -2280,17 +2281,6 @@ static inline bool parse_import(ParseContext *c)
}
/**
* imports ::= import*
*/
void parse_imports(ParseContext *c)
{
while (tok_is(c, TOKEN_IMPORT))
{
if (!parse_import(c)) recover_top_level(c);
}
}
static inline bool parse_doc_contract(ParseContext *c, AstId **docs_ref, DocDirectiveKind kind)
@@ -2529,7 +2519,7 @@ static bool parse_docs(ParseContext *c, AstId *docs_ref)
* @param visibility
* @return Decl* or a poison value if parsing failed
*/
Decl *parse_top_level_statement(ParseContext *c)
Decl *parse_top_level_statement(ParseContext *c, bool allow_import)
{
AstId docs = 0;
if (!parse_docs(c, &docs)) return poisoned_decl;
@@ -2604,6 +2594,20 @@ Decl *parse_top_level_statement(ParseContext *c)
}
break;
}
case TOKEN_IMPORT:
if (!check_no_visibility_before(c, visibility)) return poisoned_decl;
if (!allow_import)
{
SEMA_ERROR_HERE("'import' may not appear inside a compile time statement.");
return poisoned_decl;
}
if (!parse_import(c)) return poisoned_decl;
if (docs)
{
SEMA_ERROR(astptr(docs), "Unexpected doc comment before import, did you mean to use a regular comment?");
return poisoned_decl;
}
return NULL;
case TOKEN_CT_SWITCH:
{
if (!check_no_visibility_before(c, visibility)) return poisoned_decl;
@@ -2664,9 +2668,6 @@ Decl *parse_top_level_statement(ParseContext *c)
}
}
return poisoned_decl;
case TOKEN_IMPORT:
SEMA_ERROR_HERE("Imports are only allowed directly after the module declaration.");
return poisoned_decl;
case TOKEN_TLOCAL:
case TYPELIKE_TOKENS:
{

View File

@@ -66,7 +66,6 @@ static inline void parse_translation_unit(ParseContext *c)
advance(c);
NEXT_CONTEXT:
if (!parse_module(c)) return;
parse_imports(c);
while (!tok_is(c, TOKEN_EOF))
{
if (tok_is(c, TOKEN_MODULE))
@@ -77,7 +76,7 @@ static inline void parse_translation_unit(ParseContext *c)
c = new_context;
goto NEXT_CONTEXT;
}
Decl *decl = parse_top_level_statement(c);
Decl *decl = parse_top_level_statement(c, true);
if (!decl) continue;
if (decl_ok(decl))
{

View File

@@ -16,7 +16,7 @@
#define TRY_CONSUME_AFTER(_tok, _message, _type) do { if (!try_consume(c, _tok)) { sema_error_at_after(c->prev_span, _message); return _type; } } while(0)
#define CHECK_EXPR_OR_RET(_expr) do { if (!expr_ok(_expr)) return _expr; } while(0)
Decl *parse_top_level_statement(ParseContext *c);
Decl *parse_top_level_statement(ParseContext *c, bool allow_import);
Ast *parse_ct_assert_stmt(ParseContext *c);
Ast *parse_stmt(ParseContext *c);
Path *parse_path_prefix(ParseContext *c, bool *had_error);
@@ -27,7 +27,6 @@ TypeInfo *parse_type(ParseContext *c);
TypeInfo *parse_optional_type(ParseContext *c);
TypeInfo *parse_type_with_base(ParseContext *c, TypeInfo *type_info);
Expr* parse_constant_expr(ParseContext *c);
void parse_imports(ParseContext *c);
Decl *parse_decl(ParseContext *c);
Expr *parse_integer(ParseContext *c, Expr *left);
Expr *parse_decl_or_expr(ParseContext *c, Decl **decl_ref);

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.3.91"
#define COMPILER_VERSION "0.3.92"

View File

@@ -2,4 +2,8 @@ module foo;
fn void hello() {}
import bar; // #error: Imports are only allowed directly after the module declaration
$if (true):
import bar; // #error: 'import' may not appear inside a compile
$endif;

View File

@@ -2,4 +2,8 @@ module foo;
fn void hello() {}
import bar; // #error: Imports are only allowed directly after the module declaration
$if (true):
import bar; // #error: 'import' may not appear inside a compile
$endif;