eval_parser evaluates the following programm fully (until --STOP) but returns MALA_ST...
[mala.git] / std / std_statements.c
blobb0e130f9f50f55088333a261e758041e37f9af14
1 /*
2 std_statements.c - MaLa statement like parsers
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 <stdio.h>
21 #include <string.h>
22 #include <time.h>
24 #include "mala.h"
25 #include "std_statements.h"
28 static
29 mala_actioninit std_statements[] =
31 MALA_PARSER_SIMPLE("--LITERAL", mala_literal_parser),
32 //MALA_PARSER_BRIEF("--LITERAL", "Treats the next word literally"),
33 // MALA_PARSER_HELP("--LITERAL", ("TODO")),
34 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
35 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
36 // MALA_PARSER_RESULT_TYPE("--", ("")),
37 // MALA_PARSER_RESULT_USAGE("--", ("")),
40 MALA_PARSER_SIMPLE("--SKIP", mala_skip_parser),
41 //MALA_PARSER_BRIEF("--SKIP", "Treats the next n words literally"),
42 // MALA_PARSER_HELP("--LITERAL", ("TODO")),
43 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
44 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
45 // MALA_PARSER_RESULT_TYPE("--", ("")),
46 // MALA_PARSER_RESULT_USAGE("--", ("")),
49 MALA_PARSER_SIMPLE("--PASS", mala_pass_parser),
50 //MALA_PARSER_BRIEF("--PASS","does nothing"),
51 //TODO MALA_PARSER_HELP("--PASS",("--HELP-ACTION","blah")),
52 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
53 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
54 // MALA_PARSER_RESULT_TYPE("--", ("")),
55 // MALA_PARSER_RESULT_USAGE("--", ("")),
57 MALA_PARSER_SIMPLE("--GC", mala_gc_parser),
59 MALA_PARSER_SIMPLE("--REMOVE", mala_remove_parser),
61 MALA_PARSER_SIMPLE("--NO", mala_no_parser),
63 MALA_PARSER_SIMPLE("--NONO", mala_nono_parser),
65 MALA_PARSER_SIMPLE("--IF-ELSE", mala_ifelse_parser),
67 MALA_PARSER_MACRO("--IF", ("--IF-ELSE", "%1", "%2", "--BEGIN", "--PASS", "--END")),
69 MALA_PARSER_SIMPLE("--STOP", mala_stop_parser),
71 MALA_PARSER_SIMPLE("--EVAL", mala_eval_parser),
75 MALA_PARSER("--", mala__parser, NULL, NULL, NULL),
76 MALA_PARSER_BRIEF("--", ""),
77 // MALA_PARSER_HELP("--", ("TODO")),
78 MALA_PARSER_SIGNATURE_TYPE("--", ("")),
79 MALA_PARSER_SIGNATURE_USAGE("--", ("")),
80 MALA_PARSER_RESULT_TYPE("--", ("")),
81 MALA_PARSER_RESULT_USAGE("--", ("")),
83 MALA_PARSER("--CHILDOF", mala__parser, NULL, NULL, NULL),
84 MALA_PARSER_BRIEF("--", ""),
85 // MALA_PARSER_HELP("--", ("TODO")),
86 MALA_PARSER_SIGNATURE_TYPE("--", ("")),
87 MALA_PARSER_SIGNATURE_USAGE("--", ("")),
88 MALA_PARSER_RESULT_TYPE("--", ("")),
89 MALA_PARSER_RESULT_USAGE("--", ("")),
94 //MALA_PARSER("--EXCEPTION", mala_exception_parser, NULL, NULL, NULL),
95 //MALA_PARSER_BRIEF("--EXCEPTION", "defines a new macro"),
96 // MALA_PARSER_HELP("--EXCEPTION", ("TODO")),
97 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
98 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
99 // MALA_PARSER_RESULT_TYPE("--", ("")),
100 // MALA_PARSER_RESULT_USAGE("--", ("")),
102 //TODO MALA_EXPAND_PARSER("--IFDEF", ("--IF", "--DEFINED")),
103 //MALA_PARSER_BRIEF("--IFDEF", "tests if a word is defined as macro"),
104 // MALA_PARSER_HELP("--NOT", ("TODO")),
105 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
106 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
107 // MALA_PARSER_RESULT_TYPE("--", ("")),
108 // MALA_PARSER_RESULT_USAGE("--", ("")),
110 //MALA_PARSER("--DEFINED", mala_defined_parser, NULL, NULL, NULL),
111 //MALA_PARSER_BRIEF("--DEFINED", "tests if a word is defined as macro"),
112 // MALA_PARSER_HELP("--NOT", ("TODO")),
113 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
114 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
115 // MALA_PARSER_RESULT_TYPE("--", ("")),
116 // MALA_PARSER_RESULT_USAGE("--", ("")),
118 //MALA_PARSER_BRIEF("--IF", "executes some code if a condition succeeded"),
119 // MALA_PARSER_HELP("--NOT", ("TODO")),
120 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
121 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
122 // MALA_PARSER_RESULT_TYPE("--", ("")),
123 // MALA_PARSER_RESULT_USAGE("--", ("")),
126 //MALA_PARSER("--NOT", mala_not_parser, NULL, NULL, NULL),
127 //MALA_PARSER_BRIEF("--NOT", "negates logic"),
128 // MALA_PARSER_HELP("--NOT", ("TODO")),
129 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
130 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
131 // MALA_PARSER_RESULT_TYPE("--", ("")),
132 // MALA_PARSER_RESULT_USAGE("--", ("")),
136 MALA_PARSER_SIMPLE("--SLEEP",mala_sleep_parser),
137 //MALA_PARSER_BRIEF("--SLEEP", "delays execution for some time"),
138 //TODO MALA_PARSER_HELP("--SLEEP", ("The program will be suspended for some time, the time might be specified as fraction of seconds\t example: 9.5")),
139 //TODO MALA_PARSER_SIGNATURE_USAGE("--SLEEP",("Seconds to sleep")),
140 // //MALA_PARSER_RESULT_USAGE("--PRINTWRAPED", ("TODO")),
141 //MALA_PARSER_SIGNATURE_TYPE("--SLEEP", ("DURATION")),
143 //MALA_PARSER("--TRACE",mala_trace_parser, NULL, NULL, NULL),
144 //MALA_PARSER_BRIEF("--TRACE", "controls the trace mode of the MaLa VM"),
145 //MALA_PARSER_SIGNATURE_USAGE("--SLEEP",("Seconds to sleep")),
146 // //MALA_PARSER_RESULT_USAGE("--PRINTWRAPED", ("TODO")),
147 //MALA_PARSER_SIGNATURE_TYPE("--SLEEP", ("DURATION")),
149 //MALA_PARSER("--GCTRACE",mala_gctrace_parser, NULL, NULL, NULL),
150 //MALA_PARSER_BRIEF("--GCTRACE", "controls the trace mode of the MaLa garbagge collector"),
151 //MALA_PARSER_SIGNATURE_USAGE("--SLEEP",("Seconds to sleep")),
152 // //MALA_PARSER_RESULT_USAGE("--PRINTWRAPED", ("TODO")),
153 //MALA_PARSER_SIGNATURE_TYPE("--SLEEP", ("DURATION")),
155 // MALA_PARSER("--EVAL",mala_eval_parser, NULL, NULL, NULL),
156 // MALA_PARSER_BRIEF("--EVAL",""),
157 // MALA_PARSER_HELP("--EVAL",("blah")),
158 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
159 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
160 // MALA_PARSER_RESULT_TYPE("--", ("")),
161 // MALA_PARSER_RESULT_USAGE("--", ("")),
164 MALA_ACTIONS_END
168 mala_state
169 mala_literal_parser (MalaProgram prg)
171 TRACE (mala_module_std);
172 if (!mala_program_exists_arg (prg, 1))
173 return mala_program_commonexception (prg, MALA_STRING_ERROR_MISSING_ARGUMENT);
175 mala_stringlist_remove (mala_stringlist_next (prg->pptr));
176 return MALA_LITERAL;
180 mala_state
181 mala_stop_parser (MalaProgram prg)
183 TRACE (mala_module_std);
185 mala_stringlist_remove (mala_stringlist_next (prg->pptr));
186 return MALA_SUCCESS;
190 mala_state
191 mala_skip_parser (MalaProgram prg)
193 TRACE (mala_module_std);
195 int n;
197 if (mala_program_eval_arg_fmt (prg, 1, "%d", &n) > MALA_EFAULT)
198 return mala_program_commonexception (prg, MALA_STRING_ERROR);
199 if (n < 0)
200 return mala_program_commonexception (prg, MALA_STRING_ERROR_OUT_OF_RANGE);
202 MalaStringList pptr;
203 if (n)
205 pptr = (MalaStringList) llist_get_nth_stop (&prg->pptr->node, n+2,
206 &prg->program->node);
207 if (!pptr)
208 return mala_program_commonexception (prg, MALA_STRING_ERROR_MISSING_ARGUMENT);
211 mala_program_action_done (prg, 1);
212 if (n)
213 prg->pptr = pptr;
214 return MALA_STATEMENT;
218 mala_state
219 mala_pass_parser (MalaProgram prg)
221 TRACE (mala_module_std);
222 mala_stringlist_remove (mala_stringlist_next (prg->pptr));
223 return MALA_STATEMENT;
227 mala_state
228 mala_gc_parser (MalaProgram prg)
230 TRACE (mala_module_std);
231 acogc_root_collect (&prg->engine->gcroot, ACOGC_COLLECT_NORMAL);
232 mala_program_action_done (prg, 0);
233 return MALA_STATEMENT;
237 mala_state
238 mala_remove_parser (MalaProgram prg)
240 TRACE (mala_module_std);
241 if (mala_program_eval_arg (prg, 1, MALA_REMOVE, NULL) > MALA_EFAULT)
242 return mala_program_commonexception (prg, MALA_STRING_ERROR);
244 mala_program_action_done (prg, 0);
245 return MALA_STATEMENT;
249 mala_state
250 mala_no_parser (MalaProgram prg)
252 TRACE (mala_module_std);
253 MALA_MUTATOR_BEGIN
255 ++prg->negated;
257 MALA_MUTATOR_END;
259 mala_program_action_done (prg, 0);
260 return MALA_STATEMENT;
264 mala_state
265 mala_nono_parser (MalaProgram prg)
267 TRACE (mala_module_std);
268 MALA_MUTATOR_BEGIN
270 prg->negated = 0;
272 MALA_MUTATOR_END;
274 mala_program_action_done (prg, 0);
275 return MALA_STATEMENT;
279 mala_state
280 mala_ifelse_parser (MalaProgram prg)
282 TRACE (mala_module_std);
284 MalaStringList test;
286 mala_state state = mala_program_eval_arg (prg, 1, MALA_LITERAL, &test);
288 if (state > MALA_EFAULT)
289 return mala_program_commonexception (prg, MALA_STRING_ERROR);
291 if (state == MALA_LITERAL &&
292 mala_stringlist_string (test) == prg->engine->common_string[MALA_STRING_TRUE])
294 MalaStringList code;
296 mala_program_eval_arg (prg, 2, MALA_BLOCK, &code);
297 mala_program_eval_arg (prg, 3, MALA_REMOVE, NULL);
298 mala_stringlist_advance (code);
300 else if (state == MALA_LITERAL &&
301 mala_stringlist_string (test) == prg->engine->common_string[MALA_STRING_FALSE])
303 mala_program_eval_arg (prg, 2, MALA_REMOVE, NULL);
305 else if (prg->state == MALA_REMOVE)
307 mala_program_eval_arg (prg, 2, MALA_BLOCK, NULL);
308 mala_program_eval_arg (prg, 3, MALA_BLOCK, NULL);
310 mala_program_action_done (prg, 3);
311 return MALA_STATEMENT;
313 else
314 return mala_program_commonexception (prg, MALA_STRING_ERROR_NOT_A_PREDICATE);
316 mala_program_action_done (prg, 2);
317 return MALA_STATEMENT;
321 mala_state
322 mala_sleep_parser (MalaProgram prg)
324 double duration;
325 struct timespec req;
327 if (mala_program_eval_arg_fmt (prg, 1, "%lf", &duration) > MALA_EFAULT)
328 return mala_program_commonexception (prg, MALA_STRING_ERROR);
330 MALA_MUTATOR_BEGIN
332 req.tv_sec = (time_t) duration;
333 req.tv_nsec = (long) 1000000000 * (duration - ((double) req.tv_sec));
335 (void) nanosleep (&req, NULL);
337 MALA_MUTATOR_END;
339 mala_program_action_done (prg, 1);
340 return MALA_STATEMENT;
343 mala_state
344 mala_eval_parser (MalaProgram prg)
346 TRACE (mala_module_std);
347 if (mala_program_eval_arg (prg, 1, MALA_SUCCESS, NULL) > MALA_EFAULT)
348 return mala_program_commonexception (prg, MALA_STRING_ERROR);
350 mala_program_action_done (prg, 0);
351 return MALA_START;
356 #if 0
358 mala_defined_parser (MalaEngine eng,
359 MalaStringListNode_ref pptr,
360 void * data)
362 MalaStringListNode result;
364 (void) data;
366 result = mala_engine_arg_eval (eng, pptr, 1, MALA_LITERAL);
367 if (!result)
368 return eng->state;
371 mala_engine_command_done (eng, pptr, 1);
373 // if (desc && 0 /*TODO mala_actiondesc_top (desc)*/)
374 // return MALA_SUCCESS;
375 //else
376 return MALA_FAILURE;
381 mala_trace_parser (MalaEngine eng,
382 MalaStringListNode_ref pptr,
383 void * data)
385 (void) data;
387 /*TODO trace levels*/
388 MALA_SIDEEFFECT_BEGIN
389 eng->engine_trace = eng->negated ? MALA_NOTRACE:MALA_TRACE;
390 MALA_SIDEEFFECT_END;
392 mala_engine_command_done (eng, pptr, 0);
393 return MALA_CONTINUE;
396 #if 0
398 mala_gctrace_parser (MalaEngine eng,
399 MalaStringListNode_ref pptr,
400 void * data)
402 (void) data;
404 /*TODO trace levels*/
405 MALA_SIDEEFFECT_BEGIN
406 *eng->gc_trace = eng->negated ? MALA_NOTRACE:MALA_TRACE;
407 MALA_SIDEEFFECT_END;
409 mala_engine_command_done (eng, pptr, 0);
410 return MALA_CONTINUE;
412 #endif
414 /*TODO to predicates*/
415 static int
416 mala_predicate_greaterorequal_double (double * a, double * b)
418 return *a >= *b;
423 mala_not_parser (MalaEngine eng,
424 MalaStringListNode_ref pptr,
425 void * data)
427 MalaStringListNode result;
429 (void) data;
431 MALA_SIDEEFFECT_BEGIN
432 eng->negated = !eng->negated;
433 MALA_SIDEEFFECT_END;
435 result = mala_engine_arg_eval (eng, pptr, 1, MALA_LITERAL);
436 if (!result)
437 return eng->state;
439 mala_engine_command_done (eng, pptr, 1);
440 return eng->state;
444 mala_exception_parser (MalaEngine eng,
445 MalaStringListNode_ref pptr,
446 void * data)
448 // TODO needs better semantics --EXCEPTION n error -> --ERROR-error 1 .. n --HERE
450 (void) data;
452 mala_engine_arg_eval (eng, pptr, 1, MALA_LITERAL);
454 //TODO MALA_SIDEEFFECT_BEGIN
455 // {
456 #if 0 // TODO --PROGRAM
457 if (mala_stringlist_is_tail (&eng->program, *pptr))
458 return mala_engine_exception (eng, pptr, *pptr,
459 eng->common_string[MALA_STRING_ERROR_MISSING_ARGUMENT]);
460 #endif
461 if (eng->state > MALA_EFAULT)
462 return eng->state;
464 MalaString ex = mala_string_new_print (&eng->words, NULL, //TODO refs
465 "--ERROR-%s",
466 mala_stringlistnode_cstr (mala_stringlistnode_next (*pptr)));
468 // TODO mala_stringlist_elem_delete_fwd (&eng->program, pptr);
469 int state = mala_engine_exception (eng, pptr, *pptr, ex);
470 // TODO mala_stringlist_elem_delete (&eng->program, mala_stringlistnode_next (*pptr));
472 // TODO review mala_string_free (ex);
473 // MALA_SIDEEFFECT_END;
475 return state;
478 #if 0
480 mala_foreach_word_parser (MalaEngine eng,
481 MalaStringListNode_ref pptr,
482 void * data)
484 MalaAction act;
485 MalaStringListNode first;
486 MalaStringListNode second;
487 MalaStringListNode last;
488 MalaStringListNode itr;
489 (void) data;
491 /*TODO bugs, rename to --APPLY fixit etc*/
493 first = mala_engine_arg_eval (eng, pptr, 1, -1, NULL, NULL);
494 if (!first)
495 return eng->state;
496 act = mala_actiondesc_top ((MalaActionDesc) mala_stringlistnode_user_get (first));
497 // TODO allow blocks as first arg (define macro and delete it at later)
498 if (act && act->parser == mala_block_parser)
499 return mala_engine_exception (eng, pptr, first,
500 eng->common_string[MALA_STRING_ERROR_BLOCK_NOT_ALLOWED]);
502 second = mala_engine_arg_eval (eng, pptr, 2, -1, (MalaDataFactory) mala_stringlist_factory, NULL);
503 if (!second)
504 return eng->state;
506 last = mala_stringlistnode_next (second);
508 act = mala_actiondesc_top ((MalaActionDesc) mala_stringlistnode_user_get (second));
510 // expand second
511 if (eng->state != MALA_LITERAL)
512 for (itr = mala_stringlist_tail ((MalaStringList) act->data);
513 !mala_stringlist_is_end ((MalaStringList) act->data, itr);
514 mala_stringlistnode_rev (&itr))
516 #if 0 // TODO --PROGRAM
517 if (!mala_stringlist_after_new (&eng->program,
518 second,
519 mala_stringlistnode_string (itr)))
520 goto ealloc_node;
521 if (!mala_stringlist_after_new (&eng->program,
522 second,
523 mala_stringlistnode_string (first)))
524 goto ealloc_node;
525 #endif
527 else
529 #if 0
530 if (!mala_stringlist_after_new (&eng->program,
531 second,
532 mala_stringlistnode_string (second)))
533 goto ealloc_node;
534 if (!mala_stringlist_after_new (&eng->program,
535 second,
536 mala_stringlistnode_string (first)))
537 goto ealloc_node;
538 #endif
542 // was a block? delete it
543 if (act && act->parser == mala_block_parser)
544 mala_actiondesc_pop_delete (mala_stringlistnode_user_get (second));
546 mala_engine_command_done (eng, pptr, 2);
547 return MALA_SUCCESS;
549 ealloc_node:
550 for (itr = mala_stringlistnode_next (second);
551 itr != last;
552 mala_stringlistnode_fwd (&itr))
554 // mala_stringlist_elem_delete (&eng->program, itr);
557 return MALA_EALLOC; // TODO exception instead (needs pools, no allocation possible further)
564 realloc a string to at least needed size
565 return the amount really reserved or 0 on error
567 static size_t
568 reserve_string (char ** s, size_t actual, size_t needed)
570 size_t n;
571 char * r;
573 for (n = actual>64?actual:64; n <= needed; n += (n>>1)); /*n = n * 1.5*/
575 r = realloc (*s, n);
576 if (!r)
578 /* that was to much, try conservatively */
579 r = realloc (*s, n = needed);
580 if (!r)
581 return 0;
583 *s = r;
584 return n;
586 #endif
589 #endif
593 mala_module_std_statements_init (MalaEngine self)
595 return mala_engine_actions_register (self, std_statements);
599 // Local Variables:
600 // mode: C
601 // c-file-style: "gnu"
602 // End:
603 // arch-tag: 7e2dc784-1527-458a-8881-e87d3fb22cef
604 // end_of_file