From f4d0661601d94a7a21ff11777d56ab584059ed0c Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Sat, 11 Jun 2005 00:36:23 +0000 Subject: [PATCH] block_parser git-archimport-id: chth@gmx.net--2004/mala-glibc--devel--0.2--patch-66 --- ChangeLog | 13 ++++++ engine/engine.c | 73 ++++++++++++++++++++++++---------- engine/engine.h | 17 +++++++- engine/mala_types.h | 4 +- engine/stringlist.c | 12 ++---- includes/mala.h | 1 + std/std.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++-- std/std.h | 5 +++ 8 files changed, 202 insertions(+), 35 deletions(-) diff --git a/ChangeLog b/ChangeLog index 57c5264..b4d1c24 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,19 @@ # arch-tag: automatic-ChangeLog--chth@gmx.net--2004/mala-glibc--devel--0.2 # +2005-06-11 00:36:23 GMT Christian Thaeter patch-66 + + Summary: + block_parser + Revision: + mala-glibc--devel--0.2--patch-66 + + + modified files: + ChangeLog engine/engine.c engine/engine.h engine/mala_types.h + engine/stringlist.c includes/mala.h std/std.c std/std.h + + 2005-06-07 13:37:35 GMT Christian Thaeter patch-65 Summary: diff --git a/engine/engine.c b/engine/engine.c index 36e3f6f..119fea7 100644 --- a/engine/engine.c +++ b/engine/engine.c @@ -43,6 +43,9 @@ static const char * mala_common_strings []= "--SETENV", "--SECTION", "--HERE", + "--BEGIN", + "--END", + "--DEL", "--FLAG-LITERAL-EXPANSION", "--FLAG-EXCLAM-EXPANSION", "--FLAG-NO-EXPANSION", @@ -55,6 +58,7 @@ static const char * mala_common_strings []= "--FLAG-BRACKET-EXPANSION", "--FLAG-ASSIGN-CONTRACTION", "--ERROR-MISSING-ARGUMENT", + "--ERROR-MISSING-END", NULL }; @@ -76,6 +80,7 @@ mala_engine_new () return NULL; self->negated = 0; + self->blockcnt = 0; self->state = MALA_SUCCESS; @@ -162,11 +167,11 @@ mala_engine_macro_define (MalaEngine self, const char * name, int argc, char ** { /* empty substituted by --NULL, TODO use empty string instead? */ mala_stringlist_free (list); - return mala_engine_add_action (self, name, - mala_string_copy(self->common_string[MALA_STRING_NULL]), - mala_substitute_parser, - (MalaDataFactory)mala_string_factory, - NULL); + return mala_engine_add_action_cstr (self, name, + mala_string_copy (self->common_string[MALA_STRING_NULL]), + mala_substitute_parser, + (MalaDataFactory)mala_string_factory, + NULL); } @@ -182,10 +187,10 @@ mala_engine_macro_define (MalaEngine self, const char * name, int argc, char ** if (mexp) { /* macro */ - return mala_engine_add_action (self, name, list, - mala_macro_parser, - (MalaDataFactory)mala_stringlist_factory, - NULL); + return mala_engine_add_action_cstr (self, name, list, + mala_macro_parser, + (MalaDataFactory)mala_stringlist_factory, + NULL); } else if (mala_stringlist_is_tail (list, mala_stringlist_head (list))) { @@ -195,18 +200,18 @@ mala_engine_macro_define (MalaEngine self, const char * name, int argc, char ** subst = mala_string_copy (mala_stringlist_head (list) -> string); mala_stringlist_free (list); - return mala_engine_add_action (self, name, subst, - mala_substitute_parser, - (MalaDataFactory)mala_string_factory, - NULL); + return mala_engine_add_action_cstr (self, name, subst, + mala_substitute_parser, + (MalaDataFactory)mala_string_factory, + NULL); } else { /* expand */ - return mala_engine_add_action (self, name, list, - mala_expand_parser, - (MalaDataFactory) mala_stringlist_factory, - NULL); + return mala_engine_add_action_cstr (self, name, list, + mala_expand_parser, + (MalaDataFactory) mala_stringlist_factory, + NULL); } eunderrun: @@ -235,9 +240,9 @@ mala_engine_pushback_word (MalaEngine self, const char * word) } int -mala_engine_add_action (MalaEngine self, const char * cname, void * data, - MalaParserFunc parser, MalaDataFactory factory, - MalaAction parent) +mala_engine_add_action_cstr (MalaEngine self, const char * cname, void * data, + MalaParserFunc parser, MalaDataFactory factory, + MalaAction parent) { MalaString name; MalaAction action; @@ -270,6 +275,34 @@ mala_engine_add_action (MalaEngine self, const char * cname, void * data, return self->state = MALA_EALLOC; } +int +mala_engine_add_action (MalaEngine self, MalaString name, void * data, + MalaParserFunc parser, MalaDataFactory factory, + MalaAction parent) +{ + MalaAction action; + + /*TODO such checks everywhere*/ + if(!self) + return MALA_EINVALID; + if(self->state > MALA_EFAULT) + return self->state; + + action = mala_action_new (name, data, parser, factory, parent); + if (!action) + goto ealloc_action; + + if (mala_action_attach (action) != MALA_SUCCESS) + goto ealloc_attach; + + return MALA_SUCCESS; + + ealloc_attach: + mala_action_free (action); + ealloc_action: + return self->state = MALA_EALLOC; +} + MalaEngine mala_engine_new_initfunc (int (*initfunc)(MalaEngine)) diff --git a/engine/engine.h b/engine/engine.h index 3101027..b5df8e5 100644 --- a/engine/engine.h +++ b/engine/engine.h @@ -40,6 +40,9 @@ enum mala_common_strings_enum MALA_STRING_SETENV, MALA_STRING_SECTION, MALA_STRING_HERE, + MALA_STRING_BEGIN, + MALA_STRING_END, + MALA_STRING_DEL, MALA_STRING_FLAG_LITERAL_EXPANSION, MALA_STRING_FLAG_EXCLAM_EXPANSION, MALA_STRING_FLAG_NO_EXPANSION, @@ -52,6 +55,7 @@ enum mala_common_strings_enum MALA_STRING_FLAG_BRACKET_EXPANSION, MALA_STRING_FLAG_ASSIGN_CONTRACTION, MALA_STRING_ERROR_MISSING_ARGUMENT, + MALA_STRING_ERROR_MISSING_END, MALA_MAX_COMMON_STRING }; @@ -75,10 +79,14 @@ struct mala_engine_struct /*TODO static ringbuffer char ringbuffer *[10] */ - const char * argv_0; + //const char * argv_0; int negated:1; + /* --BEGIN ... --END blocks are translated to --BLOCK-xxxxxxxx macros, + where xxxxxxxx is a monotonic incrementing counter, its value is stored here */ + unsigned blockcnt; + int state; }; //#endif @@ -218,7 +226,12 @@ int mala_engine_assign_contraction (MalaEngine self, MalaStringListNode_ref pptr); int -mala_engine_add_action (MalaEngine self, const char* name, void* data, +mala_engine_add_action_cstr (MalaEngine self, const char* cname, void* data, + MalaParserFunc parser, MalaDataFactory factory, + MalaAction parent); + +int +mala_engine_add_action (MalaEngine self, MalaString name, void* data, MalaParserFunc parser, MalaDataFactory factory, MalaAction parent); diff --git a/engine/mala_types.h b/engine/mala_types.h index 62dd9c3..2e56743 100644 --- a/engine/mala_types.h +++ b/engine/mala_types.h @@ -43,8 +43,8 @@ enum mala_state_enum MALA_SUCCESS, /* last comand returned true */ MALA_FAILURE, /* last comand returned false */ MALA_EXCEPTION, /* some error occured (in MaLa code) */ - MALA_LITERAL, /* dont evaluate the next argument */ - // MALA_BLOCK, /* next command is a (maybe nested) --BEGIN --END block */ + MALA_LITERAL, /* dont evaluate argument */ + MALA_DELAY, /* delay evaluation of the command */ MALA_EFAULT, /* everything beyond are runtime errors, which may be handled by the userprogram */ MALA_ENOACTION, /* no action found, exception falltrough */ diff --git a/engine/stringlist.c b/engine/stringlist.c index 80228dc..bc2fc0b 100644 --- a/engine/stringlist.c +++ b/engine/stringlist.c @@ -79,8 +79,7 @@ mala_stringlist_head_new (MalaStringList head, MalaString str) if (!n) return NULL; - n->string = str; - mala_string_free (str); + n->string = mala_string_copy (str); CIRCLEQ_INSERT_HEAD (head, n, node); return n; @@ -98,8 +97,7 @@ mala_stringlist_tail_new (MalaStringList head, MalaString str) if (!n) return NULL; - n->string = str; - mala_string_copy (str); + n->string = mala_string_copy (str); CIRCLEQ_INSERT_TAIL (head, n, node); return n; @@ -145,8 +143,7 @@ mala_stringlist_after_new (MalaStringList head, MalaStringListNode pred, MalaStr if (!n) return NULL; - n->string = str; - mala_string_copy (str); + n->string = mala_string_copy (str); CIRCLEQ_INSERT_AFTER (head, pred, n, node); return n; @@ -160,8 +157,7 @@ mala_stringlist_before_new (MalaStringList head, MalaStringListNode succ, MalaSt if (!n) return NULL; - n->string = str; - mala_string_copy (str); + n->string = mala_string_copy (str); CIRCLEQ_INSERT_BEFORE (head, succ, n, node); return n; diff --git a/includes/mala.h b/includes/mala.h index f81d560..0d59cd3 100644 --- a/includes/mala.h +++ b/includes/mala.h @@ -23,6 +23,7 @@ #include "engine/mala_types.h" #include "engine/engine.h" #include "engine/action.h" +#include "engine/actiondesc.h" #include "engine/strings.h" //#include "engine/mala_types.h" diff --git a/std/std.c b/std/std.c index 75ac775..d5d721f 100644 --- a/std/std.c +++ b/std/std.c @@ -43,10 +43,14 @@ static mala_actioninit std_actions[] = MALA_PARSER_BRIEF("--DEF", "defines a new macro"), MALA_PARSER_HELP("--DEF", ("--HELP-ACTION", "TODO")), + MALA_PARSER("--DEL", mala_macrodef_parser, NULL, NULL, NULL), + MALA_PARSER_BRIEF("--DEF", "delete a macro"), + MALA_PARSER_HELP("--DEF", ("--HELP-ACTION", "TODO")), + + */ MALA_PARSER("--BEGIN", mala_block_parser, NULL, NULL, NULL), MALA_PARSER_BRIEF("--BEGIN", "starts a block of code"), MALA_PARSER_HELP("--BEGIN", ("--HELP-ACTION", "TODO")), - */ MALA_PARSER("--NOT", mala_not_parser, NULL, NULL, NULL), MALA_PARSER_BRIEF("--NOT", "negates logic"), @@ -69,11 +73,14 @@ static mala_actioninit std_actions[] = MALA_PARSER_HELP("--FLAG-NUMSPLIT-EXPANSION", ("--HELP-ACTION", "TODO")), MALA_TRUE_PARSER("--FLAG-LITERAL-EXPANSION"), - MALA_PARSER_BRIEF("--FLAG-LITERAL-EXPANSION", "words beginning with a single backquote will be preprocessed as '--LITERAL' 'theword'"), + MALA_PARSER_BRIEF("--FLAG-LITERAL-EXPANSION", + "words beginning with a single backquote will be " + "preprocessed as '--LITERAL' 'theword'"), MALA_PARSER_HELP("--FLAG-LITERAL-EXPANSION", ("--HELP-ACTION", "TODO")), MALA_TRUE_PARSER("--FLAG-EXCLAM-EXPANSION"), - MALA_PARSER_BRIEF("--FLAG-EXCLAM-EXPANSION", "a single ! will be preprocessed as --NOT"), + MALA_PARSER_BRIEF("--FLAG-EXCLAM-EXPANSION", + "a single ! will be preprocessed as --NOT"), MALA_PARSER_HELP("--FLAG-EXCLAM-EXPANSION", ("--HELP-ACTION", "TODO")), MALA_TRUE_PARSER("--FLAG-NO-EXPANSION"), @@ -252,6 +259,105 @@ mala_not_parser (MalaEngine eng, return MALA_SUCCESS; } +int +mala_block_parser (MalaEngine eng, + MalaStringListNode_ref pptr, + void * data) +{ + MalaStringListNode itr; + MalaStringListNode end; + MalaStringList list; + unsigned depth = 1; + MalaString name = NULL; + int mexp = 0; + + (void) data; + + if (mala_stringlist_is_tail (&eng->program, *pptr)) + return mala_engine_exception (eng, pptr, *pptr, + eng->common_string[MALA_STRING_ERROR_MISSING_END]); + + // find matching --END + for (end = mala_stringlist_next (*pptr); + !mala_stringlist_is_end (&eng->program, end); + mala_stringlist_fwd (&end)) + { + if (mala_string_same(end->string, eng->common_string[MALA_STRING_BEGIN])) + ++depth; + else if (mala_string_same(end->string, eng->common_string[MALA_STRING_END])) + --depth; + if (!depth) + break; + } + + if (depth) + return mala_engine_exception (eng, pptr, mala_stringlist_prev (end), + eng->common_string[MALA_STRING_ERROR_MISSING_END]); + + list = mala_stringlist_new (); + if (!list) + return MALA_EALLOC; + + for (itr = mala_stringlist_next (*pptr); itr != end; mala_stringlist_fwd (&itr)) + if (!mala_stringlist_tail_new (list, itr->string)) + goto ealloc_node; + + do { + mala_string_free (name); + name = mala_string_new_print (&eng->words, "--BLOCK.%08X", ++eng->blockcnt); + if (!name) + goto ealloc_name; + } while (mala_actiondesc_top ((MalaActionDesc)mala_string_user_get (name))); + + // blocks need to free themself, prepend --DEL --LITERAL --BLOCK-xxxxxxxx + mala_stringlist_head_new (list, name); + mala_stringlist_head_new (list, eng->common_string[MALA_STRING_LITERAL]); + mala_stringlist_head_new (list, eng->common_string[MALA_STRING_DEL]); + + // if the strings contain % then we have to use a macro, else simple expansion will suffice + for (itr = mala_stringlist_head (list); + !mala_stringlist_is_end (list, itr); + mala_stringlist_fwd(&itr)) + if (mala_string_char_find (itr->string, '%') != SIZE_MAX) + { + mexp = 1; + break; + } + + if (mexp) + { + /* macro */ + if (MALA_SUCCESS != mala_engine_add_action (eng, name, list, + mala_macro_parser, + (MalaDataFactory)mala_stringlist_factory, + NULL)) + goto ealloc_action; + } + else + { + /* expand */ + if (MALA_SUCCESS != mala_engine_add_action (eng, name, list, + mala_expand_parser, + (MalaDataFactory) mala_stringlist_factory, + NULL)) + goto ealloc_action; + } + + mala_stringlist_after_new (&eng->program, end, name); + mala_string_free (name); + while (*pptr != end) + mala_stringlist_elem_delete_fwd (&eng->program, pptr); + mala_stringlist_elem_delete_fwd (&eng->program, pptr); + + return MALA_DELAY; + + ealloc_action: + mala_string_free (name); + ealloc_name: + ealloc_node: + mala_stringlist_free (list); + return MALA_EALLOC; +} /* // Local Variables: diff --git a/std/std.h b/std/std.h index 499077c..126b9c1 100644 --- a/std/std.h +++ b/std/std.h @@ -105,6 +105,11 @@ mala_not_parser (MalaEngine eng, MalaStringListNode_ref pptr, void * data); +int +mala_block_parser (MalaEngine eng, + MalaStringListNode_ref pptr, + void * data); + #endif /* MALA_STD_H */ -- 2.11.4.GIT