Mercurial > hg > index.cgi
changeset 501:f3e9732973f1
Add basic integer operations to lwcc
Add +, -, *, and / to lwcc parser and code generator. Multiplication and
division require helper functions in a yet to be created support library.
These operations are integer only for the moment.
author | William Astle <lost@l-w.ca> |
---|---|
date | Tue, 24 Sep 2019 22:07:56 -0600 |
parents | 733fd05ca2a8 |
children | 14a40f8bb4eb |
files | lwcc/cc-gencode.c lwcc/cc-parse.c lwcc/tree.c lwcc/tree.h |
diffstat | 4 files changed, 97 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/lwcc/cc-gencode.c Thu Aug 29 17:00:17 2019 -0600 +++ b/lwcc/cc-gencode.c Tue Sep 24 22:07:56 2019 -0600 @@ -43,6 +43,34 @@ fprintf(output, "\tldd #%s\n", n->strval); break; + case NODE_OPER_PLUS: + generate_code(n->children, output); + fprintf(output, "\tpshs d\n"); + generate_code(n->children->next_child, output); + fprintf(output, "\taddd ,s++\n"); + break; + + case NODE_OPER_MINUS: + generate_code(n->children, output); + fprintf(output, "\tpshs d,x\n"); + generate_code(n->children->next_child, output); + fprintf(output, "\tstd 2,s\n\tpuls d\n\tsubd ,s++\n"); + break; + + case NODE_OPER_TIMES: + generate_code(n -> children, output); + fprintf(output, "\tpshs d\n"); + generate_code(n->children->next_child, output); + fprintf(output, "\tjsr ___mul16i\n"); + break; + + case NODE_OPER_DIVIDE: + generate_code(n -> children, output); + fprintf(output, "\tpshs d\n"); + generate_code(n->children->next_child, output); + fprintf(output, "\tjsr ___div16i\n"); + break; + default: for (nn = n -> children; nn; nn = nn -> next_child) generate_code(nn, output);
--- a/lwcc/cc-parse.c Thu Aug 29 17:00:17 2019 -0600 +++ b/lwcc/cc-parse.c Tue Sep 24 22:07:56 2019 -0600 @@ -169,19 +169,69 @@ } -node_t *parse_expr(struct parser_state *ps) +node_t *parse_term_real(struct parser_state *ps) { node_t *rv; - if (ps -> curtok -> ttype == TOK_CONST_INT) + + switch (ps -> curtok -> ttype) { + case TOK_CONST_INT: rv = node_create(NODE_CONST_INT, ps -> curtok -> strval); parse_next(ps); return rv; } - parse_generr(ps, "expr"); + + parse_generr(ps, "term"); return NULL; } +node_t *parse_expr_real(struct parser_state *ps, int prec) +{ + static struct { int tok; int nodetype; int prec; } operlist[] = { + { TOK_STAR, NODE_OPER_TIMES, 150 }, + { TOK_DIV, NODE_OPER_DIVIDE, 150 }, + { TOK_ADD, NODE_OPER_PLUS, 100 }, + { TOK_SUB, NODE_OPER_MINUS, 100 }, + { 0, 0, 0 } + }; + node_t *term1, *term2; + int i; + + term1 = parse_term_real(ps); + if (!term1) + return NULL; + +nextoper: + for (i = 0; operlist[i].tok; i++) + if (operlist[i].tok == ps -> curtok -> ttype) + break; + fprintf(stderr, "Matched operator: %d, %d\n", operlist[i].tok, operlist[i].prec); + // if we hit the end of the expression, return + if (operlist[i].tok == 0) + return term1; + + // is the next operator less or same precedence? + if (operlist[i].prec <= prec) + return term1; + + parse_next(ps); + term2 = parse_expr_real(ps, operlist[i].prec); + if (!term2) + { + parse_generr(ps, "expr"); + node_destroy(term2); + } + + term1 = node_create(operlist[i].nodetype, term1, term2); + term2 = NULL; + goto nextoper; +} + +node_t *parse_expr(struct parser_state *ps) +{ + return parse_expr_real(ps, 0); +} + node_t *parse_statement(struct parser_state *ps) { node_t *rv;
--- a/lwcc/tree.c Thu Aug 29 17:00:17 2019 -0600 +++ b/lwcc/tree.c Tue Sep 24 22:07:56 2019 -0600 @@ -53,6 +53,10 @@ "BLOCK", "STMT_RETURN", "CONST_INT", + "OPER_PLUS", + "OPER_MINUS", + "OPER_TIMES", + "OPER_DIVIDE", }; @@ -70,6 +74,13 @@ switch (type) { + case NODE_OPER_PLUS: + case NODE_OPER_MINUS: + case NODE_OPER_TIMES: + case NODE_OPER_DIVIDE: + nargs = 2; + break; + case NODE_DECL: nargs = 2; break;
--- a/lwcc/tree.h Thu Aug 29 17:00:17 2019 -0600 +++ b/lwcc/tree.h Tue Sep 24 22:07:56 2019 -0600 @@ -51,7 +51,11 @@ #define NODE_BLOCK 23 // statement block #define NODE_STMT_RETURN 24 // return statement #define NODE_CONST_INT 25 // constant integer -#define NODE_NUMTYPES 26 // the number of node types +#define NODE_OPER_PLUS 26 // addition +#define NODE_OPER_MINUS 27 // subtraction +#define NODE_OPER_TIMES 28 // multiplcation +#define NODE_OPER_DIVIDE 29 // division +#define NODE_NUMTYPES 30 // the number of node types typedef struct node_s node_t;