35 |
static size_t mh_code_number (int num); |
static size_t mh_code_number (int num); |
36 |
static size_t mh_code_builtin (mh_builtin_t *bp, int argtype); |
static size_t mh_code_builtin (mh_builtin_t *bp, int argtype); |
37 |
static void branch_fixup (size_t pc, size_t tgt); |
static void branch_fixup (size_t pc, size_t tgt); |
38 |
|
|
39 |
/* Lexical tie-ins */ |
/* Lexical tie-ins */ |
40 |
static int in_escape; /* Set when inside an escape sequence */ |
static int in_escape; /* Set when inside an escape sequence */ |
41 |
static int want_function; /* Set when expecting function name */ |
static int want_function; /* Set when expecting function name */ |
61 |
%token BOGUS |
%token BOGUS |
62 |
%type <type> cond_expr component funcall item argument escape literal |
%type <type> cond_expr component funcall item argument escape literal |
63 |
%type <elif_list> elif_part elif_list fi |
%type <elif_list> elif_part elif_list fi |
64 |
%type <pc> cond end else elif else_part |
%type <pc> cond end else elif else_part zlist list pitem |
65 |
%type <builtin> function |
%type <builtin> function |
66 |
|
|
67 |
%% |
%% |
68 |
|
|
69 |
input : list |
input : list |
70 |
|
{ |
71 |
|
/* nothing: to shut bison up */ |
72 |
|
} |
73 |
; |
; |
74 |
|
|
75 |
list : pitem |
list : pitem |
97 |
yyerror ("UNEXPECTED item TYPE"); |
yyerror ("UNEXPECTED item TYPE"); |
98 |
abort (); |
abort (); |
99 |
} |
} |
100 |
|
$$ = pc; |
101 |
} |
} |
102 |
; |
; |
103 |
|
|
215 |
| escape |
| escape |
216 |
; |
; |
217 |
|
|
218 |
/* 1 2 3 4 5 6 7 */ |
/* 1 2 3 4 5 6 7 */ |
219 |
cntl : if cond list end elif_part else_part fi |
cntl : if cond zlist end elif_part else_part fi |
220 |
{ |
{ |
221 |
size_t start_pc = 0, end_pc = 0; |
size_t start_pc = 0, end_pc = 0; |
222 |
|
|
248 |
} |
} |
249 |
; |
; |
250 |
|
|
251 |
|
zlist : /* empty */ |
252 |
|
{ |
253 |
|
$$ = pc; |
254 |
|
} |
255 |
|
| list |
256 |
|
; |
257 |
|
|
258 |
if : IF |
if : IF |
259 |
{ |
{ |
260 |
in_escape++; |
in_escape++; |
316 |
} |
} |
317 |
; |
; |
318 |
|
|
319 |
elif_list : elif cond list |
elif_list : elif cond zlist |
320 |
{ |
{ |
321 |
$$.cond = $1; |
$$.cond = $1; |
322 |
MHI_NUM(format.prog[$2]) = pc - $2 + 2; |
MHI_NUM(format.prog[$2]) = pc - $2 + 2; |
323 |
$$.end = 0; |
$$.end = 0; |
324 |
} |
} |
325 |
| elif_list end elif cond list |
| elif_list end elif cond zlist |
326 |
{ |
{ |
327 |
MHI_NUM(format.prog[$4]) = pc - $4 + 2; |
MHI_NUM(format.prog[$4]) = pc - $4 + 2; |
328 |
$$.cond = $1.cond; |
$$.cond = $1.cond; |
367 |
int |
int |
368 |
yylex () |
yylex () |
369 |
{ |
{ |
370 |
|
if (yydebug) |
371 |
|
fprintf (stderr, "[lex at %10.10s]\n", curp); |
372 |
if (*curp == '%') |
if (*curp == '%') |
373 |
{ |
{ |
374 |
curp++; |
curp++; |
471 |
{ |
{ |
472 |
curp -= rest; |
curp -= rest; |
473 |
yylval.builtin = bp; |
yylval.builtin = bp; |
474 |
|
while (*curp && isspace(*curp)) |
475 |
|
curp++; |
476 |
return FUNCTION; |
return FUNCTION; |
477 |
} |
} |
478 |
} |
} |
484 |
mh_format_parse (char *format_str, mh_format_t *fmt) |
mh_format_parse (char *format_str, mh_format_t *fmt) |
485 |
{ |
{ |
486 |
int rc; |
int rc; |
487 |
|
char *p = getenv ("MHFORMAT_DEBUG"); |
488 |
|
|
489 |
|
if (p) |
490 |
|
yydebug = 1; |
491 |
start = curp = format_str; |
start = curp = format_str; |
492 |
obstack_init (&stack); |
obstack_init (&stack); |
493 |
format.progsize = 0; |
format.progsize = 0; |
530 |
if (!prev) |
if (!prev) |
531 |
return; |
return; |
532 |
branch_fixup (prev, tgt); |
branch_fixup (prev, tgt); |
533 |
MHI_NUM(format.prog[prev]) = tgt - prev - 1; |
MHI_NUM(format.prog[prev]) = tgt - prev; |
534 |
} |
} |
535 |
|
|
536 |
|
|
605 |
case mhtype_num: |
case mhtype_num: |
606 |
mh_code_op (mhop_num_to_arg); |
mh_code_op (mhop_num_to_arg); |
607 |
break; |
break; |
608 |
|
|
609 |
case mhtype_str: |
case mhtype_str: |
610 |
mh_code_op (mhop_str_to_arg); |
/* mhtype_none means that the argument was an escape, |
611 |
|
which has left its string value (if any) in the |
612 |
|
arg_str register. Therefore, there's no need to |
613 |
|
code mhop_str_to_arg */ |
614 |
break; |
break; |
615 |
|
|
616 |
default: |
default: |
617 |
yyerror ("UNKNOWN ARGTYPE"); |
yyerror ("UNKNOWN ARGTYPE"); |
618 |
abort (); |
abort (); |
631 |
case mhtype_none: |
case mhtype_none: |
632 |
mh_error ("extra arguments to %s", bp->name); |
mh_error ("extra arguments to %s", bp->name); |
633 |
return 0; |
return 0; |
634 |
|
|
635 |
case mhtype_num: |
case mhtype_num: |
636 |
mh_code_op (mhop_str_to_num); |
mh_code_op (mhop_str_to_num); |
637 |
break; |
break; |
638 |
|
|
639 |
case mhtype_str: |
case mhtype_str: |
640 |
mh_code_op (mhop_num_to_str); |
mh_code_op (mhop_num_to_str); |
641 |
break; |
break; |
642 |
} |
} |
643 |
} |
} |
644 |
} |
} |
645 |
|
|
646 |
mh_code_op (mhop_call); |
mh_code_op (mhop_call); |
647 |
MHI_BUILTIN(instr) = bp->fun; |
MHI_BUILTIN(instr) = bp->fun; |
648 |
mh_code (&instr); |
mh_code (&instr); |