Mercurial > hg > index.cgi
changeset 506:7e8298f7bc0a
Add basic syntax for typecasting
Add parser support for type casts. This current scheme handles only integer
types.
Also include parenthesis grouping in expressions.
author | William Astle <lost@l-w.ca> |
---|---|
date | Sun, 27 Oct 2019 12:06:01 -0600 |
parents | 59b8c8b15bd4 |
children | dd9c5cef2e80 |
files | lwcc/cc-parse.c lwcc/tree.c lwcc/tree.h |
diffstat | 3 files changed, 127 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/lwcc/cc-parse.c Sat Oct 26 22:01:55 2019 -0600 +++ b/lwcc/cc-parse.c Sun Oct 27 12:06:01 2019 -0600 @@ -171,9 +171,94 @@ node_t *parse_expr_real(struct parser_state *ps, int prec); +// parse an elementary type (int, etc.) +node_t *parse_elem_type(struct parser_state *ps) +{ + int sgn = -1; + int nt = -1; + int nn = 1; + + if (ps -> curtok -> ttype == TOK_KW_SIGNED) + { + sgn = 1; + parse_next(ps); + } + else if (ps -> curtok -> ttype == TOK_KW_UNSIGNED) + { + sgn = 0; + parse_next(ps); + } + + switch (ps -> curtok -> ttype) + { + // NOTE: char is unsigned by default + case TOK_KW_CHAR: + if (sgn == -1 || sgn == 0) + nt = NODE_TYPE_UCHAR; + else + nt = NODE_TYPE_CHAR; + break; + + case TOK_KW_SHORT: + nt = sgn ? NODE_TYPE_SHORT : NODE_TYPE_USHORT; + break; + + case TOK_KW_INT: + nt = sgn ? NODE_TYPE_INT : NODE_TYPE_UINT; + break; + + case TOK_KW_LONG: + parse_next(ps); + if (ps -> curtok -> ttype == TOK_KW_LONG) + { + nt = sgn ? NODE_TYPE_LONGLONG : NODE_TYPE_ULONGLONG; + break; + } + nn = 0; + nt = sgn ? NODE_TYPE_LONG : NODE_TYPE_ULONG; + break; + + } + if (nt == -1) + { + if (sgn == -1) + { + return NULL; + } + else + { + nt = sgn ? NODE_TYPE_INT : NODE_TYPE_UINT; + } + } + else if (nn) + { + parse_next(ps); + } + return node_create(nt); +} + +// if ident is non-zero, accept an identifier as part of the type; otherwise +// do not accept an identifier; currently a stub +node_t *parse_type(struct parser_state *ps, int ident) +{ + node_t *rv; + + // see if we have an elementary type + rv = parse_elem_type(ps); + + // look for "struct", etc. + + // look for pointer indicator(s) + + // look for identifier if wanted/allowed + + // look for array indicator or function parameter list + return rv; +} + node_t *parse_term_real(struct parser_state *ps) { - node_t *rv; + node_t *rv, *rv2; switch (ps -> curtok -> ttype) { @@ -181,6 +266,40 @@ rv = node_create(NODE_CONST_INT, ps -> curtok -> strval); parse_next(ps); return rv; + + // opening paren: either grouping or type cast + case TOK_OPAREN: + parse_next(ps); + // parse a type without an identifier + rv2 = parse_type(ps, 0); + if (rv2) + { + if (ps -> curtok -> ttype != TOK_CPAREN) + { + node_destroy(rv2); + parse_generr(ps, "missing ) on type cast"); + return NULL; + } + parse_next(ps); + // detect C99 compound literal here + rv = parse_expr_real(ps, 175); + if (!rv) + { + node_destroy(rv); + return NULL; + } + return node_create(NODE_TYPECAST, rv2, rv); + } + // grouping + rv = parse_expr_real(ps, 0); + if (ps -> curtok -> ttype != TOK_CPAREN) + { + node_destroy(rv); + parse_generr(ps, "missing ) on expression grouping"); + return NULL; + } + parse_next(ps); + return rv; } parse_generr(ps, "term");
--- a/lwcc/tree.c Sat Oct 26 22:01:55 2019 -0600 +++ b/lwcc/tree.c Sun Oct 27 12:06:01 2019 -0600 @@ -90,6 +90,7 @@ "OPER_BWXORASS", "OPER_BWORASS", "OPER_COMMA", + "TYPECAST", }; @@ -151,6 +152,10 @@ nargs = 2; break; + case NODE_TYPECAST: + nargs = 2; + break; + case NODE_OPER_POSTINC: case NODE_OPER_POSTDEC: nargs = 1;
--- a/lwcc/tree.h Sat Oct 26 22:01:55 2019 -0600 +++ b/lwcc/tree.h Sun Oct 27 12:06:01 2019 -0600 @@ -88,7 +88,8 @@ #define NODE_OPER_BWXORASS 60 // bitwise xor/assign combo #define NODE_OPER_BWORASS 61 // bitwise or/assign combo #define NODE_OPER_COMMA 62 // comma sequential evaluation operator -#define NODE_NUMTYPES 63 // the number of node types +#define NODE_TYPECAST 63 // type cast to unsigned long long +#define NODE_NUMTYPES 64 // the number of node types typedef struct node_s node_t;