harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 756ad62e31c58c6d9232191d7c88cafa03fce56c
parent d9044484307482d2ce8e258f6e3897ee0d36d329
Author: Drew DeVault <sir@cmpwn.com>
Date:   Wed, 23 Dec 2020 15:36:19 -0500

parse: implement unary arithmetic

Diffstat:
Minclude/ast.h | 10++++++++--
Minclude/expr.h | 54++++++++++++++++++++++++++++++++++--------------------
Msrc/parse.c | 30+++++++++++++++++++++++++++++-
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);