comparison src/expr.c @ 17:df0c4a46af8f

Started adding expression handling infrastructure
author lost
date Thu, 01 Jan 2009 02:26:26 +0000
parents 1f598d89b9b0
children 218aabbc3b1a
comparison
equal deleted inserted replaced
16:4f14eae64d38 17:df0c4a46af8f
23 mechanism to store results. 23 mechanism to store results.
24 */ 24 */
25 25
26 #define __expr_c_seen__ 26 #define __expr_c_seen__
27 27
28 #include <ctype.h> 28 #include <stdio.h>
29 #include <stdlib.h> 29 #include <stdlib.h>
30 30
31 #include "expr.h" 31 #include "expr.h"
32 #include "lwval.h" 32 #include "util.h"
33 33
34 // parse a single term out of the expression; return NULL if 34 lwasm_expr_stack_t *lwasm_expr_stack_create(void)
35 // end of expression; return LWVAL_TYPE_ERR if error 35 {
36 /* 36 lwasm_expr_stack_t *s;
37 The following is handled by lwasm_parse_term: 37
38 s = lwasm_alloc(sizeof(lwasm_expr_stack_t));
39 s -> head = NULL;
40 s -> tail = NULL;
41 return s;
42 }
38 43
39 - constants 44 void lwasm_expr_stack_free(lwasm_expr_stack_t *s)
40 - parsing a symbol 45 {
41 - unary - 46 while (s -> head)
42 - unary + 47 {
43 - () 48 s -> tail = s -> head;
49 s -> head = s -> head -> next;
50 lwasm_expr_term_free(s -> tail -> term);
51 lwasm_free(s -> tail);
52 }
53 lwasm_free(s);
54 }
44 55
45 */ 56 void lwasm_expr_term_free(lwasm_expr_term_t *t)
46 LWVAL *lwasm_parse_term(char **ptr)
47 { 57 {
48 int sign = 1; 58 if (t)
49 int s = 0; 59 {
50 LWVAL *rval; 60 if (t -> symbol)
61 lwasm_free(t -> symbol);
62 lwasm_free(t);
63 }
64 }
65
66 lwasm_expr_term_t *lwasm_expr_term_create_oper(int oper)
67 {
68 lwasm_expr_term_t *t;
51 69
52 start_term: 70 t = lwasm_alloc(sizeof(lwasm_expr_term_t));
53 if (!**ptr || isspace(**ptr) || **ptr == ')') 71 t -> term_type = LWASM_TERM_OPER;
54 return s ? lwval_construct_err(1) : NULL; 72 t -> value = oper;
73 return t;
74 }
55 75
56 s = 1; 76 lwasm_expr_term_t *lwasm_expr_term_create_int(int val)
57 // unary + - NOOP 77 {
58 if (**ptr == '+') 78 lwasm_expr_term_t *t;
79
80 t = lwasm_alloc(sizeof(lwasm_expr_term_t));
81 t -> term_type = LWASM_TERM_INT;
82 t -> value = val;
83 return t;
84 }
85
86 lwasm_expr_term_t *lwasm_expr_term_create_sym(char *sym)
87 {
88 lwasm_expr_term_t *t;
89
90 t = lwasm_alloc(sizeof(lwasm_expr_term_t));
91 t -> term_type = LWASM_TERM_SYM;
92 t -> symbol = lwasm_strdup(sym);
93 return t;
94 }
95
96 lwasm_expr_term_t *lwasm_expr_term_dup(lwasm_expr_term_t *t)
97 {
98 switch (t -> term_type)
59 { 99 {
60 (*ptr)++; 100 case LWASM_TERM_INT:
61 goto start_term; 101 return lwasm_expr_term_create_int(t -> value);
102
103 case LWASM_TERM_OPER:
104 return lwasm_expr_term_create_oper(t -> value);
105
106 case LWASM_TERM_SYM:
107 return lwasm_expr_term_create_sym(t -> symbol);
108
109 default:
110 fprintf(stderr, "lwasm_expr_term_dup(): invalid term type %d\n", t -> term_type);
111 exit(1);
112 }
113 // can't get here
114 }
115
116 void lwasm_expr_stack_push(lwasm_expr_stack_t *s, lwasm_expr_term_t *t)
117 {
118 lwasm_expr_stack_node_t *n;
119
120 if (!s)
121 {
122 fprintf(stderr, "lwasm_expr_stack_push(): invalid stack pointer\n");
123 exit(1);
62 } 124 }
63 125
64 // unary - - applied once the rest of the term is worked out 126 n = lwasm_alloc(sizeof(lwasm_expr_stack_node_t));
65 if (**ptr == '-') 127 n -> next = NULL;
128 n -> prev = s -> tail;
129 n -> term = lwasm_expr_term_dup(t);
130
131 if (s -> head)
66 { 132 {
67 (*ptr)++; 133 s -> tail -> next = n;
68 sign = -sign; 134 s -> tail = n;
69 goto start_term; 135 }
136 else
137 {
138 s -> head = n;
139 s -> tail = n;
140 }
141 }
142
143 lwasm_expr_term_t *lwasm_expr_stack_pop(lwasm_expr_stack_t *s)
144 {
145 lwasm_expr_term_t *t;
146 lwasm_expr_stack_node_t *n;
147
148 if (!(s -> tail))
149 return NULL;
150
151 n = s -> tail;
152 s -> tail = n -> prev;
153 if (!(n -> prev))
154 {
155 s -> head = NULL;
70 } 156 }
71 157
72 // parens 158 t = n -> term;
73 if (**ptr == '(') 159 n -> term = NULL;
74 { 160
75 LWVAL *v; 161 lwasm_free(n);
76 (*ptr)++; 162
77 rval = lwasm_parse_expr(ptr); 163 return t;
78 if (**ptr != ')')
79 {
80 lwval_destroy(rval);
81 return lwval_construct_err(1);
82 }
83 (*ptr)++;
84 goto ret;
85 }
86
87 // parse an actual term here; no more futzing with expressions
88
89 ret:
90 // apply negation if appropriate
91 if (sign < 0)
92 lwval_neg(rval);
93 return rval;
94 } 164 }
95
96 // parse an expression
97 LWVAL *lwasm_parse_expr(char **ptr)
98 {
99 }
100
101 // attempt to evaluate/simplify expression
102 int lwasm_eval_expr(LWVAL *expr)
103 {
104 }
105
106