commit 756ad62e31c58c6d9232191d7c88cafa03fce56c
parent d9044484307482d2ce8e258f6e3897ee0d36d329
Author: Drew DeVault <sir@cmpwn.com>
Date: Wed, 23 Dec 2020 15:36:19 -0500
parse: implement unary arithmetic
Diffstat:
3 files changed, 71 insertions(+), 23 deletions(-)
diff --git a/include/ast.h b/include/ast.h
@@ -126,10 +126,15 @@ struct ast_expression_list {
struct ast_expression_list *next;
};
-struct ast_return_expression {
+struct ast_expression_return {
struct ast_expression *value;
};
+struct ast_expression_unarithm {
+ enum unarithm_operator op;
+ struct ast_expression *operand;
+};
+
struct ast_expression {
enum expr_type type;
union {
@@ -139,7 +144,8 @@ struct ast_expression {
struct ast_expression_binding binding;
struct ast_expression_constant constant;
struct ast_expression_list list;
- struct ast_return_expression _return;
+ struct ast_expression_return _return;
+ struct ast_expression_unarithm unarithm;
};
};
diff --git a/include/expr.h b/include/expr.h
@@ -50,26 +50,25 @@ struct expression_assign {
};
enum binarithm_operator {
- BIN_BAND,
- BIN_BNOT,
- BIN_BOR,
- BIN_DIV,
- BIN_GREATER,
- BIN_GREATEREQ,
- BIN_LAND,
- BIN_LEQUAL,
- BIN_LESS,
- BIN_LESSEQ,
- BIN_LOR,
- BIN_LSHIFT,
- BIN_LXOR,
- BIN_MINUS,
- BIN_MODULO,
- BIN_NEQUAL,
- BIN_PLUS,
- BIN_RSHIFT,
- BIN_TIMES,
- BIN_BXOR,
+ BIN_BAND, // &
+ BIN_BOR, // |
+ BIN_DIV, // /
+ BIN_GREATER, // >
+ BIN_GREATEREQ, // >=
+ BIN_LAND, // &&
+ BIN_LEQUAL, // ==
+ BIN_LESS, // <
+ BIN_LESSEQ, // <=
+ BIN_LOR, // ||
+ BIN_LSHIFT, // <<
+ BIN_LXOR, // ^^
+ BIN_MINUS, // -
+ BIN_MODULO, // %
+ BIN_NEQUAL, // !=
+ BIN_PLUS, // +
+ BIN_RSHIFT, // >>
+ BIN_TIMES, // *
+ BIN_BXOR, // ^
};
struct expression_binarithm {
@@ -110,6 +109,20 @@ struct expression_return {
struct expression *value;
};
+enum unarithm_operator {
+ UN_ADDRESS, // &
+ UN_BNOT, // ~
+ UN_DEREF, // *
+ UN_LNOT, // !
+ UN_MINUS, // -
+ UN_PLUS, // +
+};
+
+struct expression_unarithm {
+ enum unarithm_operator op;
+ struct expression *operand;
+};
+
struct expression {
const struct type *result;
enum expr_type type;
@@ -122,6 +135,7 @@ struct expression {
union expression_constant constant;
struct expression_list list;
struct expression_return _return;
+ struct expression_unarithm unarithm;
};
};
diff --git a/src/parse.c b/src/parse.c
@@ -532,11 +532,35 @@ parse_postfix_expression(struct parser *par)
assert(0); // Unreachable
}
+static enum unarithm_operator
+unop_for_token(enum lexical_token tok)
+{
+ switch (tok) {
+ case T_PLUS: // +
+ return UN_PLUS;
+ case T_MINUS: // -
+ return UN_MINUS;
+ case T_BNOT: // ~
+ return UN_BNOT;
+ case T_LNOT: // !
+ return UN_LNOT;
+ case T_TIMES: // *
+ return UN_DEREF;
+ case T_BAND: // &
+ return UN_ADDRESS;
+ default:
+ assert(0); // Invariant
+ }
+ assert(0); // Unreachable
+}
+
static struct ast_expression *
parse_unary_expression(struct parser *par)
{
trace(TR_PARSE, "unary-arithmetic");
+
struct token tok;
+ struct ast_expression *exp;
switch (lex(par->lex, &tok)) {
case T_PLUS: // +
case T_MINUS: // -
@@ -544,7 +568,11 @@ parse_unary_expression(struct parser *par)
case T_LNOT: // !
case T_TIMES: // *
case T_BAND: // &
- assert(0); // TODO
+ exp = calloc(1, sizeof(struct ast_expression));
+ exp->type = EXPR_UNARITHM;
+ exp->unarithm.op = unop_for_token(tok.token);
+ exp->unarithm.operand = parse_unary_expression(par);
+ return exp;
default:
unlex(par->lex, &tok);
return parse_postfix_expression(par);