split std/ into smaller files
[mala.git] / std / std_statements.c
blob675816433d2f07e9c8f3f7b37a9ef14efdd738d0
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.h"
28 static
29 mala_actioninit std_statements[] =
32 MALA_PARSER("--", mala__parser, NULL, NULL, NULL),
33 MALA_PARSER_BRIEF("--", ""),
34 // MALA_PARSER_HELP("--", ("TODO")),
35 MALA_PARSER_SIGNATURE_TYPE("--", ("")),
36 MALA_PARSER_SIGNATURE_USAGE("--", ("")),
37 MALA_PARSER_RESULT_TYPE("--", ("")),
38 MALA_PARSER_RESULT_USAGE("--", ("")),
40 MALA_PARSER("--CHILDOF", mala__parser, NULL, NULL, NULL),
41 MALA_PARSER_BRIEF("--", ""),
42 // MALA_PARSER_HELP("--", ("TODO")),
43 MALA_PARSER_SIGNATURE_TYPE("--", ("")),
44 MALA_PARSER_SIGNATURE_USAGE("--", ("")),
45 MALA_PARSER_RESULT_TYPE("--", ("")),
46 MALA_PARSER_RESULT_USAGE("--", ("")),
51 MALA_PARSER("--EXCEPTION", mala_exception_parser, NULL, NULL, NULL),
52 MALA_PARSER_BRIEF("--EXCEPTION", "defines a new macro"),
53 // MALA_PARSER_HELP("--EXCEPTION", ("TODO")),
54 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
55 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
56 // MALA_PARSER_RESULT_TYPE("--", ("")),
57 // MALA_PARSER_RESULT_USAGE("--", ("")),
59 MALA_EXPAND_PARSER("--IFDEF", ("--IF", "--DEFINED")),
60 MALA_PARSER_BRIEF("--IFDEF", "tests if a word is defined as macro"),
61 // MALA_PARSER_HELP("--NOT", ("TODO")),
62 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
63 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
64 // MALA_PARSER_RESULT_TYPE("--", ("")),
65 // MALA_PARSER_RESULT_USAGE("--", ("")),
67 MALA_PARSER("--DEFINED", mala_defined_parser, NULL, NULL, NULL),
68 MALA_PARSER_BRIEF("--DEFINED", "tests if a word is defined as macro"),
69 // MALA_PARSER_HELP("--NOT", ("TODO")),
70 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
71 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
72 // MALA_PARSER_RESULT_TYPE("--", ("")),
73 // MALA_PARSER_RESULT_USAGE("--", ("")),
75 MALA_PARSER("--IF", mala_if_parser, NULL, NULL, NULL),
76 MALA_PARSER_BRIEF("--IF", "executes some code if a condition succeeded"),
77 // MALA_PARSER_HELP("--NOT", ("TODO")),
78 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
79 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
80 // MALA_PARSER_RESULT_TYPE("--", ("")),
81 // MALA_PARSER_RESULT_USAGE("--", ("")),
83 MALA_PARSER("--ELSE", mala_else_parser, NULL, NULL, NULL),
84 MALA_PARSER_BRIEF("--ELSE", "executes some code when the former macro failed"),
85 // MALA_PARSER_HELP("--NOT", ("TODO")),
86 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
87 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
88 // MALA_PARSER_RESULT_TYPE("--", ("")),
89 // MALA_PARSER_RESULT_USAGE("--", ("")),
92 //MALA_PARSER("--NOT", mala_not_parser, NULL, NULL, NULL),
93 //MALA_PARSER_BRIEF("--NOT", "negates logic"),
94 // MALA_PARSER_HELP("--NOT", ("TODO")),
95 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
96 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
97 // MALA_PARSER_RESULT_TYPE("--", ("")),
98 // MALA_PARSER_RESULT_USAGE("--", ("")),
101 MALA_PARSER("--LITERAL", mala_literal_parser, NULL, NULL, NULL),
102 MALA_PARSER_BRIEF("--LITERAL", "Treats the next word literally"),
103 // MALA_PARSER_HELP("--LITERAL", ("TODO")),
104 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
105 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
106 // MALA_PARSER_RESULT_TYPE("--", ("")),
107 // MALA_PARSER_RESULT_USAGE("--", ("")),
110 MALA_PARSER("--SLEEP",mala_sleep_parser, NULL, NULL, NULL),
111 MALA_PARSER_BRIEF("--SLEEP", "delays execution for some time"),
112 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")),
113 MALA_PARSER_SIGNATURE_USAGE("--SLEEP",("Seconds to sleep")),
114 // //MALA_PARSER_RESULT_USAGE("--PRINTWRAPED", ("TODO")),
115 //MALA_PARSER_SIGNATURE_TYPE("--SLEEP", ("DURATION")),
117 MALA_PARSER("--TRACE",mala_trace_parser, NULL, NULL, NULL),
118 MALA_PARSER_BRIEF("--TRACE", "controls the trace mode of the MaLa VM"),
119 MALA_PARSER_HELP("--TRACE", ("The program will be suspended for some time, the time might be specified as fraction of seconds\t example: 9.5")),
120 //MALA_PARSER_SIGNATURE_USAGE("--SLEEP",("Seconds to sleep")),
121 // //MALA_PARSER_RESULT_USAGE("--PRINTWRAPED", ("TODO")),
122 //MALA_PARSER_SIGNATURE_TYPE("--SLEEP", ("DURATION")),
124 // MALA_PARSER("--EVAL",mala_eval_parser, NULL, NULL, NULL),
125 // MALA_PARSER_BRIEF("--EVAL",""),
126 // MALA_PARSER_HELP("--EVAL",("blah")),
127 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
128 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
129 // MALA_PARSER_RESULT_TYPE("--", ("")),
130 // MALA_PARSER_RESULT_USAGE("--", ("")),
132 MALA_PASS_PARSER("--PASS"),
133 MALA_PARSER_BRIEF("--PASS","does nothing"),
134 MALA_PARSER_HELP("--PASS",("--HELP-ACTION","blah")),
135 // MALA_PARSER_SIGNATURE_TYPE("--", ("")),
136 // MALA_PARSER_SIGNATURE_USAGE("--", ("")),
137 // MALA_PARSER_RESULT_TYPE("--", ("")),
138 // MALA_PARSER_RESULT_USAGE("--", ("")),
140 MALA_ACTIONS_END
146 mala_defined_parser (MalaEngine eng,
147 MalaStringListNode_ref pptr,
148 void * data)
150 MalaStringListNode result;
151 MalaActionDesc desc;
153 (void) data;
155 result = mala_engine_arg_eval (eng, pptr, 1, MALA_LITERAL);
156 if (!result)
157 return eng->state;
159 MALA_SIDEEFFECT_BEGIN
161 desc = (MalaActionDesc) mala_stringlistnode_user_get (result);
163 mala_engine_command_done (eng, pptr, 1);
165 if (desc && mala_actiondesc_top (desc))
167 return MALA_SUCCESS;
169 else
171 return MALA_FAILURE;
174 MALA_SIDEEFFECT_END;
176 return MALA_REMOVE;
181 mala_if_parser (MalaEngine eng,
182 MalaStringListNode_ref pptr,
183 void * data)
185 MalaStringListNode result;
186 (void) data;
187 /*TODO negated, blocks, parse long double 0.0 as false*/
188 /* what with syntax errors like --IF foo --ELSE .. (missing 'then' part)*/
189 int state;
191 result = mala_engine_arg_eval (eng, pptr, 1, MALA_LITERAL);
192 if (!result)
193 return eng->state;
195 MALA_SIDEEFFECT_BEGIN
197 if (eng->state == MALA_LITERAL)
199 if (mala_engine_string_istrue (eng, mala_stringlistnode_string (result)))
200 eng->state = MALA_SUCCESS;
201 else
202 eng->state = MALA_FAILURE;
205 state = eng->state;
207 if (eng->state == MALA_FAILURE)
208 eng->state = MALA_REMOVE;
210 result = mala_engine_arg_eval (eng, pptr, 2, MALA_LITERAL);
211 if (!result)
212 return eng->state;
214 if (eng->state == MALA_REMOVE)
215 eng->state = MALA_FAILURE;
217 MALA_SIDEEFFECT_END;
219 if (eng->state == MALA_LITERAL)
220 mala_engine_command_done (eng, pptr, 1);
221 else
222 mala_engine_command_done (eng, pptr, 2);
223 return state;
227 mala_else_parser (MalaEngine eng,
228 MalaStringListNode_ref pptr,
229 void * data)
231 MalaStringListNode result;
232 (void) data;
233 /*TODO blocks*/
235 MALA_SIDEEFFECT_BEGIN
237 if (eng->state == MALA_SUCCESS)
238 eng->state = MALA_REMOVE;
240 result = mala_engine_arg_eval (eng, pptr, 1, MALA_LITERAL);
241 if (!result)
242 return eng->state;
244 if (eng->state == MALA_REMOVE)
245 eng->state = MALA_SUCCESS;
247 MALA_SIDEEFFECT_END;
249 if (eng->state == MALA_LITERAL)
250 mala_engine_command_done (eng, pptr, 0);
251 else
252 mala_engine_command_done (eng, pptr, 0);
253 return eng->state;
257 mala_pass_parser (MalaEngine eng,
258 MalaStringListNode_ref pptr,
259 void * data)
261 (void) data;
263 mala_stringlist_elem_delete_fwd (&eng->program, pptr);
265 return eng->state;
269 mala_trace_parser (MalaEngine eng,
270 MalaStringListNode_ref pptr,
271 void * data)
273 (void) data;
275 MALA_SIDEEFFECT_BEGIN
276 eng->trace = !eng->negated;
277 MALA_SIDEEFFECT_END;
279 mala_engine_command_done (eng, pptr, 0);
280 return MALA_SUCCESS;
283 /*TODO to predicates*/
284 static int
285 mala_predicate_greaterorequal_double (double * a, double * b)
287 return *a >= *b;
291 mala_sleep_parser (MalaEngine eng,
292 MalaStringListNode_ref pptr,
293 void * data)
295 double duration;
296 double zero = 0.0;
297 struct timespec req;
299 (void) data;
301 if (mala_engine_arg_eval_fmt (eng, pptr, 1, "%lf", &duration,
302 (MalaPredicate) mala_predicate_greaterorequal_double, &zero
303 ) >= MALA_EXCEPTION)
304 return eng->state;
306 MALA_SIDEEFFECT_BEGIN
308 req.tv_sec = (time_t) duration;
309 req.tv_nsec = (long) 1000000000 * (duration - ((double) req.tv_sec));
311 (void) nanosleep (&req, NULL);
313 MALA_SIDEEFFECT_END;
315 mala_engine_command_done (eng, pptr, 1);
316 return MALA_SUCCESS;
320 mala_literal_parser (MalaEngine eng,
321 MalaStringListNode_ref pptr,
322 void * data)
324 (void) data;
326 MALA_SIDEEFFECT_BEGIN
328 if (mala_stringlist_is_tail (&eng->program, *pptr))
329 return mala_engine_exception (eng, pptr, *pptr,
330 eng->common_string[MALA_STRING_ERROR_MISSING_ARGUMENT]);
332 MALA_SIDEEFFECT_END;
334 mala_stringlist_elem_delete_fwd (&eng->program, pptr);
335 return MALA_LITERAL;
338 #if 0
340 mala_not_parser (MalaEngine eng,
341 MalaStringListNode_ref pptr,
342 void * data)
344 (void) data;
345 /*TODO evaluate %1*/
346 MALA_SIDEEFFECT_BEGIN
348 if (mala_stringlist_is_tail (&eng->program, *pptr))
349 return mala_engine_exception (eng, pptr, *pptr,
350 eng->common_string[MALA_STRING_ERROR_MISSING_ARGUMENT]);
351 } /*TODO remove unfinished*/
352 MALA_SIDEEFFECT_END;
354 mala_stringlist_elem_delete_fwd (&eng->program, pptr);
355 eng->negated = !eng->negated;
356 return MALA_SUCCESS; /*TODO*/
358 #endif
361 mala_exception_parser (MalaEngine eng,
362 MalaStringListNode_ref pptr,
363 void * data)
365 // TODO needs better semantics --EXCEPTION n error -> --ERROR-error 1 .. n --HERE
367 (void) data;
369 mala_engine_arg_eval (eng, pptr, 1, MALA_LITERAL);
371 //TODO MALA_SIDEEFFECT_BEGIN
372 // {
373 if (mala_stringlist_is_tail (&eng->program, *pptr))
374 return mala_engine_exception (eng, pptr, *pptr,
375 eng->common_string[MALA_STRING_ERROR_MISSING_ARGUMENT]);
377 if (eng->state > MALA_EFAULT)
378 return eng->state;
380 MalaString ex = mala_string_new_print (&eng->words, "--ERROR-%s",
381 mala_stringlistnode_cstr (mala_stringlistnode_next (*pptr)));
383 mala_stringlist_elem_delete_fwd (&eng->program, pptr);
384 int state = mala_engine_exception (eng, pptr, *pptr, ex);
385 mala_stringlist_elem_delete (&eng->program, mala_stringlistnode_next (*pptr));
387 mala_string_free (ex);
388 // MALA_SIDEEFFECT_END;
390 return state;
393 #if 0
395 mala_foreach_word_parser (MalaEngine eng,
396 MalaStringListNode_ref pptr,
397 void * data)
399 MalaAction act;
400 MalaStringListNode first;
401 MalaStringListNode second;
402 MalaStringListNode last;
403 MalaStringListNode itr;
404 (void) data;
406 /*TODO bugs, rename to --APPLY fixit etc*/
408 first = mala_engine_arg_eval (eng, pptr, 1, -1, NULL, NULL);
409 if (!first)
410 return eng->state;
411 act = mala_actiondesc_top ((MalaActionDesc) mala_stringlistnode_user_get (first));
412 // TODO allow blocks as first arg (define macro and delete it at later)
413 if (act && act->parser == mala_block_parser)
414 return mala_engine_exception (eng, pptr, first,
415 eng->common_string[MALA_STRING_ERROR_BLOCK_NOT_ALLOWED]);
417 second = mala_engine_arg_eval (eng, pptr, 2, -1, (MalaDataFactory) mala_stringlist_factory, NULL);
418 if (!second)
419 return eng->state;
421 last = mala_stringlistnode_next (second);
423 act = mala_actiondesc_top ((MalaActionDesc) mala_stringlistnode_user_get (second));
425 // expand second
426 if (eng->state != MALA_LITERAL)
427 for (itr = mala_stringlist_tail ((MalaStringList) act->data);
428 !mala_stringlist_is_end ((MalaStringList) act->data, itr);
429 mala_stringlistnode_rev (&itr))
431 if (!mala_stringlist_after_new (&eng->program,
432 second,
433 mala_stringlistnode_string (itr)))
434 goto ealloc_node;
435 if (!mala_stringlist_after_new (&eng->program,
436 second,
437 mala_stringlistnode_string (first)))
438 goto ealloc_node;
440 else
442 if (!mala_stringlist_after_new (&eng->program,
443 second,
444 mala_stringlistnode_string (second)))
445 goto ealloc_node;
446 if (!mala_stringlist_after_new (&eng->program,
447 second,
448 mala_stringlistnode_string (first)))
449 goto ealloc_node;
453 // was a block? delete it
454 if (act && act->parser == mala_block_parser)
455 mala_actiondesc_pop_delete (mala_stringlistnode_user_get (second));
457 mala_engine_command_done (eng, pptr, 2);
458 return MALA_SUCCESS;
460 ealloc_node:
461 for (itr = mala_stringlistnode_next (second);
462 itr != last;
463 mala_stringlistnode_fwd (&itr))
465 mala_stringlist_elem_delete (&eng->program, itr);
468 return MALA_EALLOC; // TODO exception instead (needs pools, no allocation possible further)
475 realloc a string to at least needed size
476 return the amount really reserved or 0 on error
478 static size_t
479 reserve_string (char ** s, size_t actual, size_t needed)
481 size_t n;
482 char * r;
484 for (n = actual>64?actual:64; n <= needed; n += (n>>1)); /*n = n * 1.5*/
486 r = realloc (*s, n);
487 if (!r)
489 /* that was to much, try conservatively */
490 r = realloc (*s, n = needed);
491 if (!r)
492 return 0;
494 *s = r;
495 return n;
497 #endif
501 mala_module_std_statements_init (MalaEngine self)
503 return mala_engine_actions_register (self, std_statements);
507 // Local Variables:
508 // mode: C
509 // c-file-style: "gnu"
510 // End:
511 // arch-tag: 7e2dc784-1527-458a-8881-e87d3fb22cef
512 // end_of_file