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.
23 #include "mala_types.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
};
36 mala_program_acogc_initize (void* o
)
39 MalaProgram self
= (MalaProgram
)o
;
44 mala_program_acogc_mark (void* o
)
47 MalaProgram self
= (MalaProgram
)o
;
48 acogc_object_lastmark (self
->program
);
49 //acogc_object_mark (self->program);
54 mala_program_new_cstr (const char* cmd
, MalaEngine engine
)
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
;
83 mala_program_run (MalaProgram self
, mala_state dest
)
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
)
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
);
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
)
118 mala_program_eval_arg (MalaProgram self
, int n
, mala_state final
, MalaStringList_ref node
)
120 if (self
->state
> MALA_EFAULT
)
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
]);
135 mala_state ostate
= self
->state
;
141 mala_program_run (self
, final
);
144 *node
= mala_stringlist_next (*node
);
146 nstate
= self
->state
;
147 self
->state
= ostate
;
151 ERROR (mala_program
, "Missing Argument");
152 nstate
= mala_program_commonexception (self
, MALA_STRING_ERROR_MISSING_ARGUMENT
, self
->program
);
162 mala_program_eval_arg_fmt (MalaProgram self
, int n
, const char* fmt
, void* data
, MalaStringList_ref node
)
167 state
= mala_program_eval_arg (self
, n
, MALA_LITERAL
, &nde
);
173 r
= mala_string_scan (mala_stringlist_string (nde
), fmt
, data
);
175 return mala_program_commonexception (self
, MALA_STRING_ERROR_WRONG_TYPE
, nde
);
181 mala_program_step (MalaProgram self
)
183 TODO(" handle --LITERAL");
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
;
204 // c-file-style: "gnu"
206 // arch-tag: fd8544bd-4144-44fe-8a9e-635aa0d3c393