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.
25 #include "std_statements.h"
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("--", ("")),
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
));
185 mala_stop_parser (MalaProgram prg
)
187 TRACE (mala_module_std
);
189 mala_stringlist_remove (mala_program_pptr (prg
));
195 mala_skip_parser (MalaProgram prg
)
197 TRACE (mala_module_std
);
202 mala_state state
= mala_program_eval_arg_fmt (prg
, 1, "%d", &n
, &node
);
203 if (state
> MALA_START
)
206 return mala_program_commonexception (prg
, MALA_STRING_ERROR_OUT_OF_RANGE
, node
);
211 pptr
= (MalaStringList
) llist_get_nth_stop (&prg
->pptr
->node
, n
+2,
212 &prg
->program
->node
);
214 return mala_program_commonexception (prg
, MALA_STRING_ERROR_MISSING_ARGUMENT
, prg
->program
);
217 mala_program_action_done (prg
, 1);
220 return MALA_STATEMENT
;
225 mala_pass_parser (MalaProgram prg
)
227 TRACE (mala_module_std
);
228 mala_stringlist_remove (mala_program_pptr (prg
));
229 return MALA_STATEMENT
;
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
;
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
)
251 mala_program_action_done (prg
, 0);
252 return MALA_STATEMENT
;
257 mala_no_parser (MalaProgram prg
)
259 TRACE (mala_module_std
);
266 mala_program_action_done (prg
, 0);
267 return MALA_STATEMENT
;
272 mala_nono_parser (MalaProgram prg
)
274 TRACE (mala_module_std
);
281 mala_program_action_done (prg
, 0);
282 return MALA_STATEMENT
;
287 mala_ifelse_parser (MalaProgram prg
)
289 TRACE (mala_module_std
);
293 mala_state state
= mala_program_eval_arg (prg
, 1, MALA_LITERAL
, &test
);
295 if (state
> MALA_START
)
298 if (state
== MALA_LITERAL
&&
299 mala_stringlist_string (test
) == prg
->engine
->common_string
[MALA_STRING_TRUE
])
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
;
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
;
329 mala_sleep_parser (MalaProgram prg
)
334 mala_state state
= mala_program_eval_arg_fmt (prg
, 1, "%lf", &duration
, NULL
);
335 if (state
> MALA_START
)
340 req
.tv_sec
= (time_t) duration
;
341 req
.tv_nsec
= (long) 1000000000 * (duration
- ((double) req
.tv_sec
));
343 (void) nanosleep (&req
, NULL
);
347 mala_program_action_done (prg
, 1);
348 return MALA_STATEMENT
;
353 mala_throw_parser (MalaProgram prg
)
355 TRACE (mala_module_std
);
357 UNIMPLEMENTED("check this");
358 return MALA_EXCEPTION
;
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
)
371 mala_program_action_done (prg
, 0);
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");
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
;
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
;
424 mala_stringlist_remove (mala_program_pptr (prg
));
430 mala_replace_parser (MalaProgram prg
)
432 TRACE (mala_module_std
);
435 MalaStringList search
;
436 MalaStringList replace
;
438 state
= mala_program_eval_arg (prg
, 1, MALA_LITERAL
, &search
);
439 if (state
> MALA_START
)
442 state
= mala_program_eval_arg (prg
, 2, MALA_LITERAL
, &replace
);
443 if (state
> MALA_START
)
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
));
458 mala_program_action_done (prg
, 2);
459 return MALA_STATEMENT
;
465 mala_defined_parser (MalaEngine eng
,
466 MalaStringListNode_ref pptr
,
469 MalaStringListNode result
;
473 result
= mala_engine_arg_eval (eng
, pptr
, 1, MALA_LITERAL
);
478 mala_engine_command_done (eng
, pptr
, 1);
480 // if (desc && 0 /*TODO mala_actiondesc_top (desc)*/)
481 // return MALA_SUCCESS;
488 mala_trace_parser (MalaEngine eng
,
489 MalaStringListNode_ref pptr
,
494 /*TODO trace levels*/
495 MALA_SIDEEFFECT_BEGIN
496 eng
->engine_trace
= eng
->negated
? MALA_NOTRACE
:MALA_TRACE
;
499 mala_engine_command_done (eng
, pptr
, 0);
500 return MALA_CONTINUE
;
505 mala_gctrace_parser (MalaEngine eng
,
506 MalaStringListNode_ref pptr
,
511 /*TODO trace levels*/
512 MALA_SIDEEFFECT_BEGIN
513 *eng
->gc_trace
= eng
->negated
? MALA_NOTRACE
:MALA_TRACE
;
516 mala_engine_command_done (eng
, pptr
, 0);
517 return MALA_CONTINUE
;
521 /*TODO to predicates*/
523 mala_predicate_greaterorequal_double (double * a
, double * b
)
530 mala_not_parser (MalaEngine eng
,
531 MalaStringListNode_ref pptr
,
534 MalaStringListNode result
;
538 MALA_SIDEEFFECT_BEGIN
539 eng
->negated
= !eng
->negated
;
542 result
= mala_engine_arg_eval (eng
, pptr
, 1, MALA_LITERAL
);
546 mala_engine_command_done (eng
, pptr
, 1);
551 mala_exception_parser (MalaEngine eng
,
552 MalaStringListNode_ref pptr
,
555 // TODO needs better semantics --EXCEPTION n error -> --ERROR-error 1 .. n --HERE
559 mala_engine_arg_eval (eng
, pptr
, 1, MALA_LITERAL
);
561 //TODO MALA_SIDEEFFECT_BEGIN
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
]);
568 if (eng
->state
> MALA_EFAULT
)
571 MalaString ex
= mala_string_new_print (&eng
->words
, NULL
, //TODO refs
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;
587 mala_foreach_word_parser (MalaEngine eng
,
588 MalaStringListNode_ref pptr
,
592 MalaStringListNode first
;
593 MalaStringListNode second
;
594 MalaStringListNode last
;
595 MalaStringListNode itr
;
598 /*TODO bugs, rename to --APPLY fixit etc*/
600 first
= mala_engine_arg_eval (eng
, pptr
, 1, -1, NULL
, NULL
);
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
);
613 last
= mala_stringlistnode_next (second
);
615 act
= mala_actiondesc_top ((MalaActionDesc
) mala_stringlistnode_user_get (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
,
626 mala_stringlistnode_string (itr
)))
628 if (!mala_stringlist_after_new (&eng
->program
,
630 mala_stringlistnode_string (first
)))
637 if (!mala_stringlist_after_new (&eng
->program
,
639 mala_stringlistnode_string (second
)))
641 if (!mala_stringlist_after_new (&eng
->program
,
643 mala_stringlistnode_string (first
)))
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);
657 for (itr
= mala_stringlistnode_next (second
);
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
675 reserve_string (char ** s
, size_t actual
, size_t needed
)
680 for (n
= actual
>64?actual
:64; n
<= needed
; n
+= (n
>>1)); /*n = n * 1.5*/
685 /* that was to much, try conservatively */
686 r
= realloc (*s
, n
= needed
);
700 mala_module_std_statements_init (MalaEngine self
)
702 return mala_engine_actions_register (self
, std_statements
);
708 // c-file-style: "gnu"
710 // arch-tag: 7e2dc784-1527-458a-8881-e87d3fb22cef