new test program, part 1
[mala.git] / std / std_statements.c
blobf6dab929ad0581ade880fdec8a20683518091542
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("--", mala__parser, NULL, NULL, NULL),
72 MALA_PARSER_BRIEF("--", ""),
73 // MALA_PARSER_HELP("--", ("TODO")),
74 MALA_PARSER_SIGNATURE_TYPE("--", ("")),
75 MALA_PARSER_SIGNATURE_USAGE("--", ("")),
76 MALA_PARSER_RESULT_TYPE("--", ("")),
77 MALA_PARSER_RESULT_USAGE("--", ("")),
79 MALA_PARSER("--CHILDOF", 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("--", ("")),
90 //MALA_PARSER("--EXCEPTION", mala_exception_parser, NULL, NULL, NULL),
91 //MALA_PARSER_BRIEF("--EXCEPTION", "defines a new macro"),
92 // MALA_PARSER_HELP("--EXCEPTION", ("TODO")),
93 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
94 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
95 // MALA_PARSER_RESULT_TYPE("--", ("")),
96 // MALA_PARSER_RESULT_USAGE("--", ("")),
98 //TODO MALA_EXPAND_PARSER("--IFDEF", ("--IF", "--DEFINED")),
99 //MALA_PARSER_BRIEF("--IFDEF", "tests if a word is defined as macro"),
100 // MALA_PARSER_HELP("--NOT", ("TODO")),
101 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
102 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
103 // MALA_PARSER_RESULT_TYPE("--", ("")),
104 // MALA_PARSER_RESULT_USAGE("--", ("")),
106 //MALA_PARSER("--DEFINED", mala_defined_parser, NULL, NULL, NULL),
107 //MALA_PARSER_BRIEF("--DEFINED", "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_BRIEF("--IF", "executes some code if a condition succeeded"),
115 // MALA_PARSER_HELP("--NOT", ("TODO")),
116 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
117 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
118 // MALA_PARSER_RESULT_TYPE("--", ("")),
119 // MALA_PARSER_RESULT_USAGE("--", ("")),
122 //MALA_PARSER("--NOT", mala_not_parser, NULL, NULL, NULL),
123 //MALA_PARSER_BRIEF("--NOT", "negates logic"),
124 // MALA_PARSER_HELP("--NOT", ("TODO")),
125 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
126 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
127 // MALA_PARSER_RESULT_TYPE("--", ("")),
128 // MALA_PARSER_RESULT_USAGE("--", ("")),
132 MALA_PARSER_SIMPLE("--SLEEP",mala_sleep_parser),
133 //MALA_PARSER_BRIEF("--SLEEP", "delays execution for some time"),
134 //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")),
135 //TODO MALA_PARSER_SIGNATURE_USAGE("--SLEEP",("Seconds to sleep")),
136 // //MALA_PARSER_RESULT_USAGE("--PRINTWRAPED", ("TODO")),
137 //MALA_PARSER_SIGNATURE_TYPE("--SLEEP", ("DURATION")),
139 //MALA_PARSER("--TRACE",mala_trace_parser, NULL, NULL, NULL),
140 //MALA_PARSER_BRIEF("--TRACE", "controls the trace mode of the MaLa VM"),
141 //MALA_PARSER_SIGNATURE_USAGE("--SLEEP",("Seconds to sleep")),
142 // //MALA_PARSER_RESULT_USAGE("--PRINTWRAPED", ("TODO")),
143 //MALA_PARSER_SIGNATURE_TYPE("--SLEEP", ("DURATION")),
145 //MALA_PARSER("--GCTRACE",mala_gctrace_parser, NULL, NULL, NULL),
146 //MALA_PARSER_BRIEF("--GCTRACE", "controls the trace mode of the MaLa garbagge collector"),
147 //MALA_PARSER_SIGNATURE_USAGE("--SLEEP",("Seconds to sleep")),
148 // //MALA_PARSER_RESULT_USAGE("--PRINTWRAPED", ("TODO")),
149 //MALA_PARSER_SIGNATURE_TYPE("--SLEEP", ("DURATION")),
151 // MALA_PARSER("--EVAL",mala_eval_parser, NULL, NULL, NULL),
152 // MALA_PARSER_BRIEF("--EVAL",""),
153 // MALA_PARSER_HELP("--EVAL",("blah")),
154 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
155 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
156 // MALA_PARSER_RESULT_TYPE("--", ("")),
157 // MALA_PARSER_RESULT_USAGE("--", ("")),
160 MALA_ACTIONS_END
164 mala_state
165 mala_literal_parser (MalaProgram prg)
167 TRACE (mala_module_std);
168 if (!mala_program_exists_arg (prg, 1))
169 return mala_program_commonexception (prg, MALA_STRING_ERROR_MISSING_ARGUMENT);
171 mala_stringlist_remove (mala_stringlist_next (prg->pptr));
172 return MALA_LITERAL;
176 mala_state
177 mala_stop_parser (MalaProgram prg)
179 TRACE (mala_module_std);
181 mala_stringlist_remove (mala_stringlist_next (prg->pptr));
182 return MALA_SUCCESS;
186 mala_state
187 mala_skip_parser (MalaProgram prg)
189 TRACE (mala_module_std);
191 int n;
193 if (mala_program_eval_arg_fmt (prg, 1, "%d", &n) > MALA_EFAULT)
194 return mala_program_commonexception (prg, MALA_STRING_ERROR);
195 if (n < 0)
196 return mala_program_commonexception (prg, MALA_STRING_ERROR_OUT_OF_RANGE);
198 MalaStringList pptr;
199 if (n)
201 pptr = (MalaStringList) llist_get_nth_stop (&prg->pptr->node, n+2,
202 &prg->program->node);
203 if (!pptr)
204 return mala_program_commonexception (prg, MALA_STRING_ERROR_MISSING_ARGUMENT);
207 mala_program_action_done (prg, 1);
208 if (n)
209 prg->pptr = pptr;
210 return MALA_STATEMENT;
214 mala_state
215 mala_pass_parser (MalaProgram prg)
217 TRACE (mala_module_std);
218 mala_stringlist_remove (mala_stringlist_next (prg->pptr));
219 return MALA_STATEMENT;
223 mala_state
224 mala_gc_parser (MalaProgram prg)
226 TRACE (mala_module_std);
227 acogc_root_collect (&prg->engine->gcroot, ACOGC_COLLECT_NORMAL);
228 mala_program_action_done (prg, 0);
229 return MALA_STATEMENT;
233 mala_state
234 mala_remove_parser (MalaProgram prg)
236 TRACE (mala_module_std);
237 if (mala_program_eval_arg (prg, 1, MALA_REMOVE, NULL) > MALA_EFAULT)
238 return mala_program_commonexception (prg, MALA_STRING_ERROR);
240 mala_program_action_done (prg, 0);
241 return MALA_STATEMENT;
245 mala_state
246 mala_no_parser (MalaProgram prg)
248 TRACE (mala_module_std);
249 MALA_MUTATOR_BEGIN
251 ++prg->negated;
253 MALA_MUTATOR_END;
255 mala_program_action_done (prg, 0);
256 return MALA_STATEMENT;
260 mala_state
261 mala_nono_parser (MalaProgram prg)
263 TRACE (mala_module_std);
264 MALA_MUTATOR_BEGIN
266 prg->negated = 0;
268 MALA_MUTATOR_END;
270 mala_program_action_done (prg, 0);
271 return MALA_STATEMENT;
275 mala_state
276 mala_ifelse_parser (MalaProgram prg)
278 TRACE (mala_module_std);
280 MalaStringList test;
282 mala_state state = mala_program_eval_arg (prg, 1, MALA_LITERAL, &test);
284 if (state > MALA_EFAULT)
285 return mala_program_commonexception (prg, MALA_STRING_ERROR);
287 if (state == MALA_LITERAL &&
288 mala_stringlist_string (test) == prg->engine->common_string[MALA_STRING_TRUE])
290 MalaStringList code;
292 mala_program_eval_arg (prg, 2, MALA_BLOCK, &code);
293 mala_program_eval_arg (prg, 3, MALA_REMOVE, NULL);
294 mala_stringlist_advance (code);
296 else if (state == MALA_LITERAL &&
297 mala_stringlist_string (test) == prg->engine->common_string[MALA_STRING_FALSE])
299 mala_program_eval_arg (prg, 2, MALA_REMOVE, NULL);
301 else if (prg->state == MALA_REMOVE)
303 mala_program_eval_arg (prg, 2, MALA_BLOCK, NULL);
304 mala_program_eval_arg (prg, 3, MALA_BLOCK, NULL);
306 mala_program_action_done (prg, 3);
307 return MALA_STATEMENT;
309 else
310 return mala_program_commonexception (prg, MALA_STRING_ERROR_NOT_A_PREDICATE);
312 mala_program_action_done (prg, 2);
313 return MALA_STATEMENT;
317 mala_state
318 mala_sleep_parser (MalaProgram prg)
320 double duration;
321 struct timespec req;
323 if (mala_program_eval_arg_fmt (prg, 1, "%lf", &duration) > MALA_EFAULT)
324 return mala_program_commonexception (prg, MALA_STRING_ERROR);
326 MALA_MUTATOR_BEGIN
328 req.tv_sec = (time_t) duration;
329 req.tv_nsec = (long) 1000000000 * (duration - ((double) req.tv_sec));
331 (void) nanosleep (&req, NULL);
333 MALA_MUTATOR_END;
335 mala_program_action_done (prg, 1);
336 return MALA_STATEMENT;
339 #if 0
341 mala_defined_parser (MalaEngine eng,
342 MalaStringListNode_ref pptr,
343 void * data)
345 MalaStringListNode result;
347 (void) data;
349 result = mala_engine_arg_eval (eng, pptr, 1, MALA_LITERAL);
350 if (!result)
351 return eng->state;
354 mala_engine_command_done (eng, pptr, 1);
356 // if (desc && 0 /*TODO mala_actiondesc_top (desc)*/)
357 // return MALA_SUCCESS;
358 //else
359 return MALA_FAILURE;
364 mala_trace_parser (MalaEngine eng,
365 MalaStringListNode_ref pptr,
366 void * data)
368 (void) data;
370 /*TODO trace levels*/
371 MALA_SIDEEFFECT_BEGIN
372 eng->engine_trace = eng->negated ? MALA_NOTRACE:MALA_TRACE;
373 MALA_SIDEEFFECT_END;
375 mala_engine_command_done (eng, pptr, 0);
376 return MALA_CONTINUE;
379 #if 0
381 mala_gctrace_parser (MalaEngine eng,
382 MalaStringListNode_ref pptr,
383 void * data)
385 (void) data;
387 /*TODO trace levels*/
388 MALA_SIDEEFFECT_BEGIN
389 *eng->gc_trace = eng->negated ? MALA_NOTRACE:MALA_TRACE;
390 MALA_SIDEEFFECT_END;
392 mala_engine_command_done (eng, pptr, 0);
393 return MALA_CONTINUE;
395 #endif
397 /*TODO to predicates*/
398 static int
399 mala_predicate_greaterorequal_double (double * a, double * b)
401 return *a >= *b;
406 mala_not_parser (MalaEngine eng,
407 MalaStringListNode_ref pptr,
408 void * data)
410 MalaStringListNode result;
412 (void) data;
414 MALA_SIDEEFFECT_BEGIN
415 eng->negated = !eng->negated;
416 MALA_SIDEEFFECT_END;
418 result = mala_engine_arg_eval (eng, pptr, 1, MALA_LITERAL);
419 if (!result)
420 return eng->state;
422 mala_engine_command_done (eng, pptr, 1);
423 return eng->state;
427 mala_exception_parser (MalaEngine eng,
428 MalaStringListNode_ref pptr,
429 void * data)
431 // TODO needs better semantics --EXCEPTION n error -> --ERROR-error 1 .. n --HERE
433 (void) data;
435 mala_engine_arg_eval (eng, pptr, 1, MALA_LITERAL);
437 //TODO MALA_SIDEEFFECT_BEGIN
438 // {
439 #if 0 // TODO --PROGRAM
440 if (mala_stringlist_is_tail (&eng->program, *pptr))
441 return mala_engine_exception (eng, pptr, *pptr,
442 eng->common_string[MALA_STRING_ERROR_MISSING_ARGUMENT]);
443 #endif
444 if (eng->state > MALA_EFAULT)
445 return eng->state;
447 MalaString ex = mala_string_new_print (&eng->words, NULL, //TODO refs
448 "--ERROR-%s",
449 mala_stringlistnode_cstr (mala_stringlistnode_next (*pptr)));
451 // TODO mala_stringlist_elem_delete_fwd (&eng->program, pptr);
452 int state = mala_engine_exception (eng, pptr, *pptr, ex);
453 // TODO mala_stringlist_elem_delete (&eng->program, mala_stringlistnode_next (*pptr));
455 // TODO review mala_string_free (ex);
456 // MALA_SIDEEFFECT_END;
458 return state;
461 #if 0
463 mala_foreach_word_parser (MalaEngine eng,
464 MalaStringListNode_ref pptr,
465 void * data)
467 MalaAction act;
468 MalaStringListNode first;
469 MalaStringListNode second;
470 MalaStringListNode last;
471 MalaStringListNode itr;
472 (void) data;
474 /*TODO bugs, rename to --APPLY fixit etc*/
476 first = mala_engine_arg_eval (eng, pptr, 1, -1, NULL, NULL);
477 if (!first)
478 return eng->state;
479 act = mala_actiondesc_top ((MalaActionDesc) mala_stringlistnode_user_get (first));
480 // TODO allow blocks as first arg (define macro and delete it at later)
481 if (act && act->parser == mala_block_parser)
482 return mala_engine_exception (eng, pptr, first,
483 eng->common_string[MALA_STRING_ERROR_BLOCK_NOT_ALLOWED]);
485 second = mala_engine_arg_eval (eng, pptr, 2, -1, (MalaDataFactory) mala_stringlist_factory, NULL);
486 if (!second)
487 return eng->state;
489 last = mala_stringlistnode_next (second);
491 act = mala_actiondesc_top ((MalaActionDesc) mala_stringlistnode_user_get (second));
493 // expand second
494 if (eng->state != MALA_LITERAL)
495 for (itr = mala_stringlist_tail ((MalaStringList) act->data);
496 !mala_stringlist_is_end ((MalaStringList) act->data, itr);
497 mala_stringlistnode_rev (&itr))
499 #if 0 // TODO --PROGRAM
500 if (!mala_stringlist_after_new (&eng->program,
501 second,
502 mala_stringlistnode_string (itr)))
503 goto ealloc_node;
504 if (!mala_stringlist_after_new (&eng->program,
505 second,
506 mala_stringlistnode_string (first)))
507 goto ealloc_node;
508 #endif
510 else
512 #if 0
513 if (!mala_stringlist_after_new (&eng->program,
514 second,
515 mala_stringlistnode_string (second)))
516 goto ealloc_node;
517 if (!mala_stringlist_after_new (&eng->program,
518 second,
519 mala_stringlistnode_string (first)))
520 goto ealloc_node;
521 #endif
525 // was a block? delete it
526 if (act && act->parser == mala_block_parser)
527 mala_actiondesc_pop_delete (mala_stringlistnode_user_get (second));
529 mala_engine_command_done (eng, pptr, 2);
530 return MALA_SUCCESS;
532 ealloc_node:
533 for (itr = mala_stringlistnode_next (second);
534 itr != last;
535 mala_stringlistnode_fwd (&itr))
537 // mala_stringlist_elem_delete (&eng->program, itr);
540 return MALA_EALLOC; // TODO exception instead (needs pools, no allocation possible further)
547 realloc a string to at least needed size
548 return the amount really reserved or 0 on error
550 static size_t
551 reserve_string (char ** s, size_t actual, size_t needed)
553 size_t n;
554 char * r;
556 for (n = actual>64?actual:64; n <= needed; n += (n>>1)); /*n = n * 1.5*/
558 r = realloc (*s, n);
559 if (!r)
561 /* that was to much, try conservatively */
562 r = realloc (*s, n = needed);
563 if (!r)
564 return 0;
566 *s = r;
567 return n;
569 #endif
572 #endif
576 mala_module_std_statements_init (MalaEngine self)
578 return mala_engine_actions_register (self, std_statements);
582 // Local Variables:
583 // mode: C
584 // c-file-style: "gnu"
585 // End:
586 // arch-tag: 7e2dc784-1527-458a-8881-e87d3fb22cef
587 // end_of_file