aboutsummaryrefslogtreecommitdiff
path: root/src/parser.c
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-01-25 19:19:25 +0000
committerGinger Bill <bill@gingerbill.org>2017-01-25 19:19:25 +0000
commitb59a052e32b1ed84134e31baad86c8e401f796c6 (patch)
tree9aef601f0d9a25e43fe046f274508bf774dad9a2 /src/parser.c
parent12498b2d390c95fd49672f8ee1c64b7b254c293c (diff)
Change casting syntax: `cast(T)x` `transmute(T)x` et al.
Diffstat (limited to 'src/parser.c')
-rw-r--r--src/parser.c119
1 files changed, 102 insertions, 17 deletions
diff --git a/src/parser.c b/src/parser.c
index 4223c36fe..7549245f4 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -142,17 +142,26 @@ AST_NODE_KIND(_ExprBegin, "", i32) \
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(CallExpr, "call expression", struct { \
- AstNode *proc; \
- AstNodeArray args; \
- Token open, close; \
- Token ellipsis; \
- }) \
AST_NODE_KIND(SliceExpr, "slice expression", struct { \
AstNode *expr; \
Token open, close; \
AstNode *low, *high; \
}) \
+ AST_NODE_KIND(CallExpr, "call expression", struct { \
+ AstNode * proc; \
+ AstNodeArray args; \
+ Token open; \
+ Token close; \
+ Token ellipsis; \
+ }) \
+ AST_NODE_KIND(MacroCallExpr, "macro call expression", struct { \
+ AstNode * macro; \
+ Token bang; \
+ AstNodeArray args; \
+ Token open; \
+ Token close; \
+ }) \
+ AST_NODE_KIND(CastExpr, "cast expression", struct { Token token; AstNode *type, *expr; Token open, close; }) \
AST_NODE_KIND(FieldValue, "field value", struct { Token eq; AstNode *field, *value; }) \
AST_NODE_KIND(BlockExpr, "block expr", struct { \
AstNodeArray stmts; \
@@ -436,6 +445,8 @@ Token ast_node_token(AstNode *node) {
return node->ParenExpr.open;
case AstNode_CallExpr:
return ast_node_token(node->CallExpr.proc);
+ case AstNode_MacroCallExpr:
+ return ast_node_token(node->MacroCallExpr.macro);
case AstNode_SelectorExpr:
if (node->SelectorExpr.selector != NULL) {
return ast_node_token(node->SelectorExpr.selector);
@@ -447,6 +458,8 @@ Token ast_node_token(AstNode *node) {
return node->SliceExpr.open;
case AstNode_Ellipsis:
return node->Ellipsis.token;
+ case AstNode_CastExpr:
+ return node->CastExpr.token;
case AstNode_FieldValue:
return node->FieldValue.eq;
case AstNode_DerefExpr:
@@ -655,14 +668,25 @@ AstNode *make_paren_expr(AstFile *f, AstNode *expr, Token open, Token close) {
AstNode *make_call_expr(AstFile *f, AstNode *proc, AstNodeArray args, Token open, Token close, Token ellipsis) {
AstNode *result = make_node(f, AstNode_CallExpr);
- result->CallExpr.proc = proc;
- result->CallExpr.args = args;
+ result->CallExpr.proc = proc;
+ result->CallExpr.args = args;
result->CallExpr.open = open;
result->CallExpr.close = close;
result->CallExpr.ellipsis = ellipsis;
return result;
}
+AstNode *make_macro_call_expr(AstFile *f, AstNode *macro, Token bang, AstNodeArray args, Token open, Token close) {
+ AstNode *result = make_node(f, AstNode_MacroCallExpr);
+ result->MacroCallExpr.macro = macro;
+ result->MacroCallExpr.bang = bang;
+ result->MacroCallExpr.args = args;
+ result->MacroCallExpr.open = open;
+ result->MacroCallExpr.close = close;
+ return result;
+}
+
+
AstNode *make_selector_expr(AstFile *f, Token token, AstNode *expr, AstNode *selector) {
AstNode *result = make_node(f, AstNode_SelectorExpr);
result->SelectorExpr.expr = expr;
@@ -755,6 +779,16 @@ AstNode *make_field_value(AstFile *f, AstNode *field, AstNode *value, Token eq)
return result;
}
+AstNode *make_cast_expr(AstFile *f, Token token, AstNode *type, AstNode *expr, Token open, Token close) {
+ AstNode *result = make_node(f, AstNode_CastExpr);
+ result->CastExpr.token = token;
+ result->CastExpr.type = type;
+ result->CastExpr.expr = expr;
+ result->CastExpr.open = open;
+ result->CastExpr.close = close;
+ return result;
+}
+
AstNode *make_compound_lit(AstFile *f, AstNode *type, AstNodeArray elems, Token open, Token close) {
AstNode *result = make_node(f, AstNode_CompoundLit);
result->CompoundLit.type = type;
@@ -1774,8 +1808,12 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
return type;
}
- case Token_OpenBrace: return parse_block_expr(f);
- case Token_if: return parse_if_expr(f);
+ case Token_if:
+ if (lhs) goto error;
+ return parse_if_expr(f);
+ case Token_OpenBrace:
+ if (lhs) goto error;
+ return parse_block_expr(f);
default: {
AstNode *type = parse_identifier_or_type(f);
@@ -1790,6 +1828,7 @@ AstNode *parse_operand(AstFile *f, bool lhs) {
}
}
+error:
Token begin = f->curr_token;
syntax_error(begin, "Expected an operand");
fix_advance_to_next_stmt(f);
@@ -1844,6 +1883,36 @@ AstNode *parse_call_expr(AstFile *f, AstNode *operand) {
return make_call_expr(f, operand, args, open_paren, close_paren, ellipsis);
}
+
+AstNode *parse_macro_call_expr(AstFile *f, AstNode *operand) {
+ AstNodeArray args = make_ast_node_array(f);
+ Token bang, open_paren, close_paren;
+
+ bang = expect_token(f, Token_Not);
+
+ f->expr_level++;
+ open_paren = expect_token(f, Token_OpenParen);
+
+ while (f->curr_token.kind != Token_CloseParen &&
+ f->curr_token.kind != Token_EOF) {
+ if (f->curr_token.kind == Token_Comma) {
+ syntax_error(f->curr_token, "Expected an expression not a ,");
+ }
+
+ AstNode *arg = parse_expr(f, false);
+ array_add(&args, arg);
+
+ if (!allow_token(f, Token_Comma)) {
+ break;
+ }
+ }
+
+ f->expr_level--;
+ close_paren = expect_closing(f, Token_CloseParen, str_lit("argument list"));
+
+ return make_macro_call_expr(f, operand, bang, args, open_paren, close_paren);
+}
+
AstNode *parse_atom_expr(AstFile *f, bool lhs) {
AstNode *operand = parse_operand(f, lhs);
@@ -1853,6 +1922,9 @@ AstNode *parse_atom_expr(AstFile *f, bool lhs) {
case Token_OpenParen:
operand = parse_call_expr(f, operand);
break;
+ case Token_Not:
+ operand = parse_macro_call_expr(f, operand);
+ break;
case Token_Period: {
Token token = f->curr_token;
@@ -1936,6 +2008,20 @@ AstNode *parse_atom_expr(AstFile *f, bool lhs) {
AstNode *parse_unary_expr(AstFile *f, bool lhs) {
switch (f->curr_token.kind) {
+
+ case Token_cast:
+ case Token_transmute:
+ case Token_down_cast:
+ case Token_union_cast:
+ {
+ Token token = f->curr_token; next_token(f);
+ Token open = expect_token(f, Token_OpenParen);
+ AstNode *type = parse_type(f);
+ Token close = expect_token(f, Token_CloseParen);
+ AstNode *expr = parse_unary_expr(f, lhs);
+ return make_cast_expr(f, token, type, expr, open, close);
+ } break;
+
case Token_Pointer: {
Token op = f->curr_token;
next_token(f);
@@ -1945,7 +2031,7 @@ AstNode *parse_unary_expr(AstFile *f, bool lhs) {
}
return make_unary_expr(f, op, expr);
} break;
- case Token_Maybe:
+ // case Token_Maybe:
case Token_Add:
case Token_Sub:
case Token_Not:
@@ -2432,10 +2518,10 @@ AstNode *parse_identifier_or_type(AstFile *f) {
AstNode *sel = parse_identifier(f);
e = make_selector_expr(f, token, e, sel);
}
- // if (f->curr_token.kind == Token_OpenParen) {
- // // HACK NOTE(bill): For type_of_val(expr)
- // e = parse_call_expr(f, e);
- // }
+ if (f->curr_token.kind == Token_OpenParen) {
+ // HACK NOTE(bill): For type_of_val(expr) et al.
+ e = parse_call_expr(f, e);
+ }
return e;
}
@@ -2464,8 +2550,7 @@ AstNode *parse_identifier_or_type(AstFile *f) {
bool is_vector = false;
if (f->curr_token.kind == Token_Ellipsis) {
- count_expr = make_ellipsis(f, f->curr_token, NULL);
- next_token(f);
+ count_expr = make_ellipsis(f, expect_token(f, Token_Ellipsis), NULL);
} else if (f->curr_token.kind == Token_vector) {
next_token(f);
if (f->curr_token.kind != Token_CloseBracket) {