# HG changeset patch # User lost # Date 1230776786 0 # Node ID df0c4a46af8fb828168e30cab3be9d7f4cce58ea # Parent 4f14eae64d38ce6e82cdf4b6077b0b12980d8646 Started adding expression handling infrastructure diff -r 4f14eae64d38 -r df0c4a46af8f src/Makefile.am --- a/src/Makefile.am Thu Oct 23 03:39:29 2008 +0000 +++ b/src/Makefile.am Thu Jan 01 02:26:26 2009 +0000 @@ -1,4 +1,4 @@ bin_PROGRAMS = lwasm -lwasm_SOURCES = main.c expr.c lwval.c pass1.c pass2.c -EXTRA_DIST = instab.h lwasm.h expr.h lwval.h +lwasm_SOURCES = main.c expr.c lwval.c pass1.c pass2.c util.c +EXTRA_DIST = instab.h lwasm.h expr.h lwval.h util.h diff -r 4f14eae64d38 -r df0c4a46af8f src/expr.c --- a/src/expr.c Thu Oct 23 03:39:29 2008 +0000 +++ b/src/expr.c Thu Jan 01 02:26:26 2009 +0000 @@ -25,82 +25,140 @@ #define __expr_c_seen__ -#include +#include #include #include "expr.h" -#include "lwval.h" +#include "util.h" + +lwasm_expr_stack_t *lwasm_expr_stack_create(void) +{ + lwasm_expr_stack_t *s; + + s = lwasm_alloc(sizeof(lwasm_expr_stack_t)); + s -> head = NULL; + s -> tail = NULL; + return s; +} -// parse a single term out of the expression; return NULL if -// end of expression; return LWVAL_TYPE_ERR if error -/* -The following is handled by lwasm_parse_term: +void lwasm_expr_stack_free(lwasm_expr_stack_t *s) +{ + while (s -> head) + { + s -> tail = s -> head; + s -> head = s -> head -> next; + lwasm_expr_term_free(s -> tail -> term); + lwasm_free(s -> tail); + } + lwasm_free(s); +} -- constants -- parsing a symbol -- unary - -- unary + -- () +void lwasm_expr_term_free(lwasm_expr_term_t *t) +{ + if (t) + { + if (t -> symbol) + lwasm_free(t -> symbol); + lwasm_free(t); + } +} + +lwasm_expr_term_t *lwasm_expr_term_create_oper(int oper) +{ + lwasm_expr_term_t *t; + + t = lwasm_alloc(sizeof(lwasm_expr_term_t)); + t -> term_type = LWASM_TERM_OPER; + t -> value = oper; + return t; +} -*/ -LWVAL *lwasm_parse_term(char **ptr) +lwasm_expr_term_t *lwasm_expr_term_create_int(int val) { - int sign = 1; - int s = 0; - LWVAL *rval; + lwasm_expr_term_t *t; + + t = lwasm_alloc(sizeof(lwasm_expr_term_t)); + t -> term_type = LWASM_TERM_INT; + t -> value = val; + return t; +} + +lwasm_expr_term_t *lwasm_expr_term_create_sym(char *sym) +{ + lwasm_expr_term_t *t; -start_term: - if (!**ptr || isspace(**ptr) || **ptr == ')') - return s ? lwval_construct_err(1) : NULL; + t = lwasm_alloc(sizeof(lwasm_expr_term_t)); + t -> term_type = LWASM_TERM_SYM; + t -> symbol = lwasm_strdup(sym); + return t; +} - s = 1; - // unary + - NOOP - if (**ptr == '+') +lwasm_expr_term_t *lwasm_expr_term_dup(lwasm_expr_term_t *t) +{ + switch (t -> term_type) { - (*ptr)++; - goto start_term; + case LWASM_TERM_INT: + return lwasm_expr_term_create_int(t -> value); + + case LWASM_TERM_OPER: + return lwasm_expr_term_create_oper(t -> value); + + case LWASM_TERM_SYM: + return lwasm_expr_term_create_sym(t -> symbol); + + default: + fprintf(stderr, "lwasm_expr_term_dup(): invalid term type %d\n", t -> term_type); + exit(1); + } +// can't get here +} + +void lwasm_expr_stack_push(lwasm_expr_stack_t *s, lwasm_expr_term_t *t) +{ + lwasm_expr_stack_node_t *n; + + if (!s) + { + fprintf(stderr, "lwasm_expr_stack_push(): invalid stack pointer\n"); + exit(1); } - // unary - - applied once the rest of the term is worked out - if (**ptr == '-') + n = lwasm_alloc(sizeof(lwasm_expr_stack_node_t)); + n -> next = NULL; + n -> prev = s -> tail; + n -> term = lwasm_expr_term_dup(t); + + if (s -> head) + { + s -> tail -> next = n; + s -> tail = n; + } + else { - (*ptr)++; - sign = -sign; - goto start_term; + s -> head = n; + s -> tail = n; + } +} + +lwasm_expr_term_t *lwasm_expr_stack_pop(lwasm_expr_stack_t *s) +{ + lwasm_expr_term_t *t; + lwasm_expr_stack_node_t *n; + + if (!(s -> tail)) + return NULL; + + n = s -> tail; + s -> tail = n -> prev; + if (!(n -> prev)) + { + s -> head = NULL; } - // parens - if (**ptr == '(') - { - LWVAL *v; - (*ptr)++; - rval = lwasm_parse_expr(ptr); - if (**ptr != ')') - { - lwval_destroy(rval); - return lwval_construct_err(1); - } - (*ptr)++; - goto ret; - } - - // parse an actual term here; no more futzing with expressions - -ret: - // apply negation if appropriate - if (sign < 0) - lwval_neg(rval); - return rval; + t = n -> term; + n -> term = NULL; + + lwasm_free(n); + + return t; } - -// parse an expression -LWVAL *lwasm_parse_expr(char **ptr) -{ -} - -// attempt to evaluate/simplify expression -int lwasm_eval_expr(LWVAL *expr) -{ -} - - diff -r 4f14eae64d38 -r df0c4a46af8f src/expr.h --- a/src/expr.h Thu Oct 23 03:39:29 2008 +0000 +++ b/src/expr.h Thu Jan 01 02:26:26 2009 +0000 @@ -25,19 +25,69 @@ #ifndef __expr_h_seen__ #define __expr_h_seen__ -#include "lwval.h" - #ifndef __expr_c_seen__ #define __expr_E__ extern #else #define __expr_E__ #endif -// parse an expression -__expr_E__ LWVAL *lwasm_parse_expr(char **ptr); +// term types +#define LWASM_TERM_NONE 0 +#define LWASM_TERM_OPER 1 // an operator +#define LWASM_TERM_INT 2 // 32 bit signed integer +#define LWASM_TERM_SYM 3 // symbol reference + +// operator types +#define LWASM_OPER_NONE 0 +#define LWASM_OPER_PLUS 1 // + +#define LWASM_OPER_MINUS 2 // - +#define LWASM_OPER_TIMES 3 // * +#define LWASM_OPER_DIVIDE 4 // / +#define LWASM_OPER_MOD 5 // % +#define LWASM_OPER_INTDIV 6 // \ +#define LWASM_OPER_BWAND 7 // bitwise AND +#define LWASM_OPER_BWOR 8 // bitwise OR +#define LWASM_OPER_BWXOR 9 // bitwise XOR +#define LWASM_OPER_AND 10 // boolean AND +#define LWASM_OPER_OR 11 // boolean OR +#define LWASM_OPER_NEG 12 // unary negation (2's complement) +#define LWASM_OPER_COM 13 // unary 1's complement + -// attempt to evaluate/simplify expression -__expr_E__ int lwasm_eval_expr(LWVAL *expr); +// term structure +typedef struct lwasm_expr_term_s +{ + int term_type; // type of term (see above) + char *symbol; // name of a symbol + int value; // value of the term (int) or operator number (OPER) +} lwasm_expr_term_t; + +// type for an expression evaluation stack +typedef struct lwasm_expr_stack_node_s lwasm_expr_stack_node_t; +struct lwasm_expr_stack_node_s +{ + lwasm_expr_term_t *term; + lwasm_expr_stack_node_t *prev; + lwasm_expr_stack_node_t *next; +}; + +typedef struct lwasm_expr_stack_s +{ + lwasm_expr_stack_node_t *head; + lwasm_expr_stack_node_t *tail; +} lwasm_expr_stack_t; + +__expr_E__ void lwasm_expr_term_free(lwasm_expr_term_t *t); +__expr_E__ lwasm_expr_term_t *lwasm_expr_term_create_oper(int oper); +__expr_E__ lwasm_expr_term_t *lwasm_expr_term_create_sym(char *sym); +__expr_E__ lwasm_expr_term_t *lwasm_expr_term_create_int(int val); +__expr_E__ lwasm_expr_term_t *lwasm_expr_term_dup(lwasm_expr_term_t *t); + +__expr_E__ void lwasm_expr_stack_free(lwasm_expr_stack_t *s); +__expr_E__ lwasm_expr_stack_t *lwasm_expr_stack_create(void); + +__expr_E__ void lwasm_expr_stack_push(lwasm_expr_stack_t *s, lwasm_expr_term_t *t); +__expr_E__ lwasm_expr_term_t *lwasm_expr_stack_pop(lwasm_expr_stack_t *s); #undef __expr_E__ diff -r 4f14eae64d38 -r df0c4a46af8f src/util.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/util.c Thu Jan 01 02:26:26 2009 +0000 @@ -0,0 +1,66 @@ +/* +util.c +Copyright © 2008 William Astle + +This file is part of LWASM. + +LWASM is free software: you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +/* +Utility functions +*/ + +#define __util_c_seen__ + +#include +#include +#include +#include + +#include "util.h" + +void *lwasm_alloc(int size) +{ + void *ptr; + + ptr = malloc(size); + if (!ptr) + { + // bail out; memory allocation error + fprintf(stderr, "Memory allocation error\n"); + exit(1); + } + return ptr; +} + +void lwasm_free(void *ptr) +{ + if (ptr) + free(ptr); +} + +char *lwasm_strdup(const char *s) +{ + char *d; + + d = strdup(s); + if (!d) + { + fprintf(stderr, "lwasm_strdup(): memory allocation error\n"); + exit(1); + } + + return d; +} diff -r 4f14eae64d38 -r df0c4a46af8f src/util.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/util.h Thu Jan 01 02:26:26 2009 +0000 @@ -0,0 +1,43 @@ +/* +expr.h +Copyright © 2008 William Astle + +This file is part of LWASM. + +LWASM is free software: you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see . +*/ + +/* +Utility functions +*/ + +#ifndef __util_h_seen__ +#define __util_h_seen__ + +#ifndef __util_c_seen__ +#define __util_E__ extern +#else +#define __util_E__ +#endif + +// allocate memory +__util_E__ void *lwasm_alloc(int size); +__util_E__ void lwasm_free(void *ptr); + +// string stuff +__util_E__ char *lwasm_strdup(const char *s); + +#undef __util_E__ + +#endif // __util_h_seen__