Commit dc502042d5
Changed files (3)
src/c_tokenizer.cpp
@@ -121,6 +121,9 @@ static void begin_token(CTokenize *ctok, CTokId id) {
case CTokIdRParen:
case CTokIdEOF:
case CTokIdDot:
+ case CTokIdAsterisk:
+ case CTokIdBang:
+ case CTokIdTilde:
break;
}
}
@@ -228,10 +231,22 @@ void tokenize_c_macro(CTokenize *ctok, const uint8_t *c) {
begin_token(ctok, CTokIdRParen);
end_token(ctok);
break;
+ case '*':
+ begin_token(ctok, CTokIdAsterisk);
+ end_token(ctok);
+ break;
case '-':
begin_token(ctok, CTokIdMinus);
end_token(ctok);
break;
+ case '!':
+ begin_token(ctok, CTokIdBang);
+ end_token(ctok);
+ break;
+ case '~':
+ begin_token(ctok, CTokIdTilde);
+ end_token(ctok);
+ break;
default:
return mark_error(ctok);
}
src/c_tokenizer.hpp
@@ -22,6 +22,9 @@ enum CTokId {
CTokIdRParen,
CTokIdEOF,
CTokIdDot,
+ CTokIdAsterisk,
+ CTokIdBang,
+ CTokIdTilde,
};
enum CNumLitSuffix {
src/translate_c.cpp
@@ -4000,6 +4000,10 @@ static void render_macros(Context *c) {
}
}
+static AstNode *parse_ctok_primary_expr(Context *c, CTokenize *ctok, size_t *tok_i);
+static AstNode *parse_ctok_expr(Context *c, CTokenize *ctok, size_t *tok_i);
+static AstNode *parse_ctok_prefix_op_expr(Context *c, CTokenize *ctok, size_t *tok_i);
+
static AstNode *parse_ctok_num_lit(Context *c, CTokenize *ctok, size_t *tok_i, bool negate) {
CTok *tok = &ctok->tokens.at(*tok_i);
if (tok->id == CTokIdNumLitInt) {
@@ -4027,7 +4031,7 @@ static AstNode *parse_ctok_num_lit(Context *c, CTokenize *ctok, size_t *tok_i, b
return nullptr;
}
-static AstNode *parse_ctok(Context *c, CTokenize *ctok, size_t *tok_i) {
+static AstNode *parse_ctok_primary_expr(Context *c, CTokenize *ctok, size_t *tok_i) {
CTok *tok = &ctok->tokens.at(*tok_i);
switch (tok->id) {
case CTokIdCharLit:
@@ -4044,38 +4048,17 @@ static AstNode *parse_ctok(Context *c, CTokenize *ctok, size_t *tok_i) {
return parse_ctok_num_lit(c, ctok, tok_i, false);
case CTokIdSymbol:
{
- bool need_symbol = false;
- CTokId curr_id = CTokIdSymbol;
+ *tok_i += 1;
Buf *symbol_name = buf_create_from_buf(&tok->data.symbol);
- AstNode *curr_node = trans_create_node_symbol(c, symbol_name);
- AstNode *parent_node = curr_node;
- do {
- *tok_i += 1;
- CTok* curr_tok = &ctok->tokens.at(*tok_i);
- if (need_symbol) {
- if (curr_tok->id == CTokIdSymbol) {
- symbol_name = buf_create_from_buf(&curr_tok->data.symbol);
- curr_node = trans_create_node_field_access(c, parent_node, buf_create_from_buf(symbol_name));
- parent_node = curr_node;
- need_symbol = false;
- } else {
- return nullptr;
- }
- } else {
- if (curr_tok->id == CTokIdDot) {
- need_symbol = true;
- continue;
- } else {
- break;
- }
- }
- } while (curr_id != CTokIdEOF);
- return curr_node;
+ return trans_create_node_symbol(c, symbol_name);
}
case CTokIdLParen:
{
*tok_i += 1;
- AstNode *inner_node = parse_ctok(c, ctok, tok_i);
+ AstNode *inner_node = parse_ctok_expr(c, ctok, tok_i);
+ if (inner_node == nullptr) {
+ return nullptr;
+ }
CTok *next_tok = &ctok->tokens.at(*tok_i);
if (next_tok->id != CTokIdRParen) {
@@ -4087,12 +4070,69 @@ static AstNode *parse_ctok(Context *c, CTokenize *ctok, size_t *tok_i) {
case CTokIdDot:
case CTokIdEOF:
case CTokIdRParen:
+ case CTokIdAsterisk:
+ case CTokIdBang:
+ case CTokIdTilde:
// not able to make sense of this
return nullptr;
}
zig_unreachable();
}
+static AstNode *parse_ctok_expr(Context *c, CTokenize *ctok, size_t *tok_i) {
+ return parse_ctok_prefix_op_expr(c, ctok, tok_i);
+}
+
+static AstNode *parse_ctok_suffix_op_expr(Context *c, CTokenize *ctok, size_t *tok_i) {
+ AstNode *node = parse_ctok_primary_expr(c, ctok, tok_i);
+ if (node == nullptr)
+ return nullptr;
+
+ while (true) {
+ CTok *first_tok = &ctok->tokens.at(*tok_i);
+ if (first_tok->id == CTokIdDot) {
+ *tok_i += 1;
+
+ CTok *name_tok = &ctok->tokens.at(*tok_i);
+ if (name_tok->id != CTokIdSymbol) {
+ return nullptr;
+ }
+ *tok_i += 1;
+
+ node = trans_create_node_field_access(c, node, buf_create_from_buf(&name_tok->data.symbol));
+ } else if (first_tok->id == CTokIdAsterisk) {
+ *tok_i += 1;
+
+ node = trans_create_node_addr_of(c, false, false, node);
+ } else {
+ return node;
+ }
+ }
+}
+
+static PrefixOp ctok_to_prefix_op(CTok *token) {
+ switch (token->id) {
+ case CTokIdBang: return PrefixOpBoolNot;
+ case CTokIdMinus: return PrefixOpNegation;
+ case CTokIdTilde: return PrefixOpBinNot;
+ case CTokIdAsterisk: return PrefixOpDereference;
+ default: return PrefixOpInvalid;
+ }
+}
+static AstNode *parse_ctok_prefix_op_expr(Context *c, CTokenize *ctok, size_t *tok_i) {
+ CTok *op_tok = &ctok->tokens.at(*tok_i);
+ PrefixOp prefix_op = ctok_to_prefix_op(op_tok);
+ if (prefix_op == PrefixOpInvalid) {
+ return parse_ctok_suffix_op_expr(c, ctok, tok_i);
+ }
+ *tok_i += 1;
+
+ AstNode *prefix_op_expr = parse_ctok_prefix_op_expr(c, ctok, tok_i);
+ if (prefix_op_expr == nullptr)
+ return nullptr;
+ return trans_create_node_prefix_op(c, prefix_op, prefix_op_expr);
+}
+
static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *char_ptr) {
tokenize_c_macro(ctok, (const uint8_t *)char_ptr);
@@ -4105,7 +4145,7 @@ static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *ch
assert(name_tok->id == CTokIdSymbol && buf_eql_buf(&name_tok->data.symbol, name));
tok_i += 1;
- AstNode *result_node = parse_ctok(c, ctok, &tok_i);
+ AstNode *result_node = parse_ctok_suffix_op_expr(c, ctok, &tok_i);
if (result_node == nullptr) {
return;
}