mirror of
https://github.com/odin-lang/Odin.git
synced 2026-02-20 18:06:42 +00:00
:: style procedure declarations; remove old parsing code
This commit is contained in:
196
src/parser.cpp
196
src/parser.cpp
@@ -34,7 +34,6 @@ struct AstFile {
|
||||
// NOTE(bill): Used to prevent type literals in control clauses
|
||||
isize expr_level;
|
||||
bool allow_range; // NOTE(bill): Ranges are only allowed in certain cases
|
||||
bool allow_gen_proc_type;
|
||||
bool in_foreign_block;
|
||||
|
||||
Array<AstNode *> decls;
|
||||
@@ -309,15 +308,6 @@ AST_NODE_KIND(_ComplexStmtEnd, "", i32) \
|
||||
AST_NODE_KIND(_StmtEnd, "", i32) \
|
||||
AST_NODE_KIND(_DeclBegin, "", i32) \
|
||||
AST_NODE_KIND(BadDecl, "bad declaration", struct { Token begin, end; }) \
|
||||
AST_NODE_KIND(ProcDecl, "procedure declaration", struct { \
|
||||
Token token; \
|
||||
AstNode *name; \
|
||||
AstNode *type; \
|
||||
AstNode *body; \
|
||||
u64 tags; \
|
||||
String link_name; \
|
||||
CommentGroup docs; \
|
||||
}) \
|
||||
AST_NODE_KIND(ForeignBlockDecl, "foreign block declaration", struct { \
|
||||
Token token; \
|
||||
AstNode * foreign_library; \
|
||||
@@ -346,19 +336,6 @@ AST_NODE_KIND(_DeclBegin, "", i32) \
|
||||
CommentGroup docs; \
|
||||
CommentGroup comment; \
|
||||
}) \
|
||||
AST_NODE_KIND(ValueSpec, "value specification", struct { \
|
||||
Array<AstNode *> names; \
|
||||
AstNode * type; \
|
||||
Array<AstNode *> values; \
|
||||
CommentGroup docs; \
|
||||
CommentGroup comment; \
|
||||
}) \
|
||||
AST_NODE_KIND(TypeSpec, "type specification", struct { \
|
||||
AstNode *name; \
|
||||
AstNode *type; \
|
||||
CommentGroup docs; \
|
||||
CommentGroup comment; \
|
||||
}) \
|
||||
AST_NODE_KIND(ImportSpec, "import specification", struct { \
|
||||
bool is_import; \
|
||||
Token relpath; \
|
||||
@@ -581,15 +558,12 @@ Token ast_node_token(AstNode *node) {
|
||||
case AstNode_PushContext: return node->PushContext.token;
|
||||
|
||||
case AstNode_BadDecl: return node->BadDecl.begin;
|
||||
case AstNode_ProcDecl: return node->ProcDecl.token;
|
||||
case AstNode_ForeignLibrarySpec: return node->ForeignLibrarySpec.filepath;
|
||||
case AstNode_Label: return node->Label.token;
|
||||
|
||||
case AstNode_GenDecl: return node->GenDecl.token;
|
||||
case AstNode_ValueDecl: return ast_node_token(node->ValueDecl.names[0]);
|
||||
case AstNode_ValueSpec: return ast_node_token(node->ValueSpec.names[0]);
|
||||
case AstNode_ImportSpec: return node->ImportSpec.import_name;
|
||||
case AstNode_TypeSpec: return ast_node_token(node->TypeSpec.name);
|
||||
|
||||
case AstNode_ForeignBlockDecl: return node->ForeignBlockDecl.token;
|
||||
|
||||
@@ -811,12 +785,7 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node) {
|
||||
break;
|
||||
|
||||
case AstNode_BadDecl: break;
|
||||
case AstNode_ProcDecl:
|
||||
n->ProcDecl.name = clone_ast_node(a, n->ProcDecl.name);
|
||||
n->ProcDecl.type = clone_ast_node(a, n->ProcDecl.type);
|
||||
n->ProcDecl.body = clone_ast_node(a, n->ProcDecl.body);
|
||||
// TODO(bill): Clone the comment group too?
|
||||
break;
|
||||
|
||||
case AstNode_ForeignBlockDecl:
|
||||
n->ForeignBlockDecl.foreign_library = clone_ast_node(a, n->ForeignBlockDecl.foreign_library);
|
||||
n->ForeignBlockDecl.decls = clone_ast_node_array(a, n->ForeignBlockDecl.decls);
|
||||
@@ -832,15 +801,6 @@ AstNode *clone_ast_node(gbAllocator a, AstNode *node) {
|
||||
n->ValueDecl.type = clone_ast_node(a, n->ValueDecl.type);
|
||||
n->ValueDecl.values = clone_ast_node_array(a, n->ValueDecl.values);
|
||||
break;
|
||||
case AstNode_ValueSpec:
|
||||
n->ValueSpec.names = clone_ast_node_array(a, n->ValueSpec.names);
|
||||
n->ValueSpec.type = clone_ast_node(a, n->ValueSpec.type);
|
||||
n->ValueSpec.values = clone_ast_node_array(a, n->ValueSpec.values);
|
||||
break;
|
||||
case AstNode_TypeSpec:
|
||||
n->TypeSpec.name = clone_ast_node(a, n->TypeSpec.name);
|
||||
n->TypeSpec.type = clone_ast_node(a, n->TypeSpec.type);
|
||||
break;
|
||||
case AstNode_ForeignLibrarySpec:
|
||||
n->ForeignLibrarySpec.cond = clone_ast_node(a, n->ForeignLibrarySpec.cond);
|
||||
break;
|
||||
@@ -1504,19 +1464,6 @@ AstNode *ast_map_type(AstFile *f, Token token, AstNode *count, AstNode *key, Ast
|
||||
}
|
||||
|
||||
|
||||
AstNode *ast_proc_decl(AstFile *f, Token token, AstNode *name, AstNode *type, AstNode *body,
|
||||
u64 tags, String link_name, CommentGroup docs) {
|
||||
AstNode *result = make_ast_node(f, AstNode_ProcDecl);
|
||||
result->ProcDecl.token = token;
|
||||
result->ProcDecl.name = name;
|
||||
result->ProcDecl.type = type;
|
||||
result->ProcDecl.body = body;
|
||||
result->ProcDecl.tags = tags;
|
||||
result->ProcDecl.link_name = link_name;
|
||||
result->ProcDecl.docs = docs;
|
||||
return result;
|
||||
}
|
||||
|
||||
AstNode *ast_foreign_block_decl(AstFile *f, Token token, AstNode *foreign_library, Token open, Token close, Array<AstNode *> decls,
|
||||
CommentGroup docs) {
|
||||
AstNode *result = make_ast_node(f, AstNode_ForeignBlockDecl);
|
||||
@@ -1558,27 +1505,6 @@ AstNode *ast_value_decl(AstFile *f, Array<AstNode *> names, AstNode *type, Array
|
||||
return result;
|
||||
}
|
||||
|
||||
AstNode *ast_value_spec(AstFile *f, Array<AstNode *> names, AstNode *type, Array<AstNode *> values,
|
||||
CommentGroup docs, CommentGroup comment) {
|
||||
AstNode *result = make_ast_node(f, AstNode_ValueSpec);
|
||||
result->ValueSpec.names = names;
|
||||
result->ValueSpec.type = type;
|
||||
result->ValueSpec.values = values;
|
||||
result->ValueSpec.docs = docs;
|
||||
result->ValueSpec.comment = comment;
|
||||
return result;
|
||||
}
|
||||
|
||||
AstNode *ast_type_spec(AstFile *f, AstNode *name, AstNode *type,
|
||||
CommentGroup docs, CommentGroup comment) {
|
||||
AstNode *result = make_ast_node(f, AstNode_TypeSpec);
|
||||
result->TypeSpec.name = name;
|
||||
result->TypeSpec.type = type;
|
||||
result->TypeSpec.docs = docs;
|
||||
result->TypeSpec.comment = comment;
|
||||
return result;
|
||||
}
|
||||
|
||||
AstNode *ast_import_spec(AstFile *f, bool is_import, Token relpath, Token import_name, AstNode *cond,
|
||||
CommentGroup docs, CommentGroup comment) {
|
||||
AstNode *result = make_ast_node(f, AstNode_ImportSpec);
|
||||
@@ -1868,8 +1794,6 @@ bool is_semicolon_optional_for_node(AstFile *f, AstNode *s) {
|
||||
return true;
|
||||
case AstNode_ProcLit:
|
||||
return s->ProcLit.body != NULL;
|
||||
case AstNode_ProcDecl:
|
||||
return s->ProcDecl.body != NULL;
|
||||
|
||||
case AstNode_ValueDecl:
|
||||
if (s->ValueDecl.is_mutable) {
|
||||
@@ -1897,9 +1821,6 @@ bool is_semicolon_optional_for_node(AstFile *f, AstNode *s) {
|
||||
return is_semicolon_optional_for_node(f, s->ForeignBlockDecl.decls[0]);
|
||||
}
|
||||
break;
|
||||
|
||||
case AstNode_TypeSpec:
|
||||
return is_semicolon_optional_for_node(f, s->TypeSpec.type);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -2764,45 +2685,6 @@ AstNode *parse_type(AstFile *f) {
|
||||
return type;
|
||||
}
|
||||
|
||||
AstNode *parse_proc_decl(AstFile *f) {
|
||||
CommentGroup docs = f->lead_comment;
|
||||
|
||||
TokenKind look_ahead = look_ahead_token_kind(f, 1);
|
||||
if (look_ahead != Token_Ident) {
|
||||
return ast_expr_stmt(f, parse_expr(f, true));
|
||||
}
|
||||
|
||||
Token token = expect_token(f, Token_proc);
|
||||
AstNode *body = NULL;
|
||||
String link_name = {};
|
||||
|
||||
|
||||
bool prev_allow_gen_proc_type = f->allow_gen_proc_type;
|
||||
f->allow_gen_proc_type = true;
|
||||
AstNode *name = parse_ident(f);
|
||||
AstNode *type = parse_proc_type(f, token, &link_name);
|
||||
u64 tags = type->ProcType.tags;
|
||||
f->allow_gen_proc_type = prev_allow_gen_proc_type;
|
||||
|
||||
|
||||
if (allow_token(f, Token_Undef)) {
|
||||
body = NULL;
|
||||
} else if (f->curr_token.kind == Token_OpenBrace) {
|
||||
if ((tags & ProcTag_foreign) != 0) {
|
||||
syntax_error(token, "A procedure tagged as `#foreign` cannot have a body");
|
||||
}
|
||||
AstNode *curr_proc = f->curr_proc;
|
||||
f->curr_proc = type;
|
||||
body = parse_body(f);
|
||||
f->curr_proc = curr_proc;
|
||||
}
|
||||
|
||||
AstNode *decl = ast_proc_decl(f, token, name, type, body, tags, link_name, docs);
|
||||
expect_semicolon(f, decl);
|
||||
return decl;
|
||||
}
|
||||
|
||||
|
||||
#define PARSE_SPEC_FUNC(name) AstNode *name(AstFile *f, CommentGroup docs, Token token)
|
||||
typedef PARSE_SPEC_FUNC(ParseSpecFunc);
|
||||
|
||||
@@ -2841,62 +2723,6 @@ AstNode *parse_gen_decl(AstFile *f, Token token, ParseSpecFunc *func) {
|
||||
return ast_gen_decl(f, token, open, close, specs, docs);
|
||||
}
|
||||
|
||||
PARSE_SPEC_FUNC(parse_value_spec) {
|
||||
bool is_mutable = token.kind != Token_const;
|
||||
|
||||
Array<AstNode *> names = parse_ident_list(f);
|
||||
AstNode *type = NULL;
|
||||
Array<AstNode *> values = {};
|
||||
|
||||
if (allow_token(f, Token_Colon)) {
|
||||
type = parse_type(f);
|
||||
} else if (f->curr_token.kind != Token_Eq &&
|
||||
f->curr_token.kind != Token_Semicolon) {
|
||||
syntax_error(f->curr_token, "Expected separator `:` or `=`");
|
||||
}
|
||||
|
||||
if (allow_token(f, Token_Eq)) {
|
||||
values = parse_rhs_expr_list(f);
|
||||
if (values.count > names.count) {
|
||||
syntax_error(f->curr_token, "Too many values on the right hand side of the declaration");
|
||||
} else if (values.count < names.count && !is_mutable) {
|
||||
syntax_error(f->curr_token, "All constant declarations must be defined");
|
||||
} else if (values.count == 0) {
|
||||
syntax_error(f->curr_token, "Expected an expression for this declaration");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (is_mutable) {
|
||||
if (type == NULL && values.count == 0) {
|
||||
syntax_error(f->curr_token, "Missing variable type or initialization");
|
||||
return ast_bad_decl(f, f->curr_token, f->curr_token);
|
||||
}
|
||||
} else {
|
||||
if (type == NULL && values.count == 0 && names.count > 0) {
|
||||
syntax_error(f->curr_token, "Missing constant value");
|
||||
return ast_bad_decl(f, f->curr_token, f->curr_token);
|
||||
}
|
||||
}
|
||||
|
||||
if (values.data == NULL) {
|
||||
values = make_ast_node_array(f);
|
||||
}
|
||||
|
||||
if (f->expr_level >= 0) {
|
||||
expect_semicolon(f, NULL);
|
||||
}
|
||||
|
||||
return ast_value_spec(f, names, type, values, docs, f->line_comment);
|
||||
}
|
||||
|
||||
PARSE_SPEC_FUNC(parse_type_spec) {
|
||||
AstNode *name = parse_ident(f);
|
||||
AstNode *type = parse_type(f);
|
||||
expect_semicolon(f, type);
|
||||
return ast_type_spec(f, name, type, docs, f->line_comment);
|
||||
}
|
||||
|
||||
PARSE_SPEC_FUNC(parse_import_spec) {
|
||||
AstNode *spec = NULL;
|
||||
if (token.kind == Token_import) {
|
||||
@@ -3034,7 +2860,6 @@ void parse_foreign_block_decl(AstFile *f, Array<AstNode *> *decls) {
|
||||
return;
|
||||
|
||||
case AstNode_ValueDecl:
|
||||
case AstNode_ProcDecl:
|
||||
array_add(decls, decl);
|
||||
return;
|
||||
|
||||
@@ -3056,15 +2881,6 @@ void parse_foreign_block_decl(AstFile *f, Array<AstNode *> *decls) {
|
||||
AstNode *parse_decl(AstFile *f) {
|
||||
ParseSpecFunc *func = NULL;
|
||||
switch (f->curr_token.kind) {
|
||||
case Token_var:
|
||||
case Token_const:
|
||||
func = parse_value_spec;
|
||||
break;
|
||||
|
||||
case Token_type:
|
||||
func = parse_type_spec;
|
||||
break;
|
||||
|
||||
case Token_import:
|
||||
case Token_import_load:
|
||||
func = parse_import_spec;
|
||||
@@ -3103,9 +2919,6 @@ AstNode *parse_decl(AstFile *f) {
|
||||
return ast_foreign_block_decl(f, token, foreign_library, open, close, decls, docs);
|
||||
} break;
|
||||
|
||||
case Token_proc:
|
||||
return parse_proc_decl(f);
|
||||
|
||||
default: {
|
||||
Token tok = f->curr_token;
|
||||
fix_advance_to_next_stmt(f);
|
||||
@@ -3501,7 +3314,7 @@ AstNode *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, Tok
|
||||
|
||||
isize total_name_count = 0;
|
||||
bool allow_ellipsis = allowed_flags&FieldFlag_ellipsis;
|
||||
bool allow_type_token = f->allow_gen_proc_type && allow_default_parameters;
|
||||
bool allow_type_token = allow_default_parameters;
|
||||
|
||||
while (f->curr_token.kind != follow &&
|
||||
f->curr_token.kind != Token_Colon &&
|
||||
@@ -3886,10 +3699,7 @@ AstNode *parse_type_or_ident(AstFile *f) {
|
||||
|
||||
case Token_proc: {
|
||||
Token token = f->curr_token; next_token(f);
|
||||
bool prev_allow_gen_proc_type = f->allow_gen_proc_type;
|
||||
f->allow_gen_proc_type = false;
|
||||
AstNode *pt = parse_proc_type(f, token, NULL);
|
||||
f->allow_gen_proc_type = prev_allow_gen_proc_type;
|
||||
if (pt->ProcType.tags != 0) {
|
||||
syntax_error(token, "A procedure type cannot have tags");
|
||||
}
|
||||
@@ -4328,7 +4138,7 @@ AstNode *parse_stmt(AstFile *f) {
|
||||
|
||||
// case Token_var:
|
||||
// case Token_const:
|
||||
case Token_proc:
|
||||
// case Token_proc:
|
||||
// case Token_type:
|
||||
case Token_import:
|
||||
case Token_import_load:
|
||||
|
||||
Reference in New Issue
Block a user