parseh understands types better and handles some situations better
See #88 Also, includes partial implementation of typedef top level declaration. See #95 Also, fix function types. Previously the way we were deduping function type pointers was incorrect.
This commit is contained in:
@@ -908,7 +908,7 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc, int *token_index, bool mand
|
||||
|
||||
/*
|
||||
PrimaryExpression = "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | FnProto | AsmExpression | ("error" "." "Symbol")
|
||||
KeywordLiteral : "true" | "false" | "null" | "break" | "continue" | "undefined" | "error"
|
||||
KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "error" | "type"
|
||||
*/
|
||||
static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool mandatory) {
|
||||
Token *token = &pc->tokens->at(*token_index);
|
||||
@@ -954,6 +954,10 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool
|
||||
AstNode *node = ast_create_node(pc, NodeTypeUndefinedLiteral, token);
|
||||
*token_index += 1;
|
||||
return node;
|
||||
} else if (token->id == TokenIdKeywordType) {
|
||||
AstNode *node = ast_create_node(pc, NodeTypeTypeLiteral, token);
|
||||
*token_index += 1;
|
||||
return node;
|
||||
} else if (token->id == TokenIdKeywordError) {
|
||||
AstNode *node = ast_create_node(pc, NodeTypeErrorType, token);
|
||||
*token_index += 1;
|
||||
@@ -2470,7 +2474,34 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, int *token_index,
|
||||
}
|
||||
|
||||
/*
|
||||
TopLevelDecl : many(Directive) option(FnVisibleMod) (FnDef | ExternFnProto | RootExportDecl | Import | ContainerDecl | VariableDeclaration | ErrorValueDecl | CImportDecl)
|
||||
TypeDecl = "type" "Symbol" "=" TypeExpr ";"
|
||||
*/
|
||||
static AstNode *ast_parse_type_decl(ParseContext *pc, int *token_index,
|
||||
ZigList<AstNode*> *directives, VisibMod visib_mod)
|
||||
{
|
||||
Token *first_token = &pc->tokens->at(*token_index);
|
||||
|
||||
if (first_token->id != TokenIdKeywordType) {
|
||||
return nullptr;
|
||||
}
|
||||
*token_index += 1;
|
||||
|
||||
Token *name_tok = ast_eat_token(pc, token_index, TokenIdSymbol);
|
||||
ast_eat_token(pc, token_index, TokenIdEq);
|
||||
|
||||
AstNode *node = ast_create_node(pc, NodeTypeTypeDecl, first_token);
|
||||
ast_buf_from_token(pc, name_tok, &node->data.type_decl.symbol);
|
||||
node->data.type_decl.child_type = ast_parse_prefix_op_expr(pc, token_index, true);
|
||||
|
||||
node->data.type_decl.visib_mod = visib_mod;
|
||||
node->data.type_decl.directives = directives;
|
||||
|
||||
normalize_parent_ptrs(node);
|
||||
return node;
|
||||
}
|
||||
|
||||
/*
|
||||
TopLevelDecl = many(Directive) option(VisibleMod) (FnDef | ExternDecl | RootExportDecl | Import | ContainerDecl | GlobalVarDecl | ErrorValueDecl | CImportDecl | TypeDecl)
|
||||
*/
|
||||
static void ast_parse_top_level_decls(ParseContext *pc, int *token_index, ZigList<AstNode *> *top_level_decls) {
|
||||
for (;;) {
|
||||
@@ -2545,6 +2576,12 @@ static void ast_parse_top_level_decls(ParseContext *pc, int *token_index, ZigLis
|
||||
continue;
|
||||
}
|
||||
|
||||
AstNode *type_decl_node = ast_parse_type_decl(pc, token_index, directives, visib_mod);
|
||||
if (type_decl_node) {
|
||||
top_level_decls->append(type_decl_node);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (directives->length > 0) {
|
||||
ast_error(pc, directive_token, "invalid directive");
|
||||
}
|
||||
@@ -2631,9 +2668,16 @@ void normalize_parent_ptrs(AstNode *node) {
|
||||
set_field(&node->data.return_expr.expr);
|
||||
break;
|
||||
case NodeTypeVariableDeclaration:
|
||||
if (node->data.variable_declaration.directives) {
|
||||
set_list_fields(node->data.variable_declaration.directives);
|
||||
}
|
||||
set_field(&node->data.variable_declaration.type);
|
||||
set_field(&node->data.variable_declaration.expr);
|
||||
break;
|
||||
case NodeTypeTypeDecl:
|
||||
set_list_fields(node->data.type_decl.directives);
|
||||
set_field(&node->data.type_decl.child_type);
|
||||
break;
|
||||
case NodeTypeErrorValueDecl:
|
||||
// none
|
||||
break;
|
||||
@@ -2772,5 +2816,8 @@ void normalize_parent_ptrs(AstNode *node) {
|
||||
case NodeTypeErrorType:
|
||||
// none
|
||||
break;
|
||||
case NodeTypeTypeLiteral:
|
||||
// none
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user