replace_parser replaces %1 with %2 in the following program
[mala.git] / std / std_statements.c
blob58acc71311c7df1e6781dc1c4aa68304a2ccd386
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),
73 MALA_PARSER_SIMPLE("--TRY", mala_try_parser),
75 MALA_PARSER_SIMPLE("--REPLACE", mala_replace_parser),
79 MALA_PARSER("--", mala__parser, NULL, NULL, NULL),
80 MALA_PARSER_BRIEF("--", ""),
81 // MALA_PARSER_HELP("--", ("TODO")),
82 MALA_PARSER_SIGNATURE_TYPE("--", ("")),
83 MALA_PARSER_SIGNATURE_USAGE("--", ("")),
84 MALA_PARSER_RESULT_TYPE("--", ("")),
85 MALA_PARSER_RESULT_USAGE("--", ("")),
87 MALA_PARSER("--CHILDOF", mala__parser, NULL, NULL, NULL),
88 MALA_PARSER_BRIEF("--", ""),
89 // MALA_PARSER_HELP("--", ("TODO")),
90 MALA_PARSER_SIGNATURE_TYPE("--", ("")),
91 MALA_PARSER_SIGNATURE_USAGE("--", ("")),
92 MALA_PARSER_RESULT_TYPE("--", ("")),
93 MALA_PARSER_RESULT_USAGE("--", ("")),
98 //MALA_PARSER("--EXCEPTION", mala_exception_parser, NULL, NULL, NULL),
99 //MALA_PARSER_BRIEF("--EXCEPTION", "defines a new macro"),
100 // MALA_PARSER_HELP("--EXCEPTION", ("TODO")),
101 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
102 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
103 // MALA_PARSER_RESULT_TYPE("--", ("")),
104 // MALA_PARSER_RESULT_USAGE("--", ("")),
106 //TODO MALA_EXPAND_PARSER("--IFDEF", ("--IF", "--DEFINED")),
107 //MALA_PARSER_BRIEF("--IFDEF", "tests if a word is defined as macro"),
108 // MALA_PARSER_HELP("--NOT", ("TODO")),
109 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
110 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
111 // MALA_PARSER_RESULT_TYPE("--", ("")),
112 // MALA_PARSER_RESULT_USAGE("--", ("")),
114 //MALA_PARSER("--DEFINED", mala_defined_parser, NULL, NULL, NULL),
115 //MALA_PARSER_BRIEF("--DEFINED", "tests if a word is defined as macro"),
116 // MALA_PARSER_HELP("--NOT", ("TODO")),
117 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
118 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
119 // MALA_PARSER_RESULT_TYPE("--", ("")),
120 // MALA_PARSER_RESULT_USAGE("--", ("")),
122 //MALA_PARSER_BRIEF("--IF", "executes some code if a condition succeeded"),
123 // MALA_PARSER_HELP("--NOT", ("TODO")),
124 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
125 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
126 // MALA_PARSER_RESULT_TYPE("--", ("")),
127 // MALA_PARSER_RESULT_USAGE("--", ("")),
130 //MALA_PARSER("--NOT", mala_not_parser, NULL, NULL, NULL),
131 //MALA_PARSER_BRIEF("--NOT", "negates logic"),
132 // MALA_PARSER_HELP("--NOT", ("TODO")),
133 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
134 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
135 // MALA_PARSER_RESULT_TYPE("--", ("")),
136 // MALA_PARSER_RESULT_USAGE("--", ("")),
140 MALA_PARSER_SIMPLE("--SLEEP",mala_sleep_parser),
141 //MALA_PARSER_BRIEF("--SLEEP", "delays execution for some time"),
142 //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")),
143 //TODO MALA_PARSER_SIGNATURE_USAGE("--SLEEP",("Seconds to sleep")),
144 // //MALA_PARSER_RESULT_USAGE("--PRINTWRAPED", ("TODO")),
145 //MALA_PARSER_SIGNATURE_TYPE("--SLEEP", ("DURATION")),
147 //MALA_PARSER("--TRACE",mala_trace_parser, NULL, NULL, NULL),
148 //MALA_PARSER_BRIEF("--TRACE", "controls the trace mode of the MaLa VM"),
149 //MALA_PARSER_SIGNATURE_USAGE("--SLEEP",("Seconds to sleep")),
150 // //MALA_PARSER_RESULT_USAGE("--PRINTWRAPED", ("TODO")),
151 //MALA_PARSER_SIGNATURE_TYPE("--SLEEP", ("DURATION")),
153 //MALA_PARSER("--GCTRACE",mala_gctrace_parser, NULL, NULL, NULL),
154 //MALA_PARSER_BRIEF("--GCTRACE", "controls the trace mode of the MaLa garbagge collector"),
155 //MALA_PARSER_SIGNATURE_USAGE("--SLEEP",("Seconds to sleep")),
156 // //MALA_PARSER_RESULT_USAGE("--PRINTWRAPED", ("TODO")),
157 //MALA_PARSER_SIGNATURE_TYPE("--SLEEP", ("DURATION")),
159 // MALA_PARSER("--EVAL",mala_eval_parser, NULL, NULL, NULL),
160 // MALA_PARSER_BRIEF("--EVAL",""),
161 // MALA_PARSER_HELP("--EVAL",("blah")),
162 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
163 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
164 // MALA_PARSER_RESULT_TYPE("--", ("")),
165 // MALA_PARSER_RESULT_USAGE("--", ("")),
168 MALA_ACTIONS_END
172 mala_state
173 mala_literal_parser (MalaProgram prg)
175 TRACE (mala_module_std);
176 if (!mala_program_exists_arg (prg, 1))
177 return mala_program_commonexception (prg, MALA_STRING_ERROR_MISSING_ARGUMENT, mala_program_pptr (prg));
179 mala_stringlist_remove (mala_program_pptr (prg));
180 return MALA_LITERAL;
184 mala_state
185 mala_stop_parser (MalaProgram prg)
187 TRACE (mala_module_std);
189 mala_stringlist_remove (mala_program_pptr (prg));
190 return MALA_SUCCESS;
194 mala_state
195 mala_skip_parser (MalaProgram prg)
197 TRACE (mala_module_std);
199 MalaStringList node;
200 int n;
202 mala_state state = mala_program_eval_arg_fmt (prg, 1, "%d", &n, &node);
203 if (state > MALA_START)
204 return state;
205 if (n < 0)
206 return mala_program_commonexception (prg, MALA_STRING_ERROR_OUT_OF_RANGE, node);
208 MalaStringList pptr;
209 if (n)
211 pptr = (MalaStringList) llist_get_nth_stop (&prg->pptr->node, n+2,
212 &prg->program->node);
213 if (!pptr)
214 return mala_program_commonexception (prg, MALA_STRING_ERROR_MISSING_ARGUMENT, prg->program);
217 mala_program_action_done (prg, 1);
218 if (n)
219 prg->pptr = pptr;
220 return MALA_STATEMENT;
224 mala_state
225 mala_pass_parser (MalaProgram prg)
227 TRACE (mala_module_std);
228 mala_stringlist_remove (mala_program_pptr (prg));
229 return MALA_STATEMENT;
233 mala_state
234 mala_gc_parser (MalaProgram prg)
236 TRACE (mala_module_std);
237 acogc_root_collect (&prg->engine->gcroot, ACOGC_COLLECT_NORMAL);
238 mala_program_action_done (prg, 0);
239 return MALA_STATEMENT;
243 mala_state
244 mala_remove_parser (MalaProgram prg)
246 TRACE (mala_module_std);
247 mala_state state = mala_program_eval_arg (prg, 1, MALA_REMOVE, NULL);
248 if (state > MALA_START)
249 return state;
251 mala_program_action_done (prg, 0);
252 return MALA_STATEMENT;
256 mala_state
257 mala_no_parser (MalaProgram prg)
259 TRACE (mala_module_std);
260 MALA_MUTATOR_BEGIN
262 ++prg->negated;
264 MALA_MUTATOR_END;
266 mala_program_action_done (prg, 0);
267 return MALA_STATEMENT;
271 mala_state
272 mala_nono_parser (MalaProgram prg)
274 TRACE (mala_module_std);
275 MALA_MUTATOR_BEGIN
277 prg->negated = 0;
279 MALA_MUTATOR_END;
281 mala_program_action_done (prg, 0);
282 return MALA_STATEMENT;
286 mala_state
287 mala_ifelse_parser (MalaProgram prg)
289 TRACE (mala_module_std);
291 MalaStringList test;
293 mala_state state = mala_program_eval_arg (prg, 1, MALA_LITERAL, &test);
295 if (state > MALA_START)
296 return state;
298 if (state == MALA_LITERAL &&
299 mala_stringlist_string (test) == prg->engine->common_string[MALA_STRING_TRUE])
301 MalaStringList code;
303 mala_program_eval_arg (prg, 2, MALA_BLOCK, &code);
304 mala_program_eval_arg (prg, 3, MALA_REMOVE, NULL);
305 mala_stringlist_advance (code);
307 else if (state == MALA_LITERAL &&
308 mala_stringlist_string (test) == prg->engine->common_string[MALA_STRING_FALSE])
310 mala_program_eval_arg (prg, 2, MALA_REMOVE, NULL);
312 else if (prg->state == MALA_REMOVE)
314 mala_program_eval_arg (prg, 2, MALA_BLOCK, NULL);
315 mala_program_eval_arg (prg, 3, MALA_BLOCK, NULL);
317 mala_program_action_done (prg, 3);
318 return MALA_STATEMENT;
320 else
321 return mala_program_commonexception (prg, MALA_STRING_ERROR_NOT_A_PREDICATE, mala_program_pptr (prg));
323 mala_program_action_done (prg, 2);
324 return MALA_STATEMENT;
328 mala_state
329 mala_sleep_parser (MalaProgram prg)
331 double duration;
332 struct timespec req;
334 mala_state state = mala_program_eval_arg_fmt (prg, 1, "%lf", &duration, NULL);
335 if (state > MALA_START)
336 return state;
338 MALA_MUTATOR_BEGIN
340 req.tv_sec = (time_t) duration;
341 req.tv_nsec = (long) 1000000000 * (duration - ((double) req.tv_sec));
343 (void) nanosleep (&req, NULL);
345 MALA_MUTATOR_END;
347 mala_program_action_done (prg, 1);
348 return MALA_STATEMENT;
352 mala_state
353 mala_throw_parser (MalaProgram prg)
355 TRACE (mala_module_std);
356 (void) prg;
357 UNIMPLEMENTED("check this");
358 return MALA_EXCEPTION;
362 mala_state
363 mala_eval_parser (MalaProgram prg)
365 TRACE (mala_module_std);
367 mala_state state = mala_program_eval_arg (prg, 1, MALA_SUCCESS, NULL);
368 if (state > MALA_START)
369 return state;
371 mala_program_action_done (prg, 0);
372 return MALA_START;
376 mala_state
377 mala_try_parser (MalaProgram prg)
379 TRACE (mala_module_std);
381 mala_state state = mala_program_eval_arg (prg, 1, MALA_LITERAL, NULL);
382 TODO ("state >EFAULT");
384 MALA_MUTATOR_BEGIN
386 if (state == MALA_EXCEPTION)
388 ACOGC_STACK_ENTER (&prg->engine->gcroot);
389 ACOGC_STACK_PTR(MalaString, s);
390 ACOGC_STACK_PTR(MalaStringList, n);
392 REQUIRE (prg->exception);
394 MalaStringList pptr = mala_program_pptr (prg);
396 s.ptr = mala_string_new_print (prg->engine->words, "--CATCH-%s", mala_stringlist_cstr (prg->exception));
398 if (mala_string_action (s.ptr))
400 n.ptr = mala_stringlist_node_new (prg->engine->common_string[MALA_STRING_STOP], prg->engine);
401 mala_stringlist_insert_after (pptr, n.ptr);
403 n.ptr = mala_stringlist_node_new (s.ptr, prg->engine);
404 mala_stringlist_insert_after (pptr, n.ptr);
406 n.ptr = mala_stringlist_node_new (prg->engine->common_string[MALA_STRING_EVAL], prg->engine);
407 mala_stringlist_insert_after (pptr, n.ptr);
408 prg->exception = NULL;
409 state = MALA_START;
411 else
413 n.ptr = mala_stringlist_node_new (prg->engine->common_string[MALA_STRING_UNHANDLED_ERROR], prg->engine);
414 mala_stringlist_insert_after (pptr, n.ptr);
416 state = MALA_ENOACTION;
419 ACOGC_STACK_LEAVE;
422 MALA_MUTATOR_END;
424 mala_stringlist_remove (mala_program_pptr (prg));
425 return state;
429 mala_state
430 mala_replace_parser (MalaProgram prg)
432 TRACE (mala_module_std);
434 mala_state state;
435 MalaStringList search;
436 MalaStringList replace;
438 state = mala_program_eval_arg (prg, 1, MALA_LITERAL, &search);
439 if (state > MALA_START)
440 return state;
442 state = mala_program_eval_arg (prg, 2, MALA_LITERAL, &replace);
443 if (state > MALA_START)
444 return state;
446 MALA_MUTATOR_BEGIN
448 MalaStringList itr;
449 for (itr = mala_stringlist_next (replace);
450 itr != prg->program && mala_stringlist_string (itr) != mala_stringlist_string (search);
451 mala_stringlist_fwd (&itr));
453 if (itr != prg->program)
454 mala_stringlist_string_set (itr, mala_stringlist_string (replace));
456 MALA_MUTATOR_END;
458 mala_program_action_done (prg, 2);
459 return MALA_STATEMENT;
463 #if 0
465 mala_defined_parser (MalaEngine eng,
466 MalaStringListNode_ref pptr,
467 void * data)
469 MalaStringListNode result;
471 (void) data;
473 result = mala_engine_arg_eval (eng, pptr, 1, MALA_LITERAL);
474 if (!result)
475 return eng->state;
478 mala_engine_command_done (eng, pptr, 1);
480 // if (desc && 0 /*TODO mala_actiondesc_top (desc)*/)
481 // return MALA_SUCCESS;
482 //else
483 return MALA_FAILURE;
488 mala_trace_parser (MalaEngine eng,
489 MalaStringListNode_ref pptr,
490 void * data)
492 (void) data;
494 /*TODO trace levels*/
495 MALA_SIDEEFFECT_BEGIN
496 eng->engine_trace = eng->negated ? MALA_NOTRACE:MALA_TRACE;
497 MALA_SIDEEFFECT_END;
499 mala_engine_command_done (eng, pptr, 0);
500 return MALA_CONTINUE;
503 #if 0
505 mala_gctrace_parser (MalaEngine eng,
506 MalaStringListNode_ref pptr,
507 void * data)
509 (void) data;
511 /*TODO trace levels*/
512 MALA_SIDEEFFECT_BEGIN
513 *eng->gc_trace = eng->negated ? MALA_NOTRACE:MALA_TRACE;
514 MALA_SIDEEFFECT_END;
516 mala_engine_command_done (eng, pptr, 0);
517 return MALA_CONTINUE;
519 #endif
521 /*TODO to predicates*/
522 static int
523 mala_predicate_greaterorequal_double (double * a, double * b)
525 return *a >= *b;
530 mala_not_parser (MalaEngine eng,
531 MalaStringListNode_ref pptr,
532 void * data)
534 MalaStringListNode result;
536 (void) data;
538 MALA_SIDEEFFECT_BEGIN
539 eng->negated = !eng->negated;
540 MALA_SIDEEFFECT_END;
542 result = mala_engine_arg_eval (eng, pptr, 1, MALA_LITERAL);
543 if (!result)
544 return eng->state;
546 mala_engine_command_done (eng, pptr, 1);
547 return eng->state;
551 mala_exception_parser (MalaEngine eng,
552 MalaStringListNode_ref pptr,
553 void * data)
555 // TODO needs better semantics --EXCEPTION n error -> --ERROR-error 1 .. n --HERE
557 (void) data;
559 mala_engine_arg_eval (eng, pptr, 1, MALA_LITERAL);
561 //TODO MALA_SIDEEFFECT_BEGIN
562 // {
563 #if 0 // TODO --PROGRAM
564 if (mala_stringlist_is_tail (&eng->program, *pptr))
565 return mala_engine_exception (eng, pptr, *pptr,
566 eng->common_string[MALA_STRING_ERROR_MISSING_ARGUMENT]);
567 #endif
568 if (eng->state > MALA_EFAULT)
569 return eng->state;
571 MalaString ex = mala_string_new_print (&eng->words, NULL, //TODO refs
572 "--ERROR-%s",
573 mala_stringlistnode_cstr (mala_stringlistnode_next (*pptr)));
575 // TODO mala_stringlist_elem_delete_fwd (&eng->program, pptr);
576 int state = mala_engine_exception (eng, pptr, *pptr, ex);
577 // TODO mala_stringlist_elem_delete (&eng->program, mala_stringlistnode_next (*pptr));
579 // TODO review mala_string_free (ex);
580 // MALA_SIDEEFFECT_END;
582 return state;
585 #if 0
587 mala_foreach_word_parser (MalaEngine eng,
588 MalaStringListNode_ref pptr,
589 void * data)
591 MalaAction act;
592 MalaStringListNode first;
593 MalaStringListNode second;
594 MalaStringListNode last;
595 MalaStringListNode itr;
596 (void) data;
598 /*TODO bugs, rename to --APPLY fixit etc*/
600 first = mala_engine_arg_eval (eng, pptr, 1, -1, NULL, NULL);
601 if (!first)
602 return eng->state;
603 act = mala_actiondesc_top ((MalaActionDesc) mala_stringlistnode_user_get (first));
604 // TODO allow blocks as first arg (define macro and delete it at later)
605 if (act && act->parser == mala_block_parser)
606 return mala_engine_exception (eng, pptr, first,
607 eng->common_string[MALA_STRING_ERROR_BLOCK_NOT_ALLOWED]);
609 second = mala_engine_arg_eval (eng, pptr, 2, -1, (MalaDataFactory) mala_stringlist_factory, NULL);
610 if (!second)
611 return eng->state;
613 last = mala_stringlistnode_next (second);
615 act = mala_actiondesc_top ((MalaActionDesc) mala_stringlistnode_user_get (second));
617 // expand second
618 if (eng->state != MALA_LITERAL)
619 for (itr = mala_stringlist_tail ((MalaStringList) act->data);
620 !mala_stringlist_is_end ((MalaStringList) act->data, itr);
621 mala_stringlistnode_rev (&itr))
623 #if 0 // TODO --PROGRAM
624 if (!mala_stringlist_after_new (&eng->program,
625 second,
626 mala_stringlistnode_string (itr)))
627 goto ealloc_node;
628 if (!mala_stringlist_after_new (&eng->program,
629 second,
630 mala_stringlistnode_string (first)))
631 goto ealloc_node;
632 #endif
634 else
636 #if 0
637 if (!mala_stringlist_after_new (&eng->program,
638 second,
639 mala_stringlistnode_string (second)))
640 goto ealloc_node;
641 if (!mala_stringlist_after_new (&eng->program,
642 second,
643 mala_stringlistnode_string (first)))
644 goto ealloc_node;
645 #endif
649 // was a block? delete it
650 if (act && act->parser == mala_block_parser)
651 mala_actiondesc_pop_delete (mala_stringlistnode_user_get (second));
653 mala_engine_command_done (eng, pptr, 2);
654 return MALA_SUCCESS;
656 ealloc_node:
657 for (itr = mala_stringlistnode_next (second);
658 itr != last;
659 mala_stringlistnode_fwd (&itr))
661 // mala_stringlist_elem_delete (&eng->program, itr);
664 return MALA_EALLOC; // TODO exception instead (needs pools, no allocation possible further)
671 realloc a string to at least needed size
672 return the amount really reserved or 0 on error
674 static size_t
675 reserve_string (char ** s, size_t actual, size_t needed)
677 size_t n;
678 char * r;
680 for (n = actual>64?actual:64; n <= needed; n += (n>>1)); /*n = n * 1.5*/
682 r = realloc (*s, n);
683 if (!r)
685 /* that was to much, try conservatively */
686 r = realloc (*s, n = needed);
687 if (!r)
688 return 0;
690 *s = r;
691 return n;
693 #endif
696 #endif
700 mala_module_std_statements_init (MalaEngine self)
702 return mala_engine_actions_register (self, std_statements);
706 // Local Variables:
707 // mode: C
708 // c-file-style: "gnu"
709 // End:
710 // arch-tag: 7e2dc784-1527-458a-8881-e87d3fb22cef
711 // end_of_file