~ubuntu-branches/debian/sid/genius/sid

« back to all changes in this revision

Viewing changes to src/parseutil.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2006-08-21 12:57:45 UTC
  • Revision ID: james.westby@ubuntu.com-20060821125745-sl9ks8v7fq324bdf
Tags: upstream-0.7.6.1
ImportĀ upstreamĀ versionĀ 0.7.6.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* GENIUS Calculator
 
2
 * Copyright (C) 1997-2004 Jiri (George) Lebl
 
3
 *
 
4
 * Author: Jiri (George) Lebl
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2 of the License, or
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the  Free Software
 
18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
 
19
 * USA.
 
20
 */
 
21
 
 
22
#include "config.h"
 
23
 
 
24
#include <glib.h>
 
25
#include <string.h>
 
26
#include "structs.h"
 
27
#include "mpwrap.h"
 
28
#include "eval.h"
 
29
#include "dict.h"
 
30
#include "util.h"
 
31
#include "calc.h"
 
32
#include "matrix.h"
 
33
#include "matrixw.h"
 
34
 
 
35
#include "parseutil.h"
 
36
 
 
37
extern GSList *gel_parsestack;
 
38
 
 
39
 
 
40
gboolean
 
41
gp_push_func (gboolean vararg)
 
42
{
 
43
        GelETree * tree;
 
44
        GelETree * val;
 
45
        GSList * list = NULL;
 
46
        int i = 0;
 
47
        
 
48
        val = stack_pop(&gel_parsestack);
 
49
        if(!val)
 
50
                return FALSE;
 
51
 
 
52
 
 
53
        for(;;) {
 
54
                tree = stack_pop(&gel_parsestack);
 
55
                if(tree && tree->type==EXPRLIST_START_NODE) {
 
56
                        gel_freetree(tree);
 
57
                        break;
 
58
                }
 
59
                /*we have gone all the way to the top and haven't found a
 
60
                  marker or tree is not an ident node*/
 
61
                if(!tree || tree->type != IDENTIFIER_NODE) {
 
62
                        if(tree) gel_freetree(tree);
 
63
                        g_slist_foreach(list,(GFunc)gel_freetree,NULL);
 
64
                        g_slist_free(list); 
 
65
                        return FALSE;
 
66
                }
 
67
                list = g_slist_prepend(list,tree->id.id);
 
68
                gel_freetree(tree);
 
69
                i++;
 
70
        }
 
71
        
 
72
        GET_NEW_NODE(tree);
 
73
 
 
74
        tree->type = FUNCTION_NODE;
 
75
        tree->func.func = d_makeufunc(NULL,val,list,i, NULL);
 
76
        tree->func.func->context = -1;
 
77
        tree->func.func->vararg = vararg;
 
78
 
 
79
        stack_push(&gel_parsestack,tree);
 
80
 
 
81
        return TRUE;
 
82
}
 
83
 
 
84
gboolean
 
85
gp_prepare_push_param (gboolean setfunc)
 
86
{
 
87
        GelETree * ident;
 
88
        GelETree * val;
 
89
        GelETree * func;
 
90
 
 
91
        /* FIXME: setfunc not yet implemented */
 
92
        g_assert ( ! setfunc);
 
93
 
 
94
        val = stack_pop (&gel_parsestack);
 
95
        if (val == NULL)
 
96
                return FALSE;
 
97
 
 
98
        ident = stack_pop (&gel_parsestack);
 
99
        if (ident == NULL)
 
100
                return FALSE;
 
101
 
 
102
        func = gel_makenum_null ();
 
103
 
 
104
        stack_push (&gel_parsestack, func);
 
105
        stack_push (&gel_parsestack, ident);
 
106
        stack_push (&gel_parsestack, val);
 
107
 
 
108
        return TRUE;
 
109
}
 
110
 
 
111
/* returns true if this is a 'by' sep */
 
112
gboolean
 
113
gp_prepare_push_region_sep (void)
 
114
{
 
115
        GelETree *e1, *e2;
 
116
 
 
117
        e2 = stack_pop (&gel_parsestack);
 
118
        e1 = stack_pop (&gel_parsestack);
 
119
 
 
120
        if (e2->type == OPERATOR_NODE &&
 
121
            e2->op.oper == E_REGION_SEP) {
 
122
                GelETree *a1 = e2->op.args;
 
123
                GelETree *a2 = e2->op.args->any.next;
 
124
                a1->any.next = NULL;
 
125
                a2->any.next = NULL;
 
126
                e2->op.args = NULL;
 
127
                gel_freetree (e2);
 
128
                stack_push (&gel_parsestack, e1);
 
129
                stack_push (&gel_parsestack, a1);
 
130
                stack_push (&gel_parsestack, a2);
 
131
 
 
132
                return TRUE;
 
133
        } else {
 
134
                stack_push (&gel_parsestack, e1);
 
135
                stack_push (&gel_parsestack, e2);
 
136
 
 
137
                return FALSE;
 
138
        }
 
139
}
 
140
 
 
141
/*pops the last expression, pushes a marker
 
142
  entry and puts the last expression back*/
 
143
gboolean
 
144
gp_push_marker(GelETreeType markertype)
 
145
{
 
146
        GelETree * last_expr = stack_pop(&gel_parsestack);
 
147
        GelETree * tree;
 
148
        
 
149
        if(!last_expr)
 
150
                return FALSE;
 
151
       
 
152
        GET_NEW_NODE(tree);
 
153
        tree->type = markertype;
 
154
        stack_push(&gel_parsestack,tree);
 
155
        stack_push(&gel_parsestack,last_expr);
 
156
        return TRUE;
 
157
}
 
158
 
 
159
/*pushes a marker*/
 
160
void
 
161
gp_push_marker_simple(GelETreeType markertype)
 
162
{
 
163
        GelETree *tree;
 
164
        GET_NEW_NODE(tree);
 
165
        tree->type = markertype;
 
166
        stack_push(&gel_parsestack,tree);
 
167
}
 
168
 
 
169
/*puts a spacer into the tree, spacers are just useless nodes to be removed
 
170
  before evaluation, they just signify where there were parenthesis*/
 
171
gboolean
 
172
gp_push_spacer(void)
 
173
{
 
174
        GelETree * last_expr = stack_pop(&gel_parsestack);
 
175
        
 
176
        if(!last_expr)
 
177
                return FALSE;
 
178
        else if(last_expr->type == SPACER_NODE)
 
179
                stack_push(&gel_parsestack,last_expr);
 
180
        else {
 
181
                GelETree * tree;
 
182
                GET_NEW_NODE(tree);
 
183
                tree->type = SPACER_NODE;
 
184
                tree->sp.arg = last_expr;
 
185
                stack_push(&gel_parsestack,tree);
 
186
        }
 
187
        return TRUE;
 
188
}
 
189
        
 
190
/*gather all expressions up until a row start marker and push the
 
191
  result as a MATRIX_ROW_NODE*/
 
192
gboolean
 
193
gp_push_matrix_row(void)
 
194
{
 
195
        GelETree *tree;
 
196
        GelETree *row = NULL;
 
197
        int i=0;
 
198
        for(;;) {
 
199
                tree = stack_pop(&gel_parsestack);
 
200
                /*we have gone all the way to the top and haven't found a
 
201
                  marker*/
 
202
                if(!tree) {
 
203
                        while(row) {
 
204
                                GelETree *li = row->any.next;
 
205
                                gel_freetree(row);
 
206
                                row = li;
 
207
                        }
 
208
                        return FALSE;
 
209
                }
 
210
                if(tree->type==EXPRLIST_START_NODE) {
 
211
                        gel_freetree(tree);
 
212
                        break;
 
213
                }
 
214
                tree->any.next = row;
 
215
                row = tree;
 
216
                i++;
 
217
        }
 
218
        GET_NEW_NODE(tree);
 
219
        tree->type = MATRIX_ROW_NODE;
 
220
        tree->row.args = row;
 
221
        tree->row.nargs = i;
 
222
 
 
223
        stack_push(&gel_parsestack,tree);
 
224
        
 
225
        return TRUE;
 
226
}
 
227
        
 
228
/*gather all expressions up until a row start marker and push the
 
229
  result as a matrix*/
 
230
gboolean
 
231
gp_push_matrix(gboolean quoted)
 
232
{
 
233
        GelETree *tree;
 
234
        int i,j;
 
235
        int cols,rows;
 
236
        GSList *rowl = NULL;
 
237
        GSList *liy;
 
238
        GelETree *lix;
 
239
        
 
240
        GelMatrix *matrix;
 
241
        
 
242
        rows=0;
 
243
        cols=0;
 
244
        for(;;) {
 
245
                tree = stack_pop(&gel_parsestack);
 
246
                /*we have gone all the way to the top and haven't found a
 
247
                  marker*/
 
248
                if(!tree) {
 
249
                        GSList *li;
 
250
                        for(li=rowl;li;li=g_slist_next(li)) {
 
251
                                GelETree *row = li->data;
 
252
                                while(row) {
 
253
                                        GelETree *a = row->any.next;
 
254
                                        gel_freetree(row);
 
255
                                        row = a;
 
256
                                }
 
257
                        }
 
258
                        g_slist_free(rowl);
 
259
                        /**/g_warning("BAD MATRIX, NO START MARKER");
 
260
                        return FALSE;
 
261
                } else if(tree->type==MATRIX_START_NODE) {
 
262
                        gel_freetree(tree);
 
263
                        break;
 
264
                } else if(tree->type==MATRIX_ROW_NODE) {
 
265
                        if(tree->row.nargs>cols)
 
266
                                cols = tree->row.nargs;
 
267
                        rowl = g_slist_prepend(rowl,tree->row.args);
 
268
                        tree->row.args = NULL;
 
269
                        tree->row.nargs = 0;
 
270
                        gel_freetree(tree);
 
271
                        rows++;
 
272
                        continue;
 
273
                } else {
 
274
                        GSList *li;
 
275
                        gel_freetree(tree);
 
276
                        for(li=rowl;li;li=g_slist_next(li)) {
 
277
                                GelETree *row = li->data;
 
278
                                while(row) {
 
279
                                        GelETree *a = row->any.next;
 
280
                                        gel_freetree(row);
 
281
                                        row = a;
 
282
                                }
 
283
                        }
 
284
                        g_slist_free(rowl);
 
285
                        /**/g_warning("BAD MATRIX, A NON ROW ELEMENT FOUND");
 
286
                        return FALSE;
 
287
                }
 
288
        }
 
289
 
 
290
        matrix = gel_matrix_new();
 
291
        gel_matrix_set_size(matrix, cols, rows, TRUE /* padding */);
 
292
        
 
293
        for(j=0,liy=rowl;liy;j++,liy=g_slist_next(liy)) {
 
294
                for(i=0,lix=liy->data;lix;i++,lix=lix->any.next) {
 
295
                        gel_matrix_index(matrix,i,j) = lix;
 
296
                }
 
297
                /* On non-quoted matrices fill the matrix with nulls
 
298
                 * since those may be converted to zeros */
 
299
                if ( ! quoted) {
 
300
                        for(;i < cols;i++) {
 
301
                                gel_matrix_index (matrix, i, j) =
 
302
                                        gel_makenum_null ();
 
303
                        }
 
304
                }
 
305
        }
 
306
        g_slist_free(rowl);
 
307
        
 
308
        GET_NEW_NODE(tree);
 
309
        tree->type = MATRIX_NODE;
 
310
        tree->mat.matrix = gel_matrixw_new_with_matrix(matrix);
 
311
        tree->mat.quoted = quoted ? 1 : 0;
 
312
        
 
313
        stack_push(&gel_parsestack,tree);
 
314
        return TRUE;
 
315
}
 
316
 
 
317
/*pushes a NULL onto the stack, null cannot be evaluated, it will be
 
318
  read as ""*/
 
319
void
 
320
gp_push_null(void)
 
321
{
 
322
        GelETree *tree;
 
323
        GET_NEW_NODE(tree);
 
324
        tree->type = NULL_NODE;
 
325
 
 
326
        stack_push(&gel_parsestack,tree);
 
327
}
 
328
 
 
329
void
 
330
gp_convert_identifier_to_bool (void)
 
331
{
 
332
        GelETree *val;
 
333
 
 
334
        val = stack_peek (&gel_parsestack);
 
335
        if (val == NULL ||
 
336
            val->type != IDENTIFIER_NODE) {
 
337
                /**/g_warning ("NO IDENTIFIER TO CONVERT TO TRY TO CONVERT BOOL");
 
338
                return;
 
339
        }
 
340
        if (val->id.id == NULL ||
 
341
            val->id.id->token == NULL)
 
342
                return;
 
343
 
 
344
        if (strcmp (val->id.id->token, "true") == 0 ||
 
345
             strcmp (val->id.id->token, "True") == 0 ||
 
346
             strcmp (val->id.id->token, "TRUE") == 0) {
 
347
                gel_emptytree (val);
 
348
                gel_makenum_bool_from (val, TRUE);
 
349
        } else if (strcmp (val->id.id->token, "false") == 0 ||
 
350
                   strcmp (val->id.id->token, "False") == 0 ||
 
351
                   strcmp (val->id.id->token, "FALSE") == 0) {
 
352
                gel_emptytree (val);
 
353
                gel_makenum_bool_from (val, FALSE);
 
354
        }
 
355
}