updated test.sh for nobug compatibility, has still problems with joined stderr and...
[mala.git] / engine / program.c
blob8dd95fdd4ac9d7a054a7f8f3e82dcf6002366f85
1 /*
2 program.c - MaLa Program container
4 Copyright (C) 2005, Christian Thaeter <chth@gmx.net>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License version 2 as
8 published by the Free Software Foundation.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, contact me.
20 #include <stdlib.h>
21 #include <ctype.h>
22 #include <stdio.h>
23 #include "mala_types.h"
24 #include "program.h"
25 #include "engine.h"
26 #include "action.h"
27 #include "stringlist.h"
29 /* genreate a string array for the states */
30 #define MALA_STATE(s) #s
31 const char * mala_program_states [] = {MALA_STATES};
32 #undef MALA_STATE
35 void
36 mala_program_acogc_initize (void* o)
38 TRACE (mala_acogc);
39 MalaProgram self = (MalaProgram)o;
40 self->program = NULL;
43 acogc_mark_result
44 mala_program_acogc_mark (void* o)
46 TRACE (mala_acogc);
47 MalaProgram self = (MalaProgram)o;
48 acogc_object_lastmark (self->program);
49 //acogc_object_mark (self->program);
50 return ACOGC_KEEP;
53 MalaProgram
54 mala_program_new_cstr (const char* cmd, MalaEngine engine)
56 TRACE (mala_program);
57 ACOGC_STACK_ENTER (&engine->gcroot);
58 ACOGC_STACK_PTR (MalaProgram, self);
59 ACOGC_STACK_PTR (MalaStringList, elem);
61 self.ptr = acogc_factory_alloc (&engine->gcfactory_programs);
63 self.ptr->program = mala_stringlist_new (engine);
65 elem.ptr = mala_stringlist_new (engine);
66 elem.ptr->string = mala_string_new_cstr (cmd, engine->words);
67 llist_insert_tail (&self.ptr->program->node, &elem.ptr->node);
69 self.ptr->pptr = self.ptr->program;
71 self.ptr->nesting_limit = 5000;
72 self.ptr->nesting_level = -1;
73 self.ptr->engine = engine;
74 self.ptr->negated = 0;
75 self.ptr->state = MALA_START;
77 ACOGC_STACK_LEAVE;
78 return self.ptr;
82 void
83 mala_program_run (MalaProgram self, mala_state dest)
85 TRACE (mala_program);
87 mala_state state = MALA_START;
89 if (++self->nesting_level >= self->nesting_limit)
90 state = mala_program_commonexception (self, MALA_STRING_ERROR_NESTING_LIMIT_EXCEED, mala_program_pptr (self));
92 if (self->state == MALA_REMOVE)
93 dest = MALA_REMOVE;
94 else if (dest == MALA_REMOVE)
95 self->state = MALA_REMOVE;
97 while (mala_program_pptr (self) != self->program &&
98 state > dest && state < MALA_EXCEPTION)
100 state = mala_program_step (self);
101 if (state == MALA_LITERAL)
103 if (dest != MALA_REMOVE)
104 mala_stringlist_fwd (&self->pptr);
105 else
106 mala_program_pptr (self)->string = self->engine->common_string[MALA_STRING_PASS];
110 TODO("set state to MALA_FINISH at the end of fully evaluated program");
112 --self->nesting_level;
113 if (dest != MALA_REMOVE)
114 self->state = state;
117 mala_state
118 mala_program_eval_arg (MalaProgram self, int n, mala_state final, MalaStringList_ref node)
120 if (self->state > MALA_EFAULT)
121 return self->state;
123 mala_state nstate;
124 MalaStringList opptr = self->pptr;
126 MalaStringList pptr = (MalaStringList) llist_get_nth_stop (&self->pptr->node, n,
127 llist_get_prev (&self->program->node));
129 TRACE (mala_program, "eval arg %d '%s' to %s", n,
130 pptr?mala_stringlist_cstr (pptr):"(missing)",
131 mala_engine_states[final]);
133 if (pptr)
135 mala_state ostate = self->state;
136 self->pptr = pptr;
138 if (node)
139 *node = pptr;
141 mala_program_run (self, final);
143 if (node)
144 *node = mala_stringlist_next (*node);
146 nstate = self->state;
147 self->state = ostate;
149 else
151 ERROR (mala_program, "Missing Argument");
152 nstate = mala_program_commonexception (self, MALA_STRING_ERROR_MISSING_ARGUMENT, self->program);
153 if (node)
154 *node = NULL;
157 self->pptr = opptr;
158 return nstate;
161 mala_state
162 mala_program_eval_arg_fmt (MalaProgram self, int n, const char* fmt, void* data, MalaStringList_ref node)
164 MalaStringList nde;
165 mala_state state;
167 state = mala_program_eval_arg (self, n, MALA_LITERAL, &nde);
168 if (node)
169 *node = nde;
171 int r;
173 r = mala_string_scan (mala_stringlist_string (nde), fmt, data);
174 if (r != 1)
175 return mala_program_commonexception (self, MALA_STRING_ERROR_WRONG_TYPE, nde);
177 return state;
180 mala_state
181 mala_program_step (MalaProgram self)
183 TODO(" handle --LITERAL");
184 mala_state state;
186 MalaStringList pptr = mala_program_pptr (self);
188 TRACE (mala_program, "%s", mala_stringlist_cstr (pptr));
190 if (pptr->string && pptr->string->action)
192 MalaAction action = mala_program_pptr_action (self);
193 state = action->parser (self);
195 else if (self->state != MALA_EXCEPTION)
196 state = MALA_LITERAL;
198 return state;
202 // Local Variables:
203 // mode: C
204 // c-file-style: "gnu"
205 // End:
206 // arch-tag: fd8544bd-4144-44fe-8a9e-635aa0d3c393
207 // end_of_file