X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fq2c.c;h=7af81865ad663b4808aea707976b7b4223979156;hb=304c185799902df1dd96a8ff2d13d279005a82e5;hp=fec3e3ab4b0d21289d573c46c4f2fb9ba0cd4d93;hpb=0dfeb46aa388fae94797accde705a13d9ef7aff8;p=pspp-builds.git diff --git a/src/q2c.c b/src/q2c.c index fec3e3ab..7af81865 100644 --- a/src/q2c.c +++ b/src/q2c.c @@ -535,6 +535,13 @@ typedef enum } subcommand_type; +typedef enum + { + ARITY_ONCE_EXACTLY, /* must occur exactly once */ + ARITY_ONCE_ONLY, /* zero or once */ + ARITY_MANY /* 0, 1, ... , inf */ + }subcommand_arity; + /* A single subcommand. */ typedef struct subcommand subcommand; struct subcommand @@ -542,7 +549,7 @@ struct subcommand subcommand *next; /* Next in the chain. */ char *name; /* Subcommand name. */ subcommand_type type; /* One of SBC_*. */ - int once; /* 1=Subcommand may appear only once. */ + subcommand_arity arity; /* How many times should the subcommand occur*/ int narray; /* Index of next array element. */ const char *prefix; /* Prefix for variable and constant names. */ specifier *spec; /* Array of specifiers. */ @@ -759,6 +766,8 @@ parse_specifiers (subcommand *sbc) static void parse_subcommand (subcommand *sbc) { + sbc->arity = ARITY_MANY; + if (match_token ('*')) { if (def) @@ -766,7 +775,11 @@ parse_subcommand (subcommand *sbc) def = sbc; } - sbc->once = match_token ('+'); + if ( match_token('+')) + sbc->arity = ARITY_ONCE_ONLY ; + else if (match_token('^')) + sbc->arity = ARITY_ONCE_EXACTLY ; + force_id (); sbc->name = xstrdup (tokstr); @@ -1448,7 +1461,7 @@ dump_specifier_parse (const specifier *spec, const subcommand *sbc) if (s->value == VAL_INT) { - dump (1, "if (!lex_integer_p ())"); + dump (1, "if (!lex_is_integer ())"); dump (1, "{"); dump (0, "msg (SE, _(\"%s specifier of %s subcommand " "requires an integer argument.\"));", @@ -1460,7 +1473,7 @@ dump_specifier_parse (const specifier *spec, const subcommand *sbc) } else { - dump (1, "if (token != T_NUM)"); + dump (1, "if (!lex_is_number ())"); dump (1, "{"); dump (0, "msg (SE, _(\"Number expected after %s " "specifier of %s subcommand.\"));", @@ -1611,7 +1624,7 @@ dump_subcommand (const subcommand *sbc) { dump (0, "p->%sv_%s = parse_variable ();", st_lower (sbc->prefix), st_lower (sbc->name)); - dump (1, "if (p->%sv_%s)", + dump (1, "if (!p->%sv_%s)", st_lower (sbc->prefix), st_lower (sbc->name)); dump (0, "goto lossage;"); outdent (); @@ -1648,7 +1661,7 @@ dump_subcommand (const subcommand *sbc) { dump (1, "if (!lex_force_num ())"); dump (0, "goto lossage;"); - dump (-1, "p->n_%s[p->sbc_%s - 1] = lex_double ();", + dump (-1, "p->n_%s[p->sbc_%s - 1] = lex_number ();", st_lower (sbc->name), st_lower (sbc->name) ); dump (0, "lex_get();"); } @@ -1700,7 +1713,7 @@ dump_subcommand (const subcommand *sbc) dump (0, "goto lossage;"); dump (-1,"}"); - dump (0, "subc_list_double_push(&p->dl_%s[p->sbc_%s-1],lex_double ());", + dump (0, "subc_list_double_push(&p->dl_%s[p->sbc_%s-1],lex_number ());", st_lower (sbc->name),st_lower (sbc->name) ); @@ -1805,7 +1818,7 @@ dump_parser (int persistent) dump (0, "lex_match ('=');"); dump (0, "p->sbc_%s++;", st_lower (sbc->name)); - if (sbc->once) + if (sbc->arity != ARITY_MANY) { dump (1, "if (p->sbc_%s > 1)", st_lower (sbc->name)); dump (1, "{"); @@ -1820,6 +1833,8 @@ dump_parser (int persistent) outdent (); } } + + /* Now deal with the /ALGORITHM subcommand implicit to all commands */ dump(1,"else if ( get_syntax() != COMPATIBLE && lex_match_id(\"ALGORITHM\"))"); dump(1,"{"); @@ -1835,6 +1850,7 @@ dump_parser (int persistent) dump (-1, "}"); outdent (); + dump (1, "if (!lex_match ('/'))"); dump (0, "break;"); @@ -1847,6 +1863,29 @@ dump_parser (int persistent) dump (0, "goto lossage;"); dump (-1, "}"); dump (0, nullstr); + + outdent (); + + { + /* Check that mandatory subcommands have been specified */ + subcommand *sbc; + + for (sbc = subcommands; sbc; sbc = sbc->next) + { + + if ( sbc->arity == ARITY_ONCE_EXACTLY ) + { + dump (0, "if ( 0 == p->sbc_%s)", st_lower (sbc->name)); + dump (1, "{"); + dump (0, "msg (SE, _(\"%s subcommand must be given.\"));", + sbc->name); + dump (0, "goto lossage;"); + dump (-1, "}"); + dump (0, nullstr); + } + } + } + dump (-1, "return 1;"); dump (0, nullstr); dump (-1, "lossage:"); @@ -2022,11 +2061,6 @@ dump_header (void) dump (0, " Generated by q2c from %s on %s.", ifn, timep); dump (0, " Do not modify!"); dump (0, " */"); - - dump (0, nullstr); - dump (0, "#include \"settings.h\""); - dump (0, "#include \"subclist.h\""); - dump (0, nullstr); } /* Write out commands to free variable state. */ @@ -2063,11 +2097,17 @@ dump_free (int persistent) { switch (sbc->type) { + case SBC_VARLIST: + dump (0, "free (p->v_variables);"); + break; case SBC_STRING: dump (0, "free (p->s_%s);", st_lower (sbc->name)); break; case SBC_DBL_LIST: - dump (0, "subc_list_double_destroy(p->dl_%s);", st_lower (sbc->name)); + dump (0, "int i;"); + dump (1, "for(i = 0; i < MAXLISTS ; ++i)"); + dump (0, "subc_list_double_destroy(&p->dl_%s[i]);", st_lower (sbc->name)); + outdent(); break; default: break; @@ -2165,7 +2205,9 @@ main (int argc, char *argv[]) dump (0, "#include \"alloc.h\""); dump (0, "#include \"error.h\""); dump (0, "#include \"lexer.h\""); + dump (0, "#include \"settings.h\""); dump (0, "#include \"str.h\""); + dump (0, "#include \"subclist.h\""); dump (0, "#include \"var.h\""); dump (0, nullstr);