From: Ben Pfaff Date: Mon, 31 May 2021 01:08:21 +0000 (-0700) Subject: Basic tests for macros and arguments pass. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?p=pspp;a=commitdiff_plain;h=350d60cd9a6515950c1a6c745cfafcbd2206bee0 Basic tests for macros and arguments pass. --- diff --git a/src/language/control/define.c b/src/language/control/define.c index 6c71f02c09..187eb9fcf8 100644 --- a/src/language/control/define.c +++ b/src/language/control/define.c @@ -23,6 +23,7 @@ #include "language/lexer/macro.h" #include "language/lexer/scan.h" #include "language/lexer/token.h" +#include "libpspp/message.h" #include "gl/xalloc.h" @@ -59,7 +60,7 @@ parse_quoted_token (struct lexer *lexer, struct token *token) struct substring s = lex_tokss (lexer); struct string_lexer slex; string_lexer_init (&slex, s.string, s.length, SEG_MODE_INTERACTIVE); - struct token another_token; + struct token another_token = { .type = T_STOP }; if (!string_lexer_next (&slex, token) || string_lexer_next (&slex, &another_token)) { @@ -228,6 +229,13 @@ cmd_debug_expand (struct lexer *lexer, struct dataset *ds UNUSED) settings_set_mprint (true); while (lex_token (lexer) != T_STOP) - lex_get (lexer); + { + if (!lex_next_is_from_macro (lexer, 0) && lex_token (lexer) != T_ENDCMD) + { + struct substring rep = lex_next_representation (lexer, 0, 0); + msg (MN, "unexpanded token \"%.*s\"", (int) rep.length, rep.string); + } + lex_get (lexer); + } return CMD_SUCCESS; } diff --git a/src/language/lexer/lexer.c b/src/language/lexer/lexer.c index f577c598b8..534ed077e1 100644 --- a/src/language/lexer/lexer.c +++ b/src/language/lexer/lexer.c @@ -216,6 +216,7 @@ lex_push_token__ (struct lex_source *src) token = &src->tokens[deque_push_front (&src->deque)]; token->token = (struct token) { .type = T_STOP }; + token->from_macro = false; return token; } @@ -972,6 +973,12 @@ lex_next_representation (const struct lexer *lexer, int n0, int n1) return lex_source_get_syntax__ (lex_source__ (lexer), n0, n1); } +bool +lex_next_is_from_macro (const struct lexer *lexer, int n) +{ + return lex_next__ (lexer, n)->from_macro; +} + static bool lex_tokens_match (const struct token *actual, const struct token *expected) { diff --git a/src/language/lexer/lexer.h b/src/language/lexer/lexer.h index 86bb4f2b5d..596e27a335 100644 --- a/src/language/lexer/lexer.h +++ b/src/language/lexer/lexer.h @@ -149,6 +149,7 @@ struct substring lex_next_tokss (const struct lexer *, int n); /* Token representation. */ struct substring lex_next_representation (const struct lexer *, int n0, int n1); +bool lex_next_is_from_macro (const struct lexer *, int n); /* Current position. */ int lex_get_first_line_number (const struct lexer *, int n); diff --git a/src/language/lexer/macro.c b/src/language/lexer/macro.c index 32185fb9cf..fd5ac452cf 100644 --- a/src/language/lexer/macro.c +++ b/src/language/lexer/macro.c @@ -429,7 +429,9 @@ me_next_arg (struct macro_expander *me) return me_finished (me); else { - me->state = me->param->positional ? ME_ARG : ME_KEYWORD; + me->state = (!me->param->positional ? ME_KEYWORD + : me->param->arg_type == ARG_ENCLOSE ? ME_ENCLOSE + : ME_ARG); return 0; } } @@ -455,8 +457,11 @@ me_error (struct macro_expander *me) static int me_add_arg (struct macro_expander *me, const struct macro_token *mt) { + const struct macro_param *p = me->param; + const struct token *token = &mt->token; - if (token->type == T_ENDCMD || token->type == T_STOP) + if ((token->type == T_ENDCMD || token->type == T_STOP) + && p->arg_type != ARG_CMDEND) { msg (SE, _("Unexpected end of command reading argument %s " "to macro %s."), me->param->name, me->macro->name); @@ -466,7 +471,6 @@ me_add_arg (struct macro_expander *me, const struct macro_token *mt) me->n_tokens++; - const struct macro_param *p = me->param; struct macro_tokens **argp = &me->args[p - me->macro->params]; if (!*argp) *argp = xzalloc (sizeof **argp); @@ -613,7 +617,9 @@ macro_expander_create (const struct macro_set *macros, return 1; else { - me->state = macro->params[0].positional ? ME_ARG : ME_KEYWORD; + me->state = (!macro->params[0].positional ? ME_KEYWORD + : macro->params[0].arg_type == ARG_ENCLOSE ? ME_ENCLOSE + : ME_ARG); me->args = xcalloc (macro->n_params, sizeof *me->args); me->param = macro->params; return 0; diff --git a/tests/language/control/define.at b/tests/language/control/define.at index f1f3f41fa0..0211c71785 100644 --- a/tests/language/control/define.at +++ b/tests/language/control/define.at @@ -29,7 +29,7 @@ m(n,o). "x "" y". !ENDDEFINE. DEBUG EXPAND. -!macro() +!macro ]) AT_CHECK([pspp --testing-mode define.sps], [0], [dnl a b c d e f g h. @@ -43,30 +43,101 @@ AT_CLEANUP AT_SETUP([macro expansion with arguments]) AT_DATA([define.sps], [dnl -DEFINE !t1(!positional !tokens(1)) (!1) !ENDDEFINE. -DEFINE !t2(!positional !tokens(2)) (!1) !ENDDEFINE. -DEFINE !ce(!positional !charend('/')) (!1) !ENDDEFINE. +DEFINE !title(!positional !tokens(1)) !1 !ENDDEFINE. +DEFINE !t1(!positional !tokens(1)) t1 (!1) !ENDDEFINE. +DEFINE !t2(!positional !tokens(2)) t2 (!1) !ENDDEFINE. + +DEFINE !ce(!positional !charend('/')) ce (!1) !ENDDEFINE. +DEFINE !ce2(!positional !charend('(') + /!positional !charend(')')) +ce2 (!1, !2) +!ENDDEFINE. + +DEFINE !e(!positional !enclose('{','}')) e (!1) !ENDDEFINE. + +DEFINE !cmd(!positional !cmdend) cmd(!1) !ENDDEFINE. +DEFINE !cmd2(!positional !cmdend + /!positional !tokens(1)) +cmd2(!1, !2) +!ENDDEFINE. + DEBUG EXPAND. +!title "!TOKENS(1) argument." !t1 a. !t1 b. !t1 a b. +!title "!TOKENS(2) argument." !t2 a b. !t2 b c d. +!title "!CHAREND argument." +!ce/. +!ce x/. +!ce x y/. !ce x y z/. + +!title "Two !CHAREND arguments." +!ce2 x(y). +!ce2 1 2 3 4(). + +!title "!ENCLOSE argument." +!e {}. +!e {a}. +!e {a b}. + +!title "!CMDEND argument." +!cmd 1 2 3 4. +!cmd2 5 6. +7. ]) AT_CHECK([pspp --testing-mode define.sps], [0], [dnl -(a) +"!TOKENS(1) argument." + +t1(a) + +t1(b) + +t1(a) + +note: unexpanded token "b" + +"!TOKENS(2) argument." + +t2(a b) + +t2(b c) + +note: unexpanded token "d" + +"!CHAREND argument." + +ce( ) + +ce(x) + +ce(x y) + +ce(x y z) + +"Two !CHAREND arguments." + +ce2(x, y) + +ce2(1 2 3 4, ) + +"!ENCLOSE argument." + +e( ) -(b) +e(a) -(a) +e(a b) -(a b) +"!CMDEND argument." -(b c) +cmd(1 2 3 4) -(x y z) +cmd2(5 6, 7) ]) AT_CLEANUP