aboutsummaryrefslogtreecommitdiff
path: root/src/parser.c
diff options
context:
space:
mode:
authorZachary Pierson <zacpiersonhehe@gmail.com>2017-02-10 23:41:23 -0600
committerZachary Pierson <zacpiersonhehe@gmail.com>2017-02-10 23:41:23 -0600
commitcad46ae51c8d3baed5a6c6d64a6e5d57fbe2a397 (patch)
treee931af6c1536ab8913d8168e7ee109a64dc7c981 /src/parser.c
parent3424b2badd347b76ced3f4107d98a12bb50ae49b (diff)
parent73d6a55f5c96459d30eca5747d1458bcf6e9fec4 (diff)
Merge https://github.com/gingerBill/Odin
Diffstat (limited to 'src/parser.c')
-rw-r--r--src/parser.c118
1 files changed, 38 insertions, 80 deletions
diff --git a/src/parser.c b/src/parser.c
index 079e39c2f..3179509e7 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -147,7 +147,6 @@ AST_NODE_KIND(_ExprBegin, "", i32) \
AST_NODE_KIND(SelectorExpr, "selector expression", struct { Token token; AstNode *expr, *selector; }) \
AST_NODE_KIND(IndexExpr, "index expression", struct { AstNode *expr, *index; Token open, close; }) \
AST_NODE_KIND(DerefExpr, "dereference expression", struct { Token op; AstNode *expr; }) \
- AST_NODE_KIND(DemaybeExpr, "demaybe expression", struct { Token op; AstNode *expr; }) \
AST_NODE_KIND(SliceExpr, "slice expression", struct { \
AstNode *expr; \
Token open, close, interval; \
@@ -251,7 +250,6 @@ AST_NODE_KIND(_ComplexStmtBegin, "", i32) \
AST_NODE_KIND(TypeMatchStmt, "type match statement", struct { \
Token token; \
AstNode *tag; \
- AstNode *var; \
AstNode *body; \
}) \
AST_NODE_KIND(DeferStmt, "defer statement", struct { Token token; AstNode *stmt; }) \
@@ -333,10 +331,6 @@ AST_NODE_KIND(_TypeBegin, "", i32) \
Token token; \
AstNode *type; \
}) \
- AST_NODE_KIND(MaybeType, "maybe type", struct { \
- Token token; \
- AstNode *type; \
- }) \
AST_NODE_KIND(ArrayType, "array type", struct { \
Token token; \
AstNode *count; \
@@ -469,7 +463,6 @@ Token ast_node_token(AstNode *node) {
case AstNode_CastExpr: return node->CastExpr.token;
case AstNode_FieldValue: return node->FieldValue.eq;
case AstNode_DerefExpr: return node->DerefExpr.op;
- case AstNode_DemaybeExpr: return node->DemaybeExpr.op;
case AstNode_BlockExpr: return node->BlockExpr.open;
case AstNode_GiveExpr: return node->GiveExpr.token;
case AstNode_IfExpr: return node->IfExpr.token;
@@ -513,7 +506,6 @@ Token ast_node_token(AstNode *node) {
case AstNode_HelperType: return node->HelperType.token;
case AstNode_ProcType: return node->ProcType.token;
case AstNode_PointerType: return node->PointerType.token;
- case AstNode_MaybeType: return node->MaybeType.token;
case AstNode_ArrayType: return node->ArrayType.token;
case AstNode_DynamicArrayType: return node->DynamicArrayType.token;
case AstNode_VectorType: return node->VectorType.token;
@@ -693,13 +685,6 @@ AstNode *ast_deref_expr(AstFile *f, AstNode *expr, Token op) {
return result;
}
-AstNode *ast_demaybe_expr(AstFile *f, AstNode *expr, Token op) {
- AstNode *result = make_ast_node(f, AstNode_DemaybeExpr);
- result->DemaybeExpr.expr = expr;
- result->DemaybeExpr.op = op;
- return result;
-}
-
AstNode *ast_interval_expr(AstFile *f, Token op, AstNode *left, AstNode *right) {
AstNode *result = make_ast_node(f, AstNode_IntervalExpr);
@@ -907,11 +892,10 @@ AstNode *ast_match_stmt(AstFile *f, Token token, AstNode *init, AstNode *tag, As
}
-AstNode *ast_type_match_stmt(AstFile *f, Token token, AstNode *tag, AstNode *var, AstNode *body) {
+AstNode *ast_type_match_stmt(AstFile *f, Token token, AstNode *tag, AstNode *body) {
AstNode *result = make_ast_node(f, AstNode_TypeMatchStmt);
result->TypeMatchStmt.token = token;
result->TypeMatchStmt.tag = tag;
- result->TypeMatchStmt.var = var;
result->TypeMatchStmt.body = body;
return result;
}
@@ -1031,13 +1015,6 @@ AstNode *ast_pointer_type(AstFile *f, Token token, AstNode *type) {
return result;
}
-AstNode *ast_maybe_type(AstFile *f, Token token, AstNode *type) {
- AstNode *result = make_ast_node(f, AstNode_MaybeType);
- result->MaybeType.token = token;
- result->MaybeType.type = type;
- return result;
-}
-
AstNode *ast_array_type(AstFile *f, Token token, AstNode *count, AstNode *elem) {
AstNode *result = make_ast_node(f, AstNode_ArrayType);
result->ArrayType.token = token;
@@ -1777,6 +1754,7 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
} else if (str_eq(name.string, str_lit("file"))) { return ast_basic_directive(f, token, name.string);
} else if (str_eq(name.string, str_lit("line"))) { return ast_basic_directive(f, token, name.string);
} else if (str_eq(name.string, str_lit("procedure"))) { return ast_basic_directive(f, token, name.string);
+ } else if (str_eq(name.string, str_lit("type"))) { return ast_helper_type(f, token, parse_type(f));
} else {
operand = ast_tag_expr(f, token, name, parse_expr(f, false));
}
@@ -1999,10 +1977,6 @@ AstNode *parse_atom_expr(AstFile *f, bool lhs) {
operand = ast_deref_expr(f, operand, expect_token(f, Token_Pointer));
break;
- case Token_Maybe: // Demaybe
- operand = ast_demaybe_expr(f, operand, expect_token(f, Token_Maybe));
- break;
-
case Token_OpenBrace:
if (!lhs && is_literal_type(operand) && f->expr_level >= 0) {
operand = parse_literal_value(f, operand);
@@ -2205,9 +2179,7 @@ AstNode *parse_value_decl(AstFile *f, AstNodeArray lhs) {
bool is_mutable = true;
if (allow_token(f, Token_Colon)) {
- if (!allow_token(f, Token_type)) {
- type = parse_type_attempt(f);
- }
+ type = parse_type_attempt(f);
} else if (f->curr_token.kind != Token_Eq &&
f->curr_token.kind != Token_Semicolon) {
syntax_error(f->curr_token, "Expected a type separator `:` or `=`");
@@ -2553,10 +2525,16 @@ AstNode *parse_type_or_ident(AstFile *f) {
return e;
}
- case Token_type: {
- Token token = expect_token(f, Token_type);
- AstNode *type = parse_type(f);
- return ast_helper_type(f, token, type);
+ case Token_Hash: {
+ Token hash_token = expect_token(f, Token_Hash);
+ Token name = expect_token(f, Token_Ident);
+ String tag = name.string;
+ if (str_eq(tag, str_lit("type"))) {
+ AstNode *type = parse_type(f);
+ return ast_helper_type(f, hash_token, type);
+ }
+ syntax_error(name, "Expected `type` after #");
+ return ast_bad_expr(f, hash_token, f->curr_token);
}
case Token_Pointer: {
@@ -2565,12 +2543,6 @@ AstNode *parse_type_or_ident(AstFile *f) {
return ast_pointer_type(f, token, elem);
}
- case Token_Maybe: {
- Token token = expect_token(f, Token_Maybe);
- AstNode *elem = parse_type(f);
- return ast_maybe_type(f, token, elem);
- }
-
case Token_OpenBracket: {
Token token = expect_token(f, Token_OpenBracket);
AstNode *count_expr = NULL;
@@ -2972,8 +2944,7 @@ AstNode *parse_for_stmt(AstFile *f) {
f->expr_level = -1;
if (f->curr_token.kind != Token_Semicolon) {
cond = parse_simple_stmt(f, true);
- if (cond->kind == AstNode_AssignStmt &&
- cond->AssignStmt.op.kind == Token_in) {
+ if (cond->kind == AstNode_AssignStmt && cond->AssignStmt.op.kind == Token_in) {
is_range = true;
}
}
@@ -3065,6 +3036,7 @@ AstNode *parse_for_stmt(AstFile *f) {
#endif
}
+
AstNode *parse_case_clause(AstFile *f) {
Token token = f->curr_token;
AstNodeArray list = make_ast_node_array(f);
@@ -3097,6 +3069,7 @@ AstNode *parse_type_case_clause(AstFile *f) {
}
+
AstNode *parse_match_stmt(AstFile *f) {
if (f->curr_proc == NULL) {
syntax_error(f->curr_token, "You cannot use a match statement in the file scope");
@@ -3108,37 +3081,16 @@ AstNode *parse_match_stmt(AstFile *f) {
AstNode *tag = NULL;
AstNode *body = NULL;
Token open, close;
+ bool is_type_match = false;
- if (allow_token(f, Token_type)) {
+ if (f->curr_token.kind != Token_OpenBrace) {
isize prev_level = f->expr_level;
f->expr_level = -1;
- AstNode *var = parse_ident(f);
- expect_token_after(f, Token_in, "match type name");
- tag = parse_simple_stmt(f, false);
-
- f->expr_level = prev_level;
-
- open = expect_token(f, Token_OpenBrace);
- AstNodeArray list = make_ast_node_array(f);
-
- while (f->curr_token.kind == Token_case ||
- f->curr_token.kind == Token_default) {
- array_add(&list, parse_type_case_clause(f));
- }
-
- close = expect_token(f, Token_CloseBrace);
- body = ast_block_stmt(f, list, open, close);
-
- tag = convert_stmt_to_expr(f, tag, str_lit("type match expression"));
- return ast_type_match_stmt(f, token, tag, var, body);
- } else {
- if (f->curr_token.kind != Token_OpenBrace) {
- isize prev_level = f->expr_level;
- f->expr_level = -1;
- if (f->curr_token.kind != Token_Semicolon) {
- tag = parse_simple_stmt(f, false);
- }
+ tag = parse_simple_stmt(f, true);
+ if (tag->kind == AstNode_AssignStmt && tag->AssignStmt.op.kind == Token_in) {
+ is_type_match = true;
+ } else {
if (allow_token(f, Token_Semicolon)) {
init = tag;
tag = NULL;
@@ -3146,28 +3098,33 @@ AstNode *parse_match_stmt(AstFile *f) {
tag = parse_simple_stmt(f, false);
}
}
-
- f->expr_level = prev_level;
}
+ f->expr_level = prev_level;
+ }
+ open = expect_token(f, Token_OpenBrace);
+ AstNodeArray list = make_ast_node_array(f);
- open = expect_token(f, Token_OpenBrace);
- AstNodeArray list = make_ast_node_array(f);
-
- while (f->curr_token.kind == Token_case ||
- f->curr_token.kind == Token_default) {
+ while (f->curr_token.kind == Token_case ||
+ f->curr_token.kind == Token_default) {
+ if (is_type_match) {
+ array_add(&list, parse_type_case_clause(f));
+ } else {
array_add(&list, parse_case_clause(f));
}
+ }
- close = expect_token(f, Token_CloseBrace);
+ close = expect_token(f, Token_CloseBrace);
- body = ast_block_stmt(f, list, open, close);
+ body = ast_block_stmt(f, list, open, close);
+ if (!is_type_match) {
tag = convert_stmt_to_expr(f, tag, str_lit("match expression"));
return ast_match_stmt(f, token, init, tag, body);
+ } else {
+ return ast_type_match_stmt(f, token, tag, body);
}
}
-
AstNode *parse_defer_stmt(AstFile *f) {
if (f->curr_proc == NULL) {
syntax_error(f->curr_token, "You cannot use a defer statement in the file scope");
@@ -3359,6 +3316,7 @@ AstNode *parse_stmt(AstFile *f) {
Token hash_token = expect_token(f, Token_Hash);
Token name = expect_token(f, Token_Ident);
String tag = name.string;
+
if (str_eq(tag, str_lit("import"))) {
AstNode *cond = NULL;
Token import_name = {0};