5 * Intermediate Code Compiler for Parrot.
7 * Copyright (C) 2002 Melvin Smith <melvin.smith@mindspring.com>
8 * Copyright (C) 2002-2008, The Perl Foundation.
10 * Grammar of the PIR language parser.
23 #include "parrot/dynext.h"
26 #include "optimizer.h"
29 # define YYENABLE_NLS 0
32 #ifndef YYLTYPE_IS_TRIVIAL
33 # define YYLTYPE_IS_TRIVIAL 0
36 /* HEADERIZER HFILE: compilers/imcc/imc.h */
38 /* HEADERIZER BEGIN: static */
39 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
41 static void add_pcc_named_arg
(PARROT_INTERP
,
42 ARGMOD
(SymReg
*cur_call
),
43 ARGIN
(const char *name
),
45 __attribute__nonnull__
(1)
46 __attribute__nonnull__
(2)
47 __attribute__nonnull__
(3)
48 __attribute__nonnull__
(4)
49 FUNC_MODIFIES
(*cur_call
);
51 static void add_pcc_named_param
(PARROT_INTERP
,
52 ARGMOD
(SymReg
*cur_call
),
53 ARGIN
(const char *name
),
55 __attribute__nonnull__
(1)
56 __attribute__nonnull__
(2)
57 __attribute__nonnull__
(3)
58 __attribute__nonnull__
(4)
59 FUNC_MODIFIES
(*cur_call
);
61 static void add_pcc_named_result
(PARROT_INTERP
,
62 ARGMOD
(SymReg
*cur_call
),
63 ARGIN
(const char *name
),
65 __attribute__nonnull__
(1)
66 __attribute__nonnull__
(2)
67 __attribute__nonnull__
(3)
68 __attribute__nonnull__
(4)
69 FUNC_MODIFIES
(*cur_call
);
71 static void add_pcc_named_return
(PARROT_INTERP
,
72 ARGMOD
(SymReg
*cur_call
),
73 ARGIN
(const char *name
),
75 __attribute__nonnull__
(1)
76 __attribute__nonnull__
(2)
77 __attribute__nonnull__
(3)
78 __attribute__nonnull__
(4)
79 FUNC_MODIFIES
(*cur_call
);
81 static void adv_named_set
(PARROT_INTERP
, ARGIN
(char *name
))
82 __attribute__nonnull__
(1)
83 __attribute__nonnull__
(2);
85 static void begin_return_or_yield
(PARROT_INTERP
, int yield
)
86 __attribute__nonnull__
(1);
88 static void clear_state
(PARROT_INTERP
)
89 __attribute__nonnull__
(1);
91 static void do_loadlib
(PARROT_INTERP
, ARGIN
(const char *lib
))
92 __attribute__nonnull__
(1)
93 __attribute__nonnull__
(2);
95 PARROT_WARN_UNUSED_RESULT
96 PARROT_CAN_RETURN_NULL
97 static Instruction
* func_ins
(PARROT_INTERP
,
98 ARGMOD
(IMC_Unit
*unit
),
100 ARGIN
(const char *op
),
105 __attribute__nonnull__
(1)
106 __attribute__nonnull__
(2)
107 __attribute__nonnull__
(3)
108 __attribute__nonnull__
(4)
109 __attribute__nonnull__
(5)
113 PARROT_CAN_RETURN_NULL
114 static Instruction
* iINDEXFETCH
(PARROT_INTERP
,
115 ARGMOD
(IMC_Unit
*unit
),
119 __attribute__nonnull__
(1)
120 __attribute__nonnull__
(2)
121 __attribute__nonnull__
(3)
122 __attribute__nonnull__
(4)
123 __attribute__nonnull__
(5)
124 FUNC_MODIFIES
(*unit
);
126 PARROT_CAN_RETURN_NULL
127 static Instruction
* iINDEXSET
(PARROT_INTERP
,
128 ARGMOD
(IMC_Unit
*unit
),
132 __attribute__nonnull__
(1)
133 __attribute__nonnull__
(2)
134 __attribute__nonnull__
(3)
135 __attribute__nonnull__
(4)
136 __attribute__nonnull__
(5)
137 FUNC_MODIFIES
(*unit
);
139 PARROT_CANNOT_RETURN_NULL
140 static Instruction
* iLABEL
(PARROT_INTERP
,
141 ARGMOD_NULLOK
(IMC_Unit
*unit
),
143 __attribute__nonnull__
(1)
144 __attribute__nonnull__
(3)
147 PARROT_WARN_UNUSED_RESULT
148 PARROT_CAN_RETURN_NULL
149 static const char * inv_op
(ARGIN
(const char *op
))
150 __attribute__nonnull__
(1);
152 PARROT_CANNOT_RETURN_NULL
153 static Instruction
* iSUBROUTINE
(PARROT_INTERP
,
154 ARGMOD_NULLOK
(IMC_Unit
*unit
),
156 __attribute__nonnull__
(1)
157 __attribute__nonnull__
(3)
160 PARROT_IGNORABLE_RESULT
161 PARROT_CAN_RETURN_NULL
162 static Instruction
* MK_I
(PARROT_INTERP
,
163 ARGMOD
(IMC_Unit
*unit
),
164 ARGIN
(const char *fmt
),
167 __attribute__nonnull__
(1)
168 __attribute__nonnull__
(2)
169 __attribute__nonnull__
(3)
170 FUNC_MODIFIES
(*unit
);
172 PARROT_WARN_UNUSED_RESULT
173 PARROT_CAN_RETURN_NULL
174 static Instruction
* mk_pmc_const
(PARROT_INTERP
,
175 ARGMOD
(IMC_Unit
*unit
),
176 ARGIN
(const char *type
),
177 ARGMOD
(SymReg
*left
),
178 ARGIN
(const char *constant
))
179 __attribute__nonnull__
(1)
180 __attribute__nonnull__
(2)
181 __attribute__nonnull__
(3)
182 __attribute__nonnull__
(4)
183 __attribute__nonnull__
(5)
185 FUNC_MODIFIES
(*left
);
187 PARROT_CANNOT_RETURN_NULL
188 static SymReg
* mk_sub_address_fromc
(PARROT_INTERP
, ARGIN
(const char *name
))
189 __attribute__nonnull__
(1)
190 __attribute__nonnull__
(2);
192 PARROT_CANNOT_RETURN_NULL
193 static SymReg
* mk_sub_address_u
(PARROT_INTERP
, ARGIN
(const char *name
))
194 __attribute__nonnull__
(1)
195 __attribute__nonnull__
(2);
197 static void set_lexical
(PARROT_INTERP
,
199 ARGIN
(const char *name
))
200 __attribute__nonnull__
(1)
201 __attribute__nonnull__
(2)
202 __attribute__nonnull__
(3)
205 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
206 /* HEADERIZER END: static */
210 #define YYERROR_VERBOSE 1
213 * We use a pure parser with the interpreter as a parameter. However this still
214 * doesn't make the parser reentrant, as there are too many globals around.
218 * Choosing instructions for Parrot is pretty easy since many are
224 * MK_I: build and emitb instruction by INS
227 * op %s, %s # comment
232 * NOTE: Most usage of this function is with
233 * IMCC_INFO(interp)->cur_unit, but there are some
234 * exceptions. Thus, we can't easily factorize that piece of
238 PARROT_IGNORABLE_RESULT
239 PARROT_CAN_RETURN_NULL
241 MK_I
(PARROT_INTERP
, ARGMOD
(IMC_Unit
*unit
), ARGIN
(const char *fmt
), int n
, ...
)
247 SymReg
*r
[IMCC_MAX_FIX_REGS
];
250 for
(p
= opname
, q
= fmt
; *q
&& *q
!= ' ';)
258 fprintf
(stderr
, "op '%s' format '%s' (%d)\n", opname
, fmt?
:"", n
);
262 for
(i
= 0; i
< n
; ++i
) {
263 r
[i
] = va_arg
(ap
, SymReg
*);
266 return INS
(interp
, unit
, opname
, fmt
, r
, n
,
267 IMCC_INFO
(interp
)->keyvec
, 1);
270 PARROT_WARN_UNUSED_RESULT
271 PARROT_CAN_RETURN_NULL
273 mk_pmc_const
(PARROT_INTERP
, ARGMOD
(IMC_Unit
*unit
), ARGIN
(const char *type
),
274 ARGMOD
(SymReg
*left
), ARGIN
(const char *constant
))
276 const int type_enum
= atoi
(type
);
277 const int ascii
= (*constant
== '\'' ||
*constant
== '"');
282 if
(left
->type
== VTADDRESS
) { /* IDENTIFIER */
283 if
(IMCC_INFO
(interp
)->state
->pasm_file
) {
284 IMCC_fataly
(interp
, E_SyntaxError
,
285 "Ident as PMC constant",
286 " %s\n", left
->name
);
288 left
->type
= VTIDENTIFIER
;
293 /* strip delimiters */
294 name
= str_dup
(constant
+ 1);
295 name
[strlen
(name
) - 1] = '\0';
298 name
= str_dup
(constant
);
303 case enum_class_Coroutine
:
304 rhs
= mk_const
(interp
, name
, 'p');
307 rhs
->type |
= VT_ENCODED
;
309 rhs
->usage
= U_FIXUP
;
312 rhs
= mk_const
(interp
, name
, 'P');
317 rhs
->pmc_type
= type_enum
;
321 return INS
(interp
, unit
, "set_p_pc", "", r
, 2, 0, 1);
324 PARROT_WARN_UNUSED_RESULT
325 PARROT_CAN_RETURN_NULL
327 func_ins
(PARROT_INTERP
, ARGMOD
(IMC_Unit
*unit
), ARGIN
(SymReg
*lhs
), ARGIN
(const char *op
),
328 ARGMOD
(SymReg
**r
), int n
, int keyv
, int emit
)
331 /* shift regs up by 1 */
332 for
(i
= n
- 1; i
>= 0; --i
)
337 return INS
(interp
, unit
, op
, "", r
, n
+1, keyv
, emit
);
340 * special instructions
346 clear_state
(PARROT_INTERP
)
348 IMCC_INFO
(interp
) -> nargs
= 0;
349 IMCC_INFO
(interp
) -> keyvec
= 0;
352 PARROT_CANNOT_RETURN_NULL
354 INS_LABEL
(PARROT_INTERP
, ARGMOD_NULLOK
(IMC_Unit
*unit
), ARGMOD
(SymReg
*r0
), int emit
)
357 Instruction
* const ins
= _mk_instruction
("", "%s:", 1, &r0
, 0);
362 emitb
(interp
, unit
, ins
);
367 PARROT_CANNOT_RETURN_NULL
369 iLABEL
(PARROT_INTERP
, ARGMOD_NULLOK
(IMC_Unit
*unit
), ARGMOD
(SymReg
*r0
))
371 Instruction
* const i
= INS_LABEL
(interp
, unit
, r0
, 1);
372 i
->line
= IMCC_INFO
(interp
)->line
;
378 PARROT_CANNOT_RETURN_NULL
380 iSUBROUTINE
(PARROT_INTERP
, ARGMOD_NULLOK
(IMC_Unit
*unit
), ARGMOD
(SymReg
*r
))
382 Instruction
* const i
= iLABEL
(interp
, unit
, r
);
384 r
->type
= (r
->type
& VT_ENCODED
) ? VT_PCC_SUB|VT_ENCODED
: VT_PCC_SUB
;
385 r
->pcc_sub
= mem_allocate_zeroed_typed
(pcc_sub_t
);
387 IMCC_INFO
(interp
)->cur_call
= r
;
388 i
->line
= IMCC_INFO
(interp
)->line
;
390 add_namespace
(interp
, unit
);
395 * substr or X = P[key]
397 PARROT_CAN_RETURN_NULL
399 iINDEXFETCH
(PARROT_INTERP
, ARGMOD
(IMC_Unit
*unit
), ARGIN
(SymReg
*r0
), ARGIN
(SymReg
*r1
),
402 if
(r0
->set
== 'S' && r1
->set
== 'S' && r2
->set
== 'I') {
403 SymReg
* const r3
= mk_const
(interp
, "1", 'I');
404 return MK_I
(interp
, unit
, "substr %s, %s, %s, 1", 4, r0
, r1
, r2
, r3
);
407 IMCC_INFO
(interp
) -> keyvec |
= KEY_BIT
(2);
408 return MK_I
(interp
, unit
, "set %s, %s[%s]", 3, r0
, r1
, r2
);
412 * substr or P[key] = X
415 PARROT_CAN_RETURN_NULL
417 iINDEXSET
(PARROT_INTERP
, ARGMOD
(IMC_Unit
*unit
), ARGIN
(SymReg
*r0
), ARGIN
(SymReg
*r1
),
420 if
(r0
->set
== 'S' && r1
->set
== 'I' && r2
->set
== 'S') {
421 SymReg
* const r3
= mk_const
(interp
, "1", 'I');
422 MK_I
(interp
, unit
, "substr %s, %s, %s, %s", 4, r0
, r1
, r3
, r2
);
424 else if
(r0
->set
== 'P') {
425 IMCC_INFO
(interp
)->keyvec |
= KEY_BIT
(1);
426 MK_I
(interp
, unit
, "set %s[%s], %s", 3, r0
, r1
, r2
);
429 IMCC_fataly
(interp
, E_SyntaxError
,
430 "unsupported indexed set op\n");
435 PARROT_WARN_UNUSED_RESULT
436 PARROT_CAN_RETURN_NULL
438 inv_op
(ARGIN
(const char *op
))
441 return get_neg_op
(op
, &n
);
444 PARROT_CANNOT_RETURN_NULL
446 IMCC_create_itcall_label
(PARROT_INTERP
)
452 snprintf
(name
, sizeof
(name
), "%cpcc_sub_call_%d", IMCC_INTERNAL_CHAR
,
453 IMCC_INFO
(interp
)->cnr
++);
455 r
= mk_pcc_sub
(interp
, name
, 0);
456 i
= iLABEL
(interp
, IMCC_INFO
(interp
)->cur_unit
, r
);
457 i
->type
= ITCALL | ITPCCSUB
;
459 IMCC_INFO
(interp
)->cur_call
= r
;
464 PARROT_CANNOT_RETURN_NULL
466 mk_sub_address_fromc
(PARROT_INTERP
, ARGIN
(const char *name
))
468 /* name is a quoted sub name */
470 char *name_copy
= str_dup
(name
+ 1);
471 name_copy
[strlen
(name_copy
) - 1] = '\0';
473 r
= mk_sub_address
(interp
, name_copy
);
474 mem_sys_free
(name_copy
);
479 PARROT_CANNOT_RETURN_NULL
481 mk_sub_address_u
(PARROT_INTERP
, ARGIN
(const char *name
))
483 SymReg
* const r
= mk_sub_address
(interp
, name
);
484 r
->type |
= VT_ENCODED
;
490 IMCC_itcall_sub
(PARROT_INTERP
, ARGIN
(SymReg
*sub
))
492 IMCC_INFO
(interp
)->cur_call
->pcc_sub
->sub
= sub
;
493 if
(IMCC_INFO
(interp
)->cur_obj
) {
494 if
(IMCC_INFO
(interp
)->cur_obj
->set
!= 'P')
495 IMCC_fataly
(interp
, E_SyntaxError
, "object isn't a PMC");
496 IMCC_INFO
(interp
)->cur_call
->pcc_sub
->object
= IMCC_INFO
(interp
)->cur_obj
;
497 IMCC_INFO
(interp
)->cur_obj
= NULL
;
499 if
(IMCC_INFO
(interp
)->cur_call
->pcc_sub
->sub
->pmc_type
== enum_class_NCI
)
500 IMCC_INFO
(interp
)->cur_call
->pcc_sub
->flags |
= isNCI
;
501 if
(IMCC_INFO
(interp
)->cur_unit
->type
== IMC_PCCSUB
)
502 IMCC_INFO
(interp
)->cur_unit
->instructions
->symregs
[0]->pcc_sub
->calls_a_sub |
= 1;
506 begin_return_or_yield
(PARROT_INTERP
, int yield
)
509 Instruction
* const ins
= IMCC_INFO
(interp
)->cur_unit
->instructions
;
512 if
(!ins ||
!ins
->symregs
[0] ||
!(ins
->symregs
[0]->type
& VT_PCC_SUB
))
513 IMCC_fataly
(interp
, E_SyntaxError
,
514 "yield or return directive outside pcc subroutine\n");
516 ins
->symregs
[0]->pcc_sub
->calls_a_sub
= 1 | ITPCCYIELD
;
517 snprintf
(name
, sizeof
(name
), yield ?
"%cpcc_sub_yield_%d" : "%cpcc_sub_ret_%d",
518 IMCC_INTERNAL_CHAR
, IMCC_INFO
(interp
)->cnr
++);
519 interp
->imc_info
->sr_return
= mk_pcc_sub
(interp
, name
, 0);
520 i
= iLABEL
(interp
, IMCC_INFO
(interp
)->cur_unit
, interp
->imc_info
->sr_return
);
521 i
->type
= yield ? ITPCCSUB | ITLABEL | ITPCCYIELD
: ITPCCSUB | ITLABEL
;
522 interp
->imc_info
->asm_state
= yield ? AsmInYield
: AsmInReturn
;
526 set_lexical
(PARROT_INTERP
, ARGMOD
(SymReg
*r
), ARGIN
(const char *name
))
528 SymReg
* const n
= mk_const
(interp
, name
, 'S');
530 r
->usage |
= U_LEXICAL
;
533 IMCC_fataly
(interp
, E_SyntaxError
,
534 "register %s already declared as lexical %s", r
->name
, n
->name
);
536 /* chain all names in r->reg */
543 add_pcc_named_arg
(PARROT_INTERP
, ARGMOD
(SymReg
*cur_call
), ARGIN
(const char *name
),
544 ARGIN
(SymReg
*value
))
546 SymReg
* const r
= mk_const
(interp
, name
, 'S');
550 add_pcc_arg
(cur_call
, r
);
551 add_pcc_arg
(cur_call
, value
);
555 add_pcc_named_result
(PARROT_INTERP
, ARGMOD
(SymReg
*cur_call
), ARGIN
(const char *name
),
556 ARGIN
(SymReg
*value
))
558 SymReg
* const r
= mk_const
(interp
, name
, 'S');
561 add_pcc_result
(cur_call
, r
);
562 add_pcc_result
(cur_call
, value
);
566 add_pcc_named_param
(PARROT_INTERP
, ARGMOD
(SymReg
*cur_call
), ARGIN
(const char *name
),
567 ARGIN
(SymReg
*value
))
569 SymReg
* const r
= mk_const
(interp
, name
, 'S');
572 add_pcc_arg
(cur_call
, r
);
573 add_pcc_arg
(cur_call
, value
);
577 add_pcc_named_return
(PARROT_INTERP
, ARGMOD
(SymReg
*cur_call
), ARGIN
(const char *name
),
578 ARGIN
(SymReg
*value
))
580 SymReg
* const r
= mk_const
(interp
, name
, 'S');
583 add_pcc_result
(cur_call
, r
);
584 add_pcc_result
(cur_call
, value
);
587 /* XXX Can name be consted? */
589 adv_named_set
(PARROT_INTERP
, ARGIN
(char *name
))
591 if
(IMCC_INFO
(interp
)->adv_named_id
) {
592 IMCC_fataly
(interp
, E_SyntaxError
,
593 "Named parameter with more than one name.\n");
595 IMCC_INFO
(interp
)->adv_named_id
= name
;
599 do_loadlib
(PARROT_INTERP
, ARGIN
(const char *lib
))
601 STRING
* const s
= string_unescape_cstring
(interp
, lib
+ 1, '"', NULL
);
602 PMC
*ignored
= Parrot_load_lib
(interp
, s
, NULL
);
604 Parrot_register_HLL_lib
(interp
, s
);
607 /* HEADERIZER STOP */
619 /* We need precedence for a few tokens to resolve a couple of conflicts */
624 %token
<t
> PRAGMA N_OPERATORS HLL HLL_MAP
625 %token
<t
> GOTO ARG IF UNLESS PNULL
626 %token
<t
> ADV_FLAT ADV_SLURPY ADV_OPTIONAL ADV_OPT_FLAG ADV_NAMED ADV_ARROW
627 %token
<t
> NEW ADV_INVOCANT
628 %token
<t
> NAMESPACE ENDNAMESPACE DOT_METHOD
629 %token
<t
> SUB SYM LOCAL LEXICAL CONST
630 %token
<t
> INC DEC GLOBAL_CONST
631 %token
<t
> PLUS_ASSIGN MINUS_ASSIGN MUL_ASSIGN DIV_ASSIGN CONCAT_ASSIGN
632 %token
<t
> BAND_ASSIGN BOR_ASSIGN BXOR_ASSIGN FDIV FDIV_ASSIGN MOD_ASSIGN
633 %token
<t
> SHR_ASSIGN SHL_ASSIGN SHR_U_ASSIGN
634 %token
<t
> SHIFT_LEFT SHIFT_RIGHT INTV FLOATV STRINGV PMCV LOG_XOR
635 %token
<t
> RELOP_EQ RELOP_NE RELOP_GT RELOP_GTE RELOP_LT RELOP_LTE
636 %token
<t
> GLOBAL GLOBALOP ADDR RESULT RETURN YIELDT GET_RESULTS
637 %token
<t
> POW SHIFT_RIGHT_U LOG_AND LOG_OR
638 %token
<t
> COMMA ESUB DOTDOT
639 %token
<t
> PCC_BEGIN PCC_END PCC_CALL PCC_SUB PCC_BEGIN_RETURN PCC_END_RETURN
640 %token
<t
> PCC_BEGIN_YIELD PCC_END_YIELD NCI_CALL METH_CALL INVOCANT
641 %token
<t
> MAIN LOAD INIT IMMEDIATE POSTCOMP METHOD ANON OUTER NEED_LEX
642 %token
<t
> MULTI VTABLE_METHOD LOADLIB SUB_INSTANCE_OF SUB_LEXID
643 %token
<t
> UNIQUE_REG
646 %token
<s
> IREG NREG SREG PREG IDENTIFIER REG MACRO ENDM
647 %token
<s
> STRINGC INTC FLOATC USTRINGC
649 %type
<t
> type pragma_1 hll_def return_or_yield comma_or_goto opt_unique_reg
651 %type
<i
> class_namespace
652 %type
<i
> constdef sub emit pcc_ret pcc_yield
653 %type
<i
> compilation_units compilation_unit pmc_const pragma
654 %type
<s
> classname relop any_string assign_op bin_op un_op
655 %type
<i
> labels _labels label statement sub_call
656 %type
<i
> pcc_sub_call
657 %type
<sr
> sub_param sub_params pcc_arg pcc_result pcc_args pcc_results sub_param_type_def
658 %type
<sr
> pcc_returns pcc_return pcc_call arg arglist the_sub multi_type
659 %type
<t
> argtype_list argtype paramtype_list paramtype
660 %type
<t
> pcc_return_many
661 %type
<t
> proto sub_proto sub_proto_list multi multi_types outer
662 %type
<t
> vtable instanceof lexid
663 %type
<i
> instruction assignment conditional_statement labeled_inst opt_label op_assign
664 %type
<i
> if_statement unless_statement
665 %type
<i
> func_assign get_results
666 %type
<i
> opt_invocant
667 %type
<sr
> target targetlist reg
const var
string result
668 %type
<sr
> keylist keylist_force _keylist key maybe_ns
669 %type
<sr
> vars _vars var_or_i _var_or_i label_op sub_label_op sub_label_op_c
670 %type
<i
> pasmcode pasmline pasm_inst
672 %type
<i
> var_returns
675 %token
<t
> LINECOMMENT
676 %token
<s
> FILECOMMENT
677 %type
<idlist
> id_list id_list_id
685 /* Note that we pass interp last, because Bison only passes
686 the last param to yyerror(). (Tested on bison <= 2.3)
688 %parse
-param
{void *yyscanner
}
689 %lex
-param
{void *yyscanner
}
690 %parse
-param
{Parrot_Interp interp
}
691 %lex
-param
{Parrot_Interp interp
}
695 /* In effort to make the grammar readable but not militaristic, please space indent
696 code blocks on 10 col boundaries and keep indentation same for all code blocks
697 in a rule. Indent rule tokens | and ; to 4th col and sub rules 6th col
703 compilation_units
{ if
(yynerrs) YYABORT; $$
= 0; }
708 | compilation_units compilation_unit
712 class_namespace
{ $$
= $1; }
713 | constdef
{ $$
= $1; }
717 imc_close_unit
(interp
, IMCC_INFO
(interp
)->cur_unit
);
718 IMCC_INFO
(interp
)->cur_unit
= 0;
723 imc_close_unit
(interp
, IMCC_INFO
(interp
)->cur_unit
);
724 IMCC_INFO
(interp
)->cur_unit
= 0;
726 | MACRO
'\n' { $$
= 0; }
732 PRAGMA pragma_1
'\n' { $$
= 0; }
733 | hll_def
'\n' { $$
= 0; }
734 | LOADLIB STRINGC
'\n'
737 do_loadlib
(interp
, $2);
746 IMCC_INFO
(interp
)->state
->pragmas |
= PR_N_OPERATORS
;
748 IMCC_INFO
(interp
)->state
->pragmas
&= ~PR_N_OPERATORS
;
753 HLL STRINGC COMMA STRINGC
755 STRING
* const hll_name
= string_unescape_cstring
(interp
, $2 + 1, '"', NULL
);
756 CONTEXT
(interp
)->current_HLL
=
757 Parrot_register_HLL
(interp
, hll_name
);
759 /* don't bother loading the library for an empty string */
760 if
(strlen
($4) > 2) {
761 STRING
* const hll_lib
=
762 string_unescape_cstring
(interp
, $4 + 1, '"', NULL
);
763 PMC
*ignored
= Parrot_load_lib
(interp
, hll_lib
, NULL
);
765 Parrot_register_HLL_lib
(interp
, hll_lib
);
768 IMCC_INFO
(interp
)->cur_namespace
= NULL
;
771 | HLL_MAP STRINGC COMMA STRINGC
773 Parrot_Context
*ctx
= CONTEXT
(interp
);
774 STRING
* const built_in_name
=
775 string_unescape_cstring
(interp
, $2 + 1, '"', NULL
);
776 STRING
* const language_name
=
777 string_unescape_cstring
(interp
, $4 + 1, '"', NULL
);
779 int built_in_type
= pmc_type
(interp
, built_in_name
);
780 int language_type
= pmc_type
(interp
, language_name
);
782 Parrot_register_HLL_type
(interp
, ctx
->current_HLL
,
783 built_in_type
, language_type
);
789 CONST
{ is_def
= 1; } type IDENTIFIER
'=' const
791 mk_const_ident
(interp
, $4, $3, $6, 1);
798 CONST
{ is_def
=1; } INTC var_or_i
'=' any_string
800 $$
= mk_pmc_const
(interp
, IMCC_INFO
(interp
)->cur_unit
, $3, $4, $6);
815 labels pasm_inst
'\n' { $$
= 0; }
816 | MACRO
'\n' { $$
= 0; }
817 | FILECOMMENT
{ $$
= 0; }
818 | LINECOMMENT
{ $$
= 0; }
819 | class_namespace
{ $$
= $1; }
824 pasm_inst: { clear_state
(interp
); }
827 $$
= INS
(interp
, IMCC_INFO
(interp
)->cur_unit
,
828 $2, 0, IMCC_INFO
(interp
)->regs
,
829 IMCC_INFO
(interp
)->nargs
, IMCC_INFO
(interp
) -> keyvec
, 1);
830 /* XXX: can't seem to mem_sys_free($1) here */
834 imc_close_unit
(interp
, IMCC_INFO
(interp
)->cur_unit
);
835 IMCC_INFO
(interp
)->cur_unit
= imc_open_unit
(interp
, IMC_PASM
);
839 $$
= iSUBROUTINE
(interp
,
840 IMCC_INFO
(interp
)->cur_unit
,
841 mk_sub_label
(interp
, $4));
842 IMCC_INFO
(interp
)->cur_call
->pcc_sub
->pragma
= $3;
846 $$
= MK_I
(interp
, IMCC_INFO
(interp
)->cur_unit
, "null", 1, $2);
848 | LEXICAL STRINGC COMMA REG
850 SymReg
*r
= mk_pasm_reg
(interp
, $4);
851 set_lexical
(interp
, r
, $2);
856 |
/* none */ { $$
= 0;}
863 emit: /* EMIT and EOM tokens are used when compiling a .pasm file. */
864 EMIT
{ IMCC_INFO
(interp
)->cur_unit
= imc_open_unit
(interp
, IMC_PASM
); }
868 /* if (optimizer_level & OPT_PASM)
869 imc_compile_unit(interp, IMCC_INFO(interp)->cur_unit);
882 NAMESPACE maybe_ns
'\n'
886 if
(IMCC_INFO
(interp
)->state
->pasm_file
&& IMCC_INFO
(interp
)->cur_namespace
) {
887 imc_close_unit
(interp
, IMCC_INFO
(interp
)->cur_unit
);
890 IMCC_INFO
(interp
)->cur_namespace
= $2;
892 IMCC_INFO
(interp
)->cur_unit
= imc_open_unit
(interp
, IMC_PASM
);
897 '[' keylist
']' { $$
= $2; }
898 |
'[' ']' { $$
= NULL
; }
905 IMCC_INFO
(interp
)->cur_unit
= imc_open_unit
(interp
, IMC_PCCSUB
);
909 iSUBROUTINE
(interp
, IMCC_INFO
(interp
)->cur_unit
, $3);
911 sub_proto
'\n' { IMCC_INFO
(interp
)->cur_call
->pcc_sub
->pragma
= $5; }
913 sub_body ESUB
{ $$
= 0; IMCC_INFO
(interp
)->cur_call
= NULL
; }
917 /* empty */ { $$
= 0; } %prec LOW_PREC
919 | sub_params sub_param
'\n'
921 if
(IMCC_INFO
(interp
)->adv_named_id
) {
922 add_pcc_named_param
(interp
, IMCC_INFO
(interp
)->cur_call
,
923 IMCC_INFO
(interp
)->adv_named_id
, $2);
924 IMCC_INFO
(interp
)->adv_named_id
= NULL
;
927 add_pcc_arg
(IMCC_INFO
(interp
)->cur_call
, $2);
932 PARAM
{ is_def
=1; } sub_param_type_def
{ $$
= $3; is_def
=0; }
936 type IDENTIFIER paramtype_list
938 if
($3 & VT_UNIQUE_REG
)
939 $$
= mk_ident_ur
(interp
, $2, $1);
941 $$
= mk_ident
(interp
, $2, $1);
946 /* don't free $2 here; adv_named_set uses the pointer directly */
947 | type STRINGC ADV_ARROW IDENTIFIER paramtype_list
949 if
($5 & VT_UNIQUE_REG
)
950 $$
= mk_ident_ur
(interp
, $4, $1);
952 $$
= mk_ident
(interp
, $4, $1);
954 adv_named_set
(interp
, $2);
962 MULTI
'(' multi_types
')' { $$
= 0; }
966 OUTER
'(' STRINGC
')'
969 IMCC_INFO
(interp
)->cur_unit
->outer
= mk_sub_address_fromc
(interp
, $3);
972 | OUTER
'(' IDENTIFIER
')'
975 IMCC_INFO
(interp
)->cur_unit
->outer
= mk_const
(interp
, $3, 'S');
984 IMCC_INFO
(interp
)->cur_unit
->vtable_name
= NULL
;
985 IMCC_INFO
(interp
)->cur_unit
->is_vtable_method
= 1;
987 | VTABLE_METHOD
'(' STRINGC
')'
990 IMCC_INFO
(interp
)->cur_unit
->vtable_name
= $3;
991 IMCC_INFO
(interp
)->cur_unit
->is_vtable_method
= 1;
996 SUB_INSTANCE_OF
'(' STRINGC
')'
999 IMCC_INFO
(interp
)->cur_unit
->instance_of
= mk_const
(interp
, $3, 'S');
1005 SUB_LEXID
'(' STRINGC
')'
1008 IMCC_INFO
(interp
)->cur_unit
->lexid
= $3;
1015 add_pcc_multi
(IMCC_INFO
(interp
)->cur_call
, NULL
);
1017 | multi_types COMMA multi_type
1020 add_pcc_multi
(IMCC_INFO
(interp
)->cur_call
, $3);
1025 add_pcc_multi
(IMCC_INFO
(interp
)->cur_call
, $1);
1030 INTV
{ $$
= mk_const
(interp
, "INTVAL", 'S'); }
1031 | FLOATV
{ $$
= mk_const
(interp
, "FLOATVAL", 'S'); }
1032 | PMCV
{ $$
= mk_const
(interp
, "PMC", 'S'); }
1033 | STRINGV
{ $$
= mk_const
(interp
, "STRING", 'S'); }
1037 if
(strcmp
($1, "_") != 0)
1038 r
= mk_const
(interp
, $1, 'S');
1040 r
= mk_const
(interp
, "PMC", 'S');
1048 if
(strcmp
($1, "_") != 0)
1049 r
= mk_const
(interp
, $1, 'S');
1051 r
= mk_const
(interp
, "PMC", 'S');
1056 |
'[' keylist
']' { $$
= $2; }
1071 snprintf
(name
, sizeof
(name
), "%cpcc_sub_call_%d",
1072 IMCC_INTERNAL_CHAR
, IMCC_INFO
(interp
)->cnr
++);
1073 $
<sr
>$
= r
= mk_pcc_sub
(interp
, name
, 0);
1074 /* this mid rule action has the semantic value of the
1076 * This is used below to append args & results
1078 i
= iLABEL
(interp
, IMCC_INFO
(interp
)->cur_unit
, r
);
1079 IMCC_INFO
(interp
)->cur_call
= r
;
1082 * if we are inside a pcc_sub mark the sub as doing a
1083 * sub call; the sub is in r[0] of the first ins
1085 r1
= IMCC_INFO
(interp
)->cur_unit
->instructions
->symregs
[0];
1086 if
(r1
&& r1
->pcc_sub
)
1087 r1
->pcc_sub
->calls_a_sub |
= 1;
1094 PCC_END
{ $$
= 0; IMCC_INFO
(interp
)->cur_call
= NULL
; }
1098 /* empty */ { $$
= NULL
; IMCC_INFO
(interp
)->cur_call
->pcc_sub
->label
= 0; }
1099 | label
'\n' { $$
= NULL
; IMCC_INFO
(interp
)->cur_call
->pcc_sub
->label
= 1; }
1103 /* empty */ { $$
= NULL
; }
1104 | INVOCANT var
'\n' { $$
= NULL
; IMCC_INFO
(interp
)->cur_call
->pcc_sub
->object
= $2; }
1108 /* empty */ { $$
= 0; }
1114 | sub_proto_list proto
{ $$
= $1 |
$2; }
1118 LOAD
{ $$
= P_LOAD
; }
1119 | INIT
{ $$
= P_INIT
; }
1120 | MAIN
{ $$
= P_MAIN
; }
1121 | IMMEDIATE
{ $$
= P_IMMEDIATE
; }
1122 | POSTCOMP
{ $$
= P_POSTCOMP
; }
1123 | ANON
{ $$
= P_ANON
; }
1124 | METHOD
{ $$
= P_METHOD
; }
1125 | NEED_LEX
{ $$
= P_NEED_LEX
; }
1134 PCC_CALL var COMMA var
'\n'
1136 add_pcc_sub
(IMCC_INFO
(interp
)->cur_call
, $2);
1137 add_pcc_cc
(IMCC_INFO
(interp
)->cur_call
, $4);
1141 add_pcc_sub
(IMCC_INFO
(interp
)->cur_call
, $2);
1145 add_pcc_sub
(IMCC_INFO
(interp
)->cur_call
, $2);
1146 IMCC_INFO
(interp
)->cur_call
->pcc_sub
->flags |
= isNCI
;
1148 | METH_CALL target
'\n'
1150 add_pcc_sub
(IMCC_INFO
(interp
)->cur_call
, $2);
1152 | METH_CALL STRINGC
'\n'
1154 add_pcc_sub
(IMCC_INFO
(interp
)->cur_call
, mk_const
(interp
, $2, 'S'));
1156 | METH_CALL target COMMA var
'\n'
1158 add_pcc_sub
(IMCC_INFO
(interp
)->cur_call
, $2);
1159 add_pcc_cc
(IMCC_INFO
(interp
)->cur_call
, $4);
1161 | METH_CALL STRINGC COMMA var
'\n'
1163 add_pcc_sub
(IMCC_INFO
(interp
)->cur_call
, mk_const
(interp
, $2, 'S'));
1164 add_pcc_cc
(IMCC_INFO
(interp
)->cur_call
, $4);
1170 /* empty */ { $$
= 0; }
1171 | pcc_args pcc_arg
'\n' { add_pcc_arg
(IMCC_INFO
(interp
)->cur_call
, $2); }
1175 ARG arg
{ $$
= $2; }
1180 /* empty */ { $$
= 0; }
1181 | pcc_results pcc_result
'\n'
1184 add_pcc_result
(IMCC_INFO
(interp
)->cur_call
, $2);
1189 RESULT target paramtype_list
{ $$
= $2; $$
->type |
= $3; }
1190 | LOCAL
{ is_def
=1; } type id_list_id
1195 ignored
= mk_ident_ur
(interp
, l
->id
, $3);
1197 ignored
= mk_ident
(interp
, l
->id
, $3);
1205 /* empty */ { $$
= 0; }
1206 | paramtype_list paramtype
{ $$
= $1 |
$2; }
1210 ADV_SLURPY
{ $$
= VT_FLAT
; }
1211 | ADV_OPTIONAL
{ $$
= VT_OPTIONAL
; }
1212 | ADV_OPT_FLAG
{ $$
= VT_OPT_FLAG
; }
1213 | ADV_NAMED
{ $$
= VT_NAMED
; }
1214 | ADV_NAMED
'(' STRINGC
')' { adv_named_set
(interp
, $3); $$
= 0; }
1215 | UNIQUE_REG
{ $$
= VT_UNIQUE_REG
; }
1220 PCC_BEGIN_RETURN
'\n'
1222 begin_return_or_yield
(interp
, 0);
1224 pcc_returns PCC_END_RETURN
1227 IMCC_INFO
(interp
)->asm_state
= AsmDefault
;
1231 IMCC_INFO
(interp
)->asm_state
= AsmDefault
;
1237 PCC_BEGIN_YIELD
'\n' { begin_return_or_yield
(interp
, 1); }
1239 PCC_END_YIELD
{ $$
= 0; IMCC_INFO
(interp
)->asm_state
= AsmDefault
; }
1243 /* empty */ { $$
= 0; }
1247 add_pcc_result
(IMCC_INFO
(interp
)->sr_return
, $1);
1249 | pcc_returns pcc_return
'\n'
1252 add_pcc_result
(IMCC_INFO
(interp
)->sr_return
, $2);
1257 RETURN var argtype_list
{ $$
= $2; $$
->type |
= $3; }
1263 if
(IMCC_INFO
(interp
)->asm_state
== AsmDefault
)
1264 begin_return_or_yield
(interp
, $1);
1268 IMCC_INFO
(interp
)->asm_state
= AsmDefault
;
1275 | YIELDT
{ $$
= 1; }
1279 /* empty */ { $$
= 0; }
1282 if
(IMCC_INFO
(interp
)->adv_named_id
) {
1283 add_pcc_named_return
(interp
, IMCC_INFO
(interp
)->sr_return
,
1284 IMCC_INFO
(interp
)->adv_named_id
, $1);
1285 IMCC_INFO
(interp
)->adv_named_id
= NULL
;
1288 add_pcc_result
(IMCC_INFO
(interp
)->sr_return
, $1);
1290 | STRINGC ADV_ARROW var
1292 add_pcc_named_return
(interp
, IMCC_INFO
(interp
)->sr_return
, $1, $3);
1294 | var_returns COMMA arg
1296 if
(IMCC_INFO
(interp
)->adv_named_id
) {
1297 add_pcc_named_return
(interp
, IMCC_INFO
(interp
)->sr_return
,
1298 IMCC_INFO
(interp
)->adv_named_id
, $3);
1299 IMCC_INFO
(interp
)->adv_named_id
= NULL
;
1302 add_pcc_result
(IMCC_INFO
(interp
)->sr_return
, $3);
1304 | var_returns COMMA STRINGC ADV_ARROW var
1306 add_pcc_named_return
(interp
, IMCC_INFO
(interp
)->sr_return
, $3, $5);
1313 | statements statement
1316 /* This is ugly. Because 'instruction' can start with PARAM and in the
1317 * 'pcc_sub' rule, 'pcc_params' is followed by 'statement', we get a
1318 * shift/reduce conflict on PARAM between reducing to the dummy
1319 * { clear_state(); } rule and shifting the PARAM to be used as part
1320 * of the 'pcc_params' (which is what we want). However, yacc syntax
1321 * doesn't propagate precedence to the dummy rules, so we have to
1322 * split out the action just so that we can assign it a precedence. */
1325 { clear_state
(interp
); } %prec LOW_PREC
1330 instruction
{ $$
= $2; }
1331 | MACRO
'\n' { $$
= 0; }
1332 | FILECOMMENT
{ $$
= 0; }
1333 | LINECOMMENT
{ $$
= 0; }
1337 /* none */ { $$
= NULL
; }
1349 $$
= iLABEL
(interp
, IMCC_INFO
(interp
)->cur_unit
, mk_local_label
(interp
, $1));
1356 labels labeled_inst
'\n' { $$
= $2; }
1359 if
(yynerrs >= PARROT_MAX_RECOVER_ERRORS
) {
1360 IMCC_warning
(interp
, "Too many errors. Correct some first.\n");
1375 | id_list COMMA id_list_id
1384 IDENTIFIER opt_unique_reg
1386 IdList
* const l
= mem_allocate_n_zeroed_typed
(1, IdList
);
1394 /* empty */ { $$
= 0; }
1395 | UNIQUE_REG
{ $$
= 1; }
1401 | conditional_statement
1402 | NAMESPACE IDENTIFIER
{ push_namespace
(interp
, $2); mem_sys_free
($2); }
1403 | ENDNAMESPACE IDENTIFIER
{ pop_namespace
(interp
, $2); mem_sys_free
($2); }
1404 | LOCAL
{ is_def
=1; } type id_list
1410 mk_ident_ur
(interp
, l
->id
, $3);
1412 mk_ident
(interp
, l
->id
, $3);
1415 mem_sys_free
(l1
->id
);
1420 | LEXICAL STRINGC COMMA target
1422 set_lexical
(interp
, $4, $2); $$
= 0;
1424 | CONST
{ is_def
=1; } type IDENTIFIER
'=' const
1426 mk_const_ident
(interp
, $4, $3, $6, 0);
1432 | GLOBAL_CONST
{ is_def
=1; } type IDENTIFIER
'=' const
1434 mk_const_ident
(interp
, $4, $3, $6, 1);
1441 IMCC_INFO
(interp
)->cur_call
->pcc_sub
->flags |
= isTAIL_CALL
;
1442 IMCC_INFO
(interp
)->cur_call
= NULL
;
1444 | GOTO label_op
{ $$
= MK_I
(interp
, IMCC_INFO
(interp
)->cur_unit
, "branch", 1, $2); }
1448 IMCC_INFO
(interp
)->cur_unit
,
1451 IMCC_INFO
(interp
)->regs
,
1452 IMCC_INFO
(interp
)->nargs
,
1453 IMCC_INFO
(interp
)->keyvec
,
1457 | PNULL var
{ $$
= MK_I
(interp
, IMCC_INFO
(interp
)->cur_unit
, "null", 1, $2); }
1458 | sub_call
{ $$
= 0; IMCC_INFO
(interp
)->cur_call
= NULL
; }
1459 | pcc_sub_call
{ $$
= 0; }
1462 |
/* none */ { $$
= 0;}
1467 | FLOATV
{ $$
= 'N'; }
1468 | STRINGV
{ $$
= 'S'; }
1469 | PMCV
{ $$
= 'P'; }
1475 /* there'd normally be a str_dup() here, but the lexer already
1476 * copied the string, so it's safe to use directly */
1477 if
((IMCC_INFO
(interp
)->cur_pmc_type
= pmc_type
(interp
,
1478 string_from_cstring
(interp
, $1, 0))) <= 0) {
1479 IMCC_fataly
(interp
, E_SyntaxError
, "Unknown PMC type '%s'\n", $1);
1486 { $$
= MK_I
(interp
, IMCC_INFO
(interp
)->cur_unit
, "set", 2, $1, $3); }
1487 | target
'=' un_op var
1488 { $$
= MK_I
(interp
, IMCC_INFO
(interp
)->cur_unit
, $3, 2, $1, $4); }
1489 | target
'=' var bin_op var
1490 { $$
= MK_I
(interp
, IMCC_INFO
(interp
)->cur_unit
, $4, 3, $1, $3, $5); }
1491 | target
'=' var
'[' keylist
']'
1492 { $$
= iINDEXFETCH
(interp
, IMCC_INFO
(interp
)->cur_unit
, $1, $3, $5); }
1493 | target
'[' keylist
']' '=' var
1494 { $$
= iINDEXSET
(interp
, IMCC_INFO
(interp
)->cur_unit
, $1, $3, $6); }
1495 | target
'=' NEW classname COMMA var
1496 { $$
= iNEW
(interp
, IMCC_INFO
(interp
)->cur_unit
, $1, $4, $6, 1); }
1497 | target
'=' NEW classname
'[' keylist
']'
1498 { $$
= iNEW
(interp
, IMCC_INFO
(interp
)->cur_unit
, $1, $4, $6, 1); }
1499 | target
'=' NEW classname
1500 { $$
= iNEW
(interp
, IMCC_INFO
(interp
)->cur_unit
, $1, $4, NULL
, 1); }
1501 | target
'=' NEW var
1502 { $$
= MK_I
(interp
, IMCC_INFO
(interp
)->cur_unit
, "new", 2, $1, $4); }
1503 | target
'=' NEW
'[' keylist
']'
1504 { $$
= MK_I
(interp
, IMCC_INFO
(interp
)->cur_unit
, "new", 2, $1, $5); }
1505 | target
'=' NEW
'[' keylist
']' COMMA var
1506 { $$
= MK_I
(interp
, IMCC_INFO
(interp
)->cur_unit
, "new", 3, $1, $5, $8); }
1507 | target
'=' NEW var COMMA var
1508 { $$
= MK_I
(interp
, IMCC_INFO
(interp
)->cur_unit
, "new", 3, $1, $4, $6); }
1509 | target
'=' NEW var
'[' keylist
']'
1510 { $$
= MK_I
(interp
, IMCC_INFO
(interp
)->cur_unit
, "new", 3, $1, $4, $6); }
1511 | target
'=' ADDR IDENTIFIER
1512 { $$
= MK_I
(interp
, IMCC_INFO
(interp
)->cur_unit
, "set_addr",
1513 2, $1, mk_label_address
(interp
, $4)); mem_sys_free
($4); }
1514 | target
'=' GLOBALOP
string
1515 { $$
= MK_I
(interp
, IMCC_INFO
(interp
)->cur_unit
, "find_global", 2, $1, $4);}
1516 | GLOBALOP
string '=' var
1517 { $$
= MK_I
(interp
, IMCC_INFO
(interp
)->cur_unit
, "store_global", 2, $2, $4); }
1518 /* NEW is here because it is both PIR and PASM keywords so we
1519 * have to handle the token here (or badly hack the lexer). */
1520 | NEW target COMMA var
1521 { $$
= MK_I
(interp
, IMCC_INFO
(interp
)->cur_unit
, "new", 2, $2, $4); }
1522 | NEW target COMMA var COMMA var
1523 { $$
= MK_I
(interp
, IMCC_INFO
(interp
)->cur_unit
, "new", 3, $2, $4, $6); }
1524 | NEW target COMMA var
'[' keylist
']'
1525 { $$
= MK_I
(interp
, IMCC_INFO
(interp
)->cur_unit
, "new", 3, $2, $4, $6); }
1526 /* Subroutine call the short way */
1527 | target
'=' sub_call
1529 add_pcc_result
($3->symregs
[0], $1);
1530 IMCC_INFO
(interp
)->cur_call
= NULL
;
1535 $
<i
>$
= IMCC_create_itcall_label
(interp
);
1537 targetlist
')' '=' the_sub
'(' arglist
')'
1539 IMCC_itcall_sub
(interp
, $6);
1540 IMCC_INFO
(interp
)->cur_call
= NULL
;
1547 $$
= MK_I
(interp
, IMCC_INFO
(interp
)->cur_unit
, "null", 1, $1);
1551 /* C++ hates implicit casts from string constants to char *, so be explicit */
1553 '!' { $$
= (char *)"not"; }
1554 |
'~' { $$
= (char *)"bnot"; }
1555 |
'-' { $$
= (char *)"neg"; }
1559 '-' { $$
= (char *)"sub"; }
1560 |
'+' { $$
= (char *)"add"; }
1561 |
'*' { $$
= (char *)"mul"; }
1562 |
'/' { $$
= (char *)"div"; }
1563 |
'%' { $$
= (char *)"mod"; }
1564 | FDIV
{ $$
= (char *)"fdiv"; }
1565 | POW
{ $$
= (char *)"pow"; }
1566 | CONCAT
{ $$
= (char *)"concat"; }
1567 | RELOP_EQ
{ $$
= (char *)"iseq"; }
1568 | RELOP_NE
{ $$
= (char *)"isne"; }
1569 | RELOP_GT
{ $$
= (char *)"isgt"; }
1570 | RELOP_GTE
{ $$
= (char *)"isge"; }
1571 | RELOP_LT
{ $$
= (char *)"islt"; }
1572 | RELOP_LTE
{ $$
= (char *)"isle"; }
1573 | SHIFT_LEFT
{ $$
= (char *)"shl"; }
1574 | SHIFT_RIGHT
{ $$
= (char *)"shr"; }
1575 | SHIFT_RIGHT_U
{ $$
= (char *)"lsr"; }
1576 | LOG_AND
{ $$
= (char *)"and"; }
1577 | LOG_OR
{ $$
= (char *)"or"; }
1578 | LOG_XOR
{ $$
= (char *)"xor"; }
1579 |
'&' { $$
= (char *)"band"; }
1580 |
'|' { $$
= (char *)"bor"; }
1581 |
'~' { $$
= (char *)"bxor"; }
1588 $$
= IMCC_create_itcall_label
(interp
);
1589 $$
->type
&= ~ITCALL
;
1590 $$
->type |
= ITRESULT
;
1592 '(' targetlist
')' { $$
= 0; }
1598 target assign_op var
1600 $$
= MK_I
(interp
, IMCC_INFO
(interp
)->cur_unit
, $2, 2, $1, $3);
1605 PLUS_ASSIGN
{ $$
= (char *)"add"; }
1606 | MINUS_ASSIGN
{ $$
= (char *)"sub"; }
1607 | MUL_ASSIGN
{ $$
= (char *)"mul"; }
1608 | DIV_ASSIGN
{ $$
= (char *)"div"; }
1609 | MOD_ASSIGN
{ $$
= (char *)"mod"; }
1610 | FDIV_ASSIGN
{ $$
= (char *)"fdiv"; }
1611 | CONCAT_ASSIGN
{ $$
= (char *)"concat"; }
1612 | BAND_ASSIGN
{ $$
= (char *)"band"; }
1613 | BOR_ASSIGN
{ $$
= (char *)"bor"; }
1614 | BXOR_ASSIGN
{ $$
= (char *)"bxor"; }
1615 | SHR_ASSIGN
{ $$
= (char *)"shr"; }
1616 | SHL_ASSIGN
{ $$
= (char *)"shl"; }
1617 | SHR_U_ASSIGN
{ $$
= (char *)"lsr"; }
1622 target
'=' PARROT_OP pasm_args
1624 $$
= func_ins
(interp
, IMCC_INFO
(interp
)->cur_unit
, $1, $3,
1625 IMCC_INFO
(interp
) -> regs
,
1626 IMCC_INFO
(interp
) -> nargs
,
1627 IMCC_INFO
(interp
) -> keyvec
, 1);
1633 IDENTIFIER
{ $$
= mk_sub_address
(interp
, $1); mem_sys_free
($1); }
1634 | STRINGC
{ $$
= mk_sub_address_fromc
(interp
, $1); mem_sys_free
($1); }
1635 | USTRINGC
{ $$
= mk_sub_address_u
(interp
, $1); mem_sys_free
($1); }
1640 IMCC_fataly
(interp
, E_SyntaxError
, "Sub isn't a PMC");
1642 | target DOT sub_label_op
{ IMCC_INFO
(interp
)->cur_obj
= $1; $$
= $3; }
1643 | target DOT STRINGC
1645 IMCC_INFO
(interp
)->cur_obj
= $1; $$
= mk_const
(interp
, $3, 'S');
1648 | target DOT target
{ IMCC_INFO
(interp
)->cur_obj
= $1; $$
= $3; }
1655 $$
= IMCC_create_itcall_label
(interp
);
1656 IMCC_itcall_sub
(interp
, $1);
1658 '(' arglist
')' { $$
= $
<i
>2; }
1662 /* empty */ { $$
= 0; }
1666 if
(IMCC_INFO
(interp
)->adv_named_id
) {
1667 add_pcc_named_arg
(interp
, IMCC_INFO
(interp
)->cur_call
, IMCC_INFO
(interp
)->adv_named_id
, $3);
1668 IMCC_INFO
(interp
)->adv_named_id
= NULL
;
1671 add_pcc_arg
(IMCC_INFO
(interp
)->cur_call
, $3);
1676 if
(IMCC_INFO
(interp
)->adv_named_id
) {
1677 add_pcc_named_arg
(interp
, IMCC_INFO
(interp
)->cur_call
, IMCC_INFO
(interp
)->adv_named_id
, $1);
1678 IMCC_INFO
(interp
)->adv_named_id
= NULL
;
1681 add_pcc_arg
(IMCC_INFO
(interp
)->cur_call
, $1);
1683 | arglist COMMA STRINGC ADV_ARROW var
1686 add_pcc_named_arg
(interp
, IMCC_INFO
(interp
)->cur_call
, $3, $5);
1689 | STRINGC ADV_ARROW var
1692 add_pcc_named_arg
(interp
, IMCC_INFO
(interp
)->cur_call
, $1, $3);
1698 var argtype_list
{ $$
= $1; $$
->type |
= $2; }
1702 /* empty */ { $$
= 0; }
1703 | argtype_list argtype
{ $$
= $1 |
$2; }
1707 ADV_FLAT
{ $$
= VT_FLAT
; }
1708 | ADV_NAMED
{ $$
= VT_NAMED
; }
1710 /* don't free $3 here; adv_named_set uses the pointer directly */
1711 | ADV_NAMED
'(' STRINGC
')' { adv_named_set
(interp
, $3); $$
= 0; }
1715 target paramtype_list
{ $$
= $1; $$
->type |
= $2; }
1719 targetlist COMMA result
1722 if
(IMCC_INFO
(interp
)->adv_named_id
) {
1723 add_pcc_named_result
(interp
, IMCC_INFO
(interp
)->cur_call
, IMCC_INFO
(interp
)->adv_named_id
, $3);
1724 IMCC_INFO
(interp
)->adv_named_id
= NULL
;
1727 add_pcc_result
(IMCC_INFO
(interp
)->cur_call
, $3);
1729 | targetlist COMMA STRINGC ADV_ARROW target
1731 add_pcc_named_result
(interp
, IMCC_INFO
(interp
)->cur_call
, $3, $5);
1737 if
(IMCC_INFO
(interp
)->adv_named_id
) {
1738 add_pcc_named_result
(interp
, IMCC_INFO
(interp
)->cur_call
, IMCC_INFO
(interp
)->adv_named_id
, $1);
1739 IMCC_INFO
(interp
)->adv_named_id
= NULL
;
1742 add_pcc_result
(IMCC_INFO
(interp
)->cur_call
, $1);
1744 | STRINGC ADV_ARROW target
1746 add_pcc_named_result
(interp
, IMCC_INFO
(interp
)->cur_call
, $1, $3);
1749 |
/* empty */ { $$
= 0; }
1752 conditional_statement:
1753 if_statement
{ $$
= $1; }
1754 | unless_statement
{ $$
= $1; }
1758 UNLESS var relop var GOTO label_op
1760 $$
=MK_I
(interp
, IMCC_INFO
(interp
)->cur_unit
, inv_op
($3), 3, $2, $4, $6);
1762 | UNLESS PNULL var GOTO label_op
1764 $$
= MK_I
(interp
, IMCC_INFO
(interp
)->cur_unit
, "unless_null", 2, $3, $5);
1766 | UNLESS var comma_or_goto label_op
1768 $$
= MK_I
(interp
, IMCC_INFO
(interp
)->cur_unit
, "unless", 2, $2, $4);
1773 IF var comma_or_goto label_op
1775 $$
= MK_I
(interp
, IMCC_INFO
(interp
)->cur_unit
, "if", 2, $2, $4);
1777 | IF var relop var GOTO label_op
1779 $$
=MK_I
(interp
, IMCC_INFO
(interp
)->cur_unit
, $3, 3, $2, $4, $6);
1781 | IF PNULL var GOTO label_op
1783 $$
= MK_I
(interp
, IMCC_INFO
(interp
)->cur_unit
, "if_null", 2, $3, $5);
1793 RELOP_EQ
{ $$
= (char *)"eq"; }
1794 | RELOP_NE
{ $$
= (char *)"ne"; }
1795 | RELOP_GT
{ $$
= (char *)"gt"; }
1796 | RELOP_GTE
{ $$
= (char *)"ge"; }
1797 | RELOP_LT
{ $$
= (char *)"lt"; }
1798 | RELOP_LTE
{ $$
= (char *)"le"; }
1807 /* empty */ { $$
= NULL
; }
1808 | _vars
{ $$
= $1; }
1812 _vars COMMA _var_or_i
{ $$
= IMCC_INFO
(interp
)->regs
[0]; }
1817 var_or_i
{ IMCC_INFO
(interp
)->regs
[IMCC_INFO
(interp
)->nargs
++] = $1; }
1818 | target
'[' keylist
']'
1820 IMCC_INFO
(interp
) -> regs
[IMCC_INFO
(interp
)->nargs
++] = $1;
1821 IMCC_INFO
(interp
) -> keyvec |
= KEY_BIT
(IMCC_INFO
(interp
)->nargs
);
1822 IMCC_INFO
(interp
) -> regs
[IMCC_INFO
(interp
)->nargs
++] = $3;
1825 |
'[' keylist_force
']'
1827 IMCC_INFO
(interp
) -> regs
[IMCC_INFO
(interp
)->nargs
++] = $2;
1833 | STRINGC
{ $$
= mk_sub_address_fromc
(interp
, $1); mem_sys_free
($1); }
1834 | USTRINGC
{ $$
= mk_sub_address_u
(interp
, $1); mem_sys_free
($1); }
1838 IDENTIFIER
{ $$
= mk_sub_address
(interp
, $1); mem_sys_free
($1); }
1839 | PARROT_OP
{ $$
= mk_sub_address
(interp
, $1); mem_sys_free
($1); }
1843 IDENTIFIER
{ $$
= mk_label_address
(interp
, $1); mem_sys_free
($1); }
1844 | PARROT_OP
{ $$
= mk_label_address
(interp
, $1); mem_sys_free
($1); }
1859 IMCC_INFO
(interp
)->nkeys
= 0;
1860 IMCC_INFO
(interp
)->in_slice
= 0;
1864 $$
= link_keys
(interp
,
1865 IMCC_INFO
(interp
)->nkeys
,
1866 IMCC_INFO
(interp
)->keys
, 0);
1872 IMCC_INFO
(interp
)->nkeys
= 0;
1873 IMCC_INFO
(interp
)->in_slice
= 0;
1877 $$
= link_keys
(interp
,
1878 IMCC_INFO
(interp
)->nkeys
,
1879 IMCC_INFO
(interp
)->keys
, 1);
1884 key
{ IMCC_INFO
(interp
)->keys
[IMCC_INFO
(interp
)->nkeys
++] = $1; }
1887 IMCC_INFO
(interp
)->keys
[IMCC_INFO
(interp
)->nkeys
++] = $3;
1888 $$
= IMCC_INFO
(interp
)->keys
[0];
1890 | _keylist COMMA
{ IMCC_INFO
(interp
)->in_slice
= 1; }
1893 IMCC_INFO
(interp
)->keys
[IMCC_INFO
(interp
)->nkeys
++] = $4;
1894 $$
= IMCC_INFO
(interp
)->keys
[0];
1901 if
(IMCC_INFO
(interp
)->in_slice
)
1902 $1->type |
= VT_START_SLICE | VT_END_SLICE
;
1907 $1->type |
= VT_START_SLICE
;
1908 $3->type |
= VT_END_SLICE
;
1909 IMCC_INFO
(interp
)->keys
[IMCC_INFO
(interp
)->nkeys
++] = $1;
1912 | DOTDOT var
{ $2->type |
= VT_START_ZERO | VT_END_SLICE
; $$
= $2; }
1913 | var DOTDOT
{ $1->type |
= VT_START_SLICE | VT_END_INF
; $$
= $1; }
1917 IREG
{ $$
= mk_symreg
(interp
, $1, 'I'); }
1918 | NREG
{ $$
= mk_symreg
(interp
, $1, 'N'); }
1919 | SREG
{ $$
= mk_symreg
(interp
, $1, 'S'); }
1920 | PREG
{ $$
= mk_symreg
(interp
, $1, 'P'); }
1921 | REG
{ $$
= mk_pasm_reg
(interp
, $1); mem_sys_free
($1); }
1925 INTC
{ $$
= mk_const
(interp
, $1, 'I'); mem_sys_free
($1); }
1926 | FLOATC
{ $$
= mk_const
(interp
, $1, 'N'); mem_sys_free
($1); }
1927 | STRINGC
{ $$
= mk_const
(interp
, $1, 'S'); mem_sys_free
($1); }
1928 | USTRINGC
{ $$
= mk_const
(interp
, $1, 'U'); mem_sys_free
($1); }
1932 SREG
{ $$
= mk_symreg
(interp
, $1, 'S'); mem_sys_free
($1); }
1933 | STRINGC
{ $$
= mk_const
(interp
, $1, 'S'); mem_sys_free
($1); }
1940 /* I need this prototype somewhere... */
1941 char *yyget_text
(yyscan_t yyscanner
);
1943 /* I do not like this function, but, atm, it is the only way I can
1944 * make the code in yyerror work without segfault on some specific
1947 /* int yyholds_char(yyscan_t yyscanner); */
1949 int yyerror(void *yyscanner
, PARROT_INTERP
, const char *s
)
1951 /* If the error occurr in the end of the buffer (I mean, the last
1952 * token was already read), yyget_text will return a pointer
1953 * outside the bison buffer, and thus, not "accessible" by
1954 * us. This means it may segfault. */
1955 const char * const chr
= yyget_text
((yyscan_t
)yyscanner
);
1957 /* IMCC_fataly(interp, E_SyntaxError, s); */
1958 /* --- This was called before, not sure if I should call some
1959 similar function that does not die like this one. */
1961 /* Basically, if current token is a newline, it mean the error was
1962 * before the newline, and thus, line is the line *after* the
1963 * error. Instead of duplicating code for both cases (the 'newline' and
1964 * non-newline case, do the test twice; efficiency is not important when
1965 * we have an error anyway.
1967 if
(!at_eof
(yyscanner
)) {
1969 IMCC_INFO
(interp
)->line
--;
1972 IMCC_warning
(interp
, "error:imcc:%s", s
);
1973 /* don't print the current token if it is a newline */
1975 IMCC_warning
(interp
, " ('%s')", chr
);
1977 IMCC_print_inc
(interp
);
1980 IMCC_INFO
(interp
)->line
++;
1984 else
{ /* scanner is at end of file; just to be sure, do not print "current" token. */
1985 IMCC_warning
(interp
, "error:imcc:%s", s
);
1986 IMCC_print_inc
(interp
);
1994 * c-file-style: "parrot"
1996 * vim: expandtab shiftwidth=4: