Mercurial > hg-old > index.cgi
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 |