2 /* NetHack 3.6 lev_comp.y $NHDT-Date: 1448074095 2015/11/21 02:48:15 $ $NHDT-Branch: master $:$NHDT-Revision: 1.18 $ */
3 /* Copyright (c) 1989 by Jean-Christophe Collet */
4 /* NetHack may be freely redistributed. See license for details. */
7 * This file contains the Level Compiler code
8 * It may handle special mazes & special room-levels
11 /* In case we're using bison in AIX. This definition must be
12 * placed before any other C-language construct in the file
13 * excluding comments and preprocessor directives (thanks IBM
14 * for this wonderful feature...).
16 * Note: some cpps barf on this 'undefined control' (#pragma).
17 * Addition of the leading space seems to prevent barfage for now,
18 * and AIX will still see the directive.
21 #pragma alloca /* keep leading space! */
24 #define SPEC_LEV /* for USE_OLDARGS (sp_lev.h) */
29 /* many types of things are put in chars for transference to NetHack.
30 * since some systems will use signed chars, limit everybody to the
31 * same number for portability.
33 #define MAX_OF_TYPE 128
35 #define MAX_NESTED_IFS 20
36 #define MAX_SWITCH_CASES 20
39 (type
*) memset
((genericptr_t
) alloc
(sizeof
(type
)), 0, sizeof
(type
))
40 #define NewTab(type, size) (type **) alloc(sizeof (type *) * size)
41 #define Free(ptr) free((genericptr_t) ptr)
43 extern
void VDECL
(lc_error
, (const char *, ...
));
44 extern
void VDECL
(lc_warning
, (const char *, ...
));
45 extern
void FDECL
(yyerror, (const char *));
46 extern
void FDECL
(yywarning
, (const char *));
47 extern
int NDECL
(yylex);
50 extern
int FDECL
(get_floor_type
, (CHAR_P
));
51 extern
int FDECL
(get_room_type
, (char *));
52 extern
int FDECL
(get_trap_type
, (char *));
53 extern
int FDECL
(get_monster_id
, (char *,CHAR_P
));
54 extern
int FDECL
(get_object_id
, (char *,CHAR_P
));
55 extern boolean FDECL
(check_monster_char
, (CHAR_P
));
56 extern boolean FDECL
(check_object_char
, (CHAR_P
));
57 extern
char FDECL
(what_map_char
, (CHAR_P
));
58 extern
void FDECL
(scan_map
, (char *, sp_lev
*));
59 extern
void FDECL
(add_opcode
, (sp_lev
*, int, genericptr_t
));
60 extern genericptr_t FDECL
(get_last_opcode_data1
, (sp_lev
*, int));
61 extern genericptr_t FDECL
(get_last_opcode_data2
, (sp_lev
*, int, int));
62 extern boolean FDECL
(check_subrooms
, (sp_lev
*));
63 extern boolean FDECL
(write_level_file
, (char *,sp_lev
*));
64 extern
struct opvar
*FDECL
(set_opvar_int
, (struct opvar
*, long));
65 extern
void VDECL
(add_opvars
, (sp_lev
*, const char *, ...
));
66 extern
void FDECL
(start_level_def
, (sp_lev
* *, char *));
68 extern
struct lc_funcdefs
*FDECL
(funcdef_new
, (long,char *));
69 extern
void FDECL
(funcdef_free_all
, (struct lc_funcdefs
*));
70 extern
struct lc_funcdefs
*FDECL
(funcdef_defined
, (struct lc_funcdefs
*,
72 extern
char *FDECL
(funcdef_paramtypes
, (struct lc_funcdefs
*));
73 extern
char *FDECL
(decode_parm_str
, (char *));
75 extern
struct lc_vardefs
*FDECL
(vardef_new
, (long,char *));
76 extern
void FDECL
(vardef_free_all
, (struct lc_vardefs
*));
77 extern
struct lc_vardefs
*FDECL
(vardef_defined
, (struct lc_vardefs
*,
80 extern
void NDECL
(break_stmt_start
);
81 extern
void FDECL
(break_stmt_end
, (sp_lev
*));
82 extern
void FDECL
(break_stmt_new
, (sp_lev
*, long));
84 extern
void FDECL
(splev_add_from
, (sp_lev
*, sp_lev
*));
86 extern
void FDECL
(check_vardef_type
, (struct lc_vardefs
*, char *, long));
87 extern
void FDECL
(vardef_used
, (struct lc_vardefs
*, char *));
88 extern
struct lc_vardefs
*FDECL
(add_vardef_type
, (struct lc_vardefs
*,
91 extern
int FDECL
(reverse_jmp_opcode
, (int));
102 static struct forloopdef forloop_list
[MAX_NESTED_IFS
];
103 static short n_forloops
= 0;
106 sp_lev
*splev
= NULL
;
108 static struct opvar
*if_list
[MAX_NESTED_IFS
];
110 static short n_if_list
= 0;
112 unsigned int max_x_map
, max_y_map
;
113 int obj_containment
= 0;
115 int in_container_obj
= 0;
117 /* integer value is possibly an inconstant value (eg. dice notation or a variable) */
118 int is_inconstant_number
= 0;
120 int in_switch_statement
= 0;
121 static struct opvar
*switch_check_jump
= NULL
;
122 static struct opvar
*switch_default_case
= NULL
;
123 static struct opvar
*switch_case_list
[MAX_SWITCH_CASES
];
124 static long switch_case_value
[MAX_SWITCH_CASES
];
125 int n_switch_case_list
= 0;
127 int allow_break_statements
= 0;
128 struct lc_breakdef
*break_list
= NULL
;
130 extern
struct lc_vardefs
*variable_definitions
;
133 struct lc_vardefs
*function_tmp_var_defs
= NULL
;
134 extern
struct lc_funcdefs
*function_definitions
;
135 struct lc_funcdefs
*curr_function
= NULL
;
136 struct lc_funcdefs_parm
* curr_function_param
= NULL
;
137 int in_function_definition
= 0;
138 sp_lev
*function_splev_backup
= NULL
;
140 extern
int fatal_error
;
141 extern
int got_errors
;
142 extern
int line_number
;
143 extern
const char *fname
;
145 extern
char curr_token
[512];
188 %token
<i
> CHAR INTEGER BOOLEAN PERCENT SPERCENT
189 %token
<i
> MINUS_INTEGER PLUS_INTEGER
190 %token
<i
> MAZE_GRID_ID SOLID_FILL_ID MINES_ID ROGUELEV_ID
191 %token
<i
> MESSAGE_ID MAZE_ID LEVEL_ID LEV_INIT_ID GEOMETRY_ID NOMAP_ID
192 %token
<i
> OBJECT_ID COBJECT_ID MONSTER_ID TRAP_ID DOOR_ID DRAWBRIDGE_ID
193 %token
<i
> object_ID monster_ID terrain_ID
194 %token
<i
> MAZEWALK_ID WALLIFY_ID REGION_ID FILLING IRREGULAR JOINED
195 %token
<i
> ALTAR_ID LADDER_ID STAIR_ID NON_DIGGABLE_ID NON_PASSWALL_ID ROOM_ID
196 %token
<i
> PORTAL_ID TELEPRT_ID BRANCH_ID LEV MINERALIZE_ID
197 %token
<i
> CORRIDOR_ID GOLD_ID ENGRAVING_ID FOUNTAIN_ID POOL_ID SINK_ID NONE
198 %token
<i
> RAND_CORRIDOR_ID DOOR_STATE LIGHT_STATE CURSE_TYPE ENGRAVING_TYPE
199 %token
<i
> DIRECTION RANDOM_TYPE RANDOM_TYPE_BRACKET A_REGISTER
200 %token
<i
> ALIGNMENT LEFT_OR_RIGHT CENTER TOP_OR_BOT ALTAR_TYPE UP_OR_DOWN
201 %token
<i
> SUBROOM_ID NAME_ID FLAGS_ID FLAG_TYPE MON_ATTITUDE MON_ALERTNESS
202 %token
<i
> MON_APPEARANCE ROOMDOOR_ID IF_ID ELSE_ID
203 %token
<i
> TERRAIN_ID HORIZ_OR_VERT REPLACE_TERRAIN_ID
204 %token
<i
> EXIT_ID SHUFFLE_ID
205 %token
<i
> QUANTITY_ID BURIED_ID LOOP_ID
206 %token
<i
> FOR_ID TO_ID
207 %token
<i
> SWITCH_ID CASE_ID BREAK_ID DEFAULT_ID
208 %token
<i
> ERODED_ID TRAPPED_STATE RECHARGED_ID INVIS_ID GREASED_ID
209 %token
<i
> FEMALE_ID CANCELLED_ID REVIVED_ID AVENGE_ID FLEEING_ID BLINDED_ID
210 %token
<i
> PARALYZED_ID STUNNED_ID CONFUSED_ID SEENTRAPS_ID ALL_ID
211 %token
<i
> MONTYPE_ID
212 %token
<i
> GRAVE_ID ERODEPROOF_ID
213 %token
<i
> FUNCTION_ID
214 %token
<i
> MSG_OUTPUT_TYPE
215 %token
<i
> COMPARE_TYPE
216 %token
<i
> UNKNOWN_TYPE
217 %token
<i
> rect_ID fillrect_ID line_ID randline_ID grow_ID selection_ID flood_ID
218 %token
<i
> rndcoord_ID circle_ID ellipse_ID filter_ID complement_ID
219 %token
<i
> gradient_ID GRADIENT_TYPE LIMITED HUMIDITY_TYPE
220 %token
<i
> ',' ':' '(' ')' '[' ']' '{' '}'
221 %token
<map
> STRING MAP_ID
222 %token
<map
> NQSTRING VARSTRING
223 %token
<map
> CFUNC CFUNC_INT CFUNC_STR CFUNC_COORD CFUNC_REGION
224 %token
<map
> VARSTRING_INT VARSTRING_INT_ARRAY
225 %token
<map
> VARSTRING_STRING VARSTRING_STRING_ARRAY
226 %token
<map
> VARSTRING_VAR VARSTRING_VAR_ARRAY
227 %token
<map
> VARSTRING_COORD VARSTRING_COORD_ARRAY
228 %token
<map
> VARSTRING_REGION VARSTRING_REGION_ARRAY
229 %token
<map
> VARSTRING_MAPCHAR VARSTRING_MAPCHAR_ARRAY
230 %token
<map
> VARSTRING_MONST VARSTRING_MONST_ARRAY
231 %token
<map
> VARSTRING_OBJ VARSTRING_OBJ_ARRAY
232 %token
<map
> VARSTRING_SEL VARSTRING_SEL_ARRAY
233 %token
<meth
> METHOD_INT METHOD_INT_ARRAY
234 %token
<meth
> METHOD_STRING METHOD_STRING_ARRAY
235 %token
<meth
> METHOD_VAR METHOD_VAR_ARRAY
236 %token
<meth
> METHOD_COORD METHOD_COORD_ARRAY
237 %token
<meth
> METHOD_REGION METHOD_REGION_ARRAY
238 %token
<meth
> METHOD_MAPCHAR METHOD_MAPCHAR_ARRAY
239 %token
<meth
> METHOD_MONST METHOD_MONST_ARRAY
240 %token
<meth
> METHOD_OBJ METHOD_OBJ_ARRAY
241 %token
<meth
> METHOD_SEL METHOD_SEL_ARRAY
243 %type
<i
> h_justif v_justif trap_name room_type door_state light_state
244 %type
<i
> alignment altar_type a_register roomfill door_pos
245 %type
<i
> alignment_prfx
246 %type
<i
> door_wall walled secret
247 %type
<i
> dir_list teleprt_detail
248 %type
<i
> object_infos object_info monster_infos monster_info
249 %type
<i
> levstatements stmt_block region_detail_end
250 %type
<i
> engraving_type flag_list roomregionflag roomregionflags optroomregionflags
251 %type
<i
> humidity_flags
252 %type
<i
> comparestmt encodecoord encoderegion mapchar
253 %type
<i
> seen_trap_mask
254 %type
<i
> encodemonster encodeobj encodeobj_list
255 %type
<i
> integer_list string_list encodecoord_list encoderegion_list mapchar_list encodemonster_list
256 %type
<i
> opt_percent opt_fillchar
257 %type
<i
> all_integers
258 %type
<i
> ter_selection ter_selection_x
259 %type
<i
> func_param_type
260 %type
<i
> objectid monsterid terrainid
261 %type
<i
> opt_coord_or_var opt_limited
263 %type
<map
> level_def
264 %type
<map
> any_var any_var_array any_var_or_arr any_var_or_unk
265 %type
<map
> func_call_params_list func_call_param_list
266 %type
<i
> func_call_param_part
267 %type
<corpos
> corr_spec
268 %type
<lregn
> region lev_region
269 %type
<crd
> room_pos subroom_pos room_align
270 %type
<sze
> room_size
271 %type
<terr
> terrain_type
285 level
: level_def flags levstatements
287 if
(fatal_error
> 0) {
288 (void) fprintf
(stderr
,
289 "%s: %d errors detected for level \"%s\". No output created!\n",
290 fname
, fatal_error
, $1);
293 } else if
(!got_errors
) {
294 if
(!write_level_file
($1, splev
)) {
295 lc_error
("Can't write output file for '%s'!", $1);
302 vardef_free_all
(variable_definitions
);
303 variable_definitions
= NULL
;
307 level_def
: LEVEL_ID
':' STRING
309 start_level_def
(&splev
, $3);
312 | MAZE_ID
':' STRING
',' mazefiller
314 start_level_def
(&splev
, $3);
316 add_opvars
(splev
, "iiiiiiiio",
317 VA_PASS9
(LVLINIT_MAZEGRID
,HWALL
,0,0,
318 0,0,0,0, SPO_INITLEVEL
));
320 long bg
= what_map_char
((char) $5);
321 add_opvars
(splev
, "iiiiiiiio",
322 VA_PASS9
(LVLINIT_SOLIDFILL
, bg
, 0,0,
323 0,0,0,0, SPO_INITLEVEL
));
325 add_opvars
(splev
, "io",
326 VA_PASS2
(MAZELEVEL
, SPO_LEVEL_FLAGS
));
333 mazefiller
: RANDOM_TYPE
339 $$
= what_map_char
((char) $1);
343 lev_init
: LEV_INIT_ID
':' SOLID_FILL_ID
',' terrain_type
345 long filling
= $5.ter
;
346 if
(filling
== INVALID_TYPE || filling
>= MAX_TYPE
)
347 lc_error
("INIT_MAP: Invalid fill char type.");
348 add_opvars
(splev
, "iiiiiiiio",
349 LVLINIT_SOLIDFILL
,filling
,0,(long)$5.lit
, 0,0,0,0, SPO_INITLEVEL
);
353 | LEV_INIT_ID
':' MAZE_GRID_ID
',' CHAR
355 long filling
= what_map_char
((char) $5);
356 if
(filling
== INVALID_TYPE || filling
>= MAX_TYPE
)
357 lc_error
("INIT_MAP: Invalid fill char type.");
358 add_opvars
(splev
, "iiiiiiiio",
359 VA_PASS9
(LVLINIT_MAZEGRID
,filling
,0,0,
360 0,0,0,0, SPO_INITLEVEL
));
364 | LEV_INIT_ID
':' ROGUELEV_ID
366 add_opvars
(splev
, "iiiiiiiio",
367 VA_PASS9
(LVLINIT_ROGUE
,0,0,0,
368 0,0,0,0, SPO_INITLEVEL
));
370 | LEV_INIT_ID
':' MINES_ID
',' CHAR
',' CHAR
',' BOOLEAN
',' BOOLEAN
',' light_state
',' walled opt_fillchar
372 long fg
= what_map_char
((char) $5);
373 long bg
= what_map_char
((char) $7);
379 if
(fg
== INVALID_TYPE || fg
>= MAX_TYPE
)
380 lc_error
("INIT_MAP: Invalid foreground type.");
381 if
(bg
== INVALID_TYPE || bg
>= MAX_TYPE
)
382 lc_error
("INIT_MAP: Invalid background type.");
383 if
(joined
&& fg
!= CORR
&& fg
!= ROOM
)
384 lc_error
("INIT_MAP: Invalid foreground type for joined map.");
386 if
(filling
== INVALID_TYPE
)
387 lc_error
("INIT_MAP: Invalid fill char type.");
389 add_opvars
(splev
, "iiiiiiiio",
390 VA_PASS9
(LVLINIT_MINES
,filling
,walled
,lit
,
391 joined
,smoothed
,bg
,fg
,
398 opt_limited
: /* nothing */
408 opt_coord_or_var
: /* nothing */
410 add_opvars
(splev
, "o", VA_PASS1
(SPO_COPY
));
419 opt_fillchar
: /* nothing */
425 $$
= what_map_char
((char) $2);
434 flags
: /* nothing */
436 add_opvars
(splev
, "io", VA_PASS2
(0, SPO_LEVEL_FLAGS
));
438 | FLAGS_ID
':' flag_list
440 add_opvars
(splev
, "io", VA_PASS2
($3, SPO_LEVEL_FLAGS
));
444 flag_list
: FLAG_TYPE
',' flag_list
454 levstatements
: /* nothing */
458 | levstatement levstatements
464 stmt_block
: '{' levstatements
'}'
470 levstatement
: message
508 | replace_terrain_detail
516 any_var_array
: VARSTRING_INT_ARRAY
517 | VARSTRING_STRING_ARRAY
518 | VARSTRING_VAR_ARRAY
519 | VARSTRING_COORD_ARRAY
520 | VARSTRING_REGION_ARRAY
521 | VARSTRING_MAPCHAR_ARRAY
522 | VARSTRING_MONST_ARRAY
523 | VARSTRING_OBJ_ARRAY
524 | VARSTRING_SEL_ARRAY
527 any_var
: VARSTRING_INT
538 any_var_or_arr
: any_var_array
543 any_var_or_unk
: VARSTRING
547 shuffle_detail
: SHUFFLE_ID
':' any_var_array
549 struct lc_vardefs
*vd
;
550 if
((vd
= vardef_defined
(variable_definitions
, $3, 1))) {
551 if
(!(vd
->var_type
& SPOVAR_ARRAY
))
552 lc_error
("Trying to shuffle non-array variable '%s'", $3);
553 } else lc_error
("Trying to shuffle undefined variable '%s'", $3);
554 add_opvars
(splev
, "so", VA_PASS2
($3, SPO_SHUFFLE_ARRAY
));
559 variable_define
: any_var_or_arr
'=' math_expr_var
561 variable_definitions
= add_vardef_type
(variable_definitions
, $1, SPOVAR_INT
);
562 add_opvars
(splev
, "iso", VA_PASS3
(0, $1, SPO_VAR_INIT
));
565 | any_var_or_arr
'=' selection_ID
':' ter_selection
567 variable_definitions
= add_vardef_type
(variable_definitions
, $1, SPOVAR_SEL
);
568 add_opvars
(splev
, "iso", VA_PASS3
(0, $1, SPO_VAR_INIT
));
571 | any_var_or_arr
'=' string_expr
573 variable_definitions
= add_vardef_type
(variable_definitions
, $1, SPOVAR_STRING
);
574 add_opvars
(splev
, "iso", VA_PASS3
(0, $1, SPO_VAR_INIT
));
577 | any_var_or_arr
'=' terrainid
':' mapchar_or_var
579 variable_definitions
= add_vardef_type
(variable_definitions
, $1, SPOVAR_MAPCHAR
);
580 add_opvars
(splev
, "iso", VA_PASS3
(0, $1, SPO_VAR_INIT
));
583 | any_var_or_arr
'=' monsterid
':' monster_or_var
585 variable_definitions
= add_vardef_type
(variable_definitions
, $1, SPOVAR_MONST
);
586 add_opvars
(splev
, "iso", VA_PASS3
(0, $1, SPO_VAR_INIT
));
589 | any_var_or_arr
'=' objectid
':' object_or_var
591 variable_definitions
= add_vardef_type
(variable_definitions
, $1, SPOVAR_OBJ
);
592 add_opvars
(splev
, "iso", VA_PASS3
(0, $1, SPO_VAR_INIT
));
595 | any_var_or_arr
'=' coord_or_var
597 variable_definitions
= add_vardef_type
(variable_definitions
, $1, SPOVAR_COORD
);
598 add_opvars
(splev
, "iso", VA_PASS3
(0, $1, SPO_VAR_INIT
));
601 | any_var_or_arr
'=' region_or_var
603 variable_definitions
= add_vardef_type
(variable_definitions
, $1, SPOVAR_REGION
);
604 add_opvars
(splev
, "iso", VA_PASS3
(0, $1, SPO_VAR_INIT
));
607 | any_var_or_arr
'=' '{' integer_list
'}'
610 variable_definitions
= add_vardef_type
(variable_definitions
, $1, SPOVAR_INT|SPOVAR_ARRAY
);
611 add_opvars
(splev
, "iso",
612 VA_PASS3
(n_items
, $1, SPO_VAR_INIT
));
615 | any_var_or_arr
'=' '{' encodecoord_list
'}'
618 variable_definitions
= add_vardef_type
(variable_definitions
, $1, SPOVAR_COORD|SPOVAR_ARRAY
);
619 add_opvars
(splev
, "iso",
620 VA_PASS3
(n_items
, $1, SPO_VAR_INIT
));
623 | any_var_or_arr
'=' '{' encoderegion_list
'}'
626 variable_definitions
= add_vardef_type
(variable_definitions
, $1, SPOVAR_REGION|SPOVAR_ARRAY
);
627 add_opvars
(splev
, "iso",
628 VA_PASS3
(n_items
, $1, SPO_VAR_INIT
));
631 | any_var_or_arr
'=' terrainid
':' '{' mapchar_list
'}'
634 variable_definitions
= add_vardef_type
(variable_definitions
, $1, SPOVAR_MAPCHAR|SPOVAR_ARRAY
);
635 add_opvars
(splev
, "iso",
636 VA_PASS3
(n_items
, $1, SPO_VAR_INIT
));
639 | any_var_or_arr
'=' monsterid
':' '{' encodemonster_list
'}'
642 variable_definitions
= add_vardef_type
(variable_definitions
, $1, SPOVAR_MONST|SPOVAR_ARRAY
);
643 add_opvars
(splev
, "iso",
644 VA_PASS3
(n_items
, $1, SPO_VAR_INIT
));
647 | any_var_or_arr
'=' objectid
':' '{' encodeobj_list
'}'
650 variable_definitions
= add_vardef_type
(variable_definitions
, $1, SPOVAR_OBJ|SPOVAR_ARRAY
);
651 add_opvars
(splev
, "iso",
652 VA_PASS3
(n_items
, $1, SPO_VAR_INIT
));
655 | any_var_or_arr
'=' '{' string_list
'}'
658 variable_definitions
= add_vardef_type
(variable_definitions
, $1, SPOVAR_STRING|SPOVAR_ARRAY
);
659 add_opvars
(splev
, "iso",
660 VA_PASS3
(n_items
, $1, SPO_VAR_INIT
));
665 encodeobj_list
: encodeobj
667 add_opvars
(splev
, "O", VA_PASS1
($1));
670 | encodeobj_list
',' encodeobj
672 add_opvars
(splev
, "O", VA_PASS1
($3));
677 encodemonster_list
: encodemonster
679 add_opvars
(splev
, "M", VA_PASS1
($1));
682 | encodemonster_list
',' encodemonster
684 add_opvars
(splev
, "M", VA_PASS1
($3));
689 mapchar_list
: mapchar
691 add_opvars
(splev
, "m", VA_PASS1
($1));
694 | mapchar_list
',' mapchar
696 add_opvars
(splev
, "m", VA_PASS1
($3));
701 encoderegion_list
: encoderegion
705 | encoderegion_list
',' encoderegion
711 encodecoord_list
: encodecoord
713 add_opvars
(splev
, "c", VA_PASS1
($1));
716 | encodecoord_list
',' encodecoord
718 add_opvars
(splev
, "c", VA_PASS1
($3));
723 integer_list
: math_expr_var
727 | integer_list
',' math_expr_var
733 string_list
: string_expr
737 | string_list
',' string_expr
743 function_define
: FUNCTION_ID NQSTRING
'('
745 struct lc_funcdefs
*funcdef
;
747 if
(in_function_definition
)
748 lc_error
("Recursively defined functions not allowed (function %s).", $2);
750 in_function_definition
++;
752 if
(funcdef_defined
(function_definitions
, $2, 1))
753 lc_error
("Function '%s' already defined once.", $2);
755 funcdef
= funcdef_new
(-1, $2);
756 funcdef
->next
= function_definitions
;
757 function_definitions
= funcdef
;
758 function_splev_backup
= splev
;
759 splev
= &(funcdef
->code
);
761 curr_function
= funcdef
;
762 function_tmp_var_defs
= variable_definitions
;
763 variable_definitions
= NULL
;
771 add_opvars
(splev
, "io", VA_PASS2
(0, SPO_RETURN
));
772 splev
= function_splev_backup
;
773 in_function_definition
--;
774 curr_function
= NULL
;
775 vardef_free_all
(variable_definitions
);
776 variable_definitions
= function_tmp_var_defs
;
780 function_call
: NQSTRING
'(' func_call_params_list
')'
782 struct lc_funcdefs
*tmpfunc
;
783 tmpfunc
= funcdef_defined
(function_definitions
, $1, 1);
786 long nparams
= strlen
( $3 );
787 char *fparamstr
= funcdef_paramtypes
(tmpfunc
);
788 if
(strcmp
($3, fparamstr
)) {
789 char *tmps
= strdup
(decode_parm_str
(fparamstr
));
790 lc_error
("Function '%s' requires params '%s', got '%s' instead.", $1, tmps
, decode_parm_str
($3));
795 if
(!(tmpfunc
->n_called
)) {
796 /* we haven't called the function yet, so insert it in the code */
797 struct opvar
*jmp
= New
(struct opvar
);
798 set_opvar_int
(jmp
, splev
->n_opcodes
+1);
799 add_opcode
(splev
, SPO_PUSH
, jmp
);
800 add_opcode
(splev
, SPO_JMP
, NULL
); /* we must jump past it first, then CALL it, due to RETURN. */
802 tmpfunc
->addr
= splev
->n_opcodes
;
804 { /* init function parameter variables */
805 struct lc_funcdefs_parm
*tfp
= tmpfunc
->params
;
807 add_opvars
(splev
, "iso",
808 VA_PASS3
(0, tfp
->name
,
814 splev_add_from
(splev
, &(tmpfunc
->code
));
815 set_opvar_int
(jmp
, splev
->n_opcodes
- jmp
->vardata.l
);
817 l
= tmpfunc
->addr
- splev
->n_opcodes
- 2;
818 add_opvars
(splev
, "iio",
819 VA_PASS3
(nparams
, l
, SPO_CALL
));
822 lc_error
("Function '%s' not defined.", $1);
828 exitstatement
: EXIT_ID
830 add_opcode
(splev
, SPO_EXIT
, NULL
);
834 opt_percent
: /* nothing */
844 comparestmt
: PERCENT
847 add_opvars
(splev
, "iio",
848 VA_PASS3
((long)$1, 100, SPO_RN2
));
851 |
'[' math_expr_var COMPARE_TYPE math_expr_var
']'
855 |
'[' math_expr_var
']'
857 /* boolean, explicit foo != 0 */
858 add_opvars
(splev
, "i", VA_PASS1
(0));
863 switchstatement
: SWITCH_ID
865 is_inconstant_number
= 0;
867 '[' integer_or_var
']'
869 struct opvar
*chkjmp
;
870 if
(in_switch_statement
> 0)
871 lc_error
("Cannot nest switch-statements.");
873 in_switch_statement
++;
875 n_switch_case_list
= 0;
876 switch_default_case
= NULL
;
878 if
(!is_inconstant_number
)
879 add_opvars
(splev
, "o", VA_PASS1
(SPO_RN2
));
880 is_inconstant_number
= 0;
882 chkjmp
= New
(struct opvar
);
883 set_opvar_int
(chkjmp
, splev
->n_opcodes
+1);
884 switch_check_jump
= chkjmp
;
885 add_opcode
(splev
, SPO_PUSH
, chkjmp
);
886 add_opcode
(splev
, SPO_JMP
, NULL
);
891 struct opvar
*endjump
= New
(struct opvar
);
894 set_opvar_int
(endjump
, splev
->n_opcodes
+1);
896 add_opcode
(splev
, SPO_PUSH
, endjump
);
897 add_opcode
(splev
, SPO_JMP
, NULL
);
899 set_opvar_int
(switch_check_jump
,
900 splev
->n_opcodes
- switch_check_jump
->vardata.l
);
902 for
(i
= 0; i
< n_switch_case_list
; i
++) {
903 add_opvars
(splev
, "oio",
905 switch_case_value
[i
], SPO_CMP
));
906 set_opvar_int
(switch_case_list
[i
],
907 switch_case_list
[i
]->vardata.l
- splev
->n_opcodes
-1);
908 add_opcode
(splev
, SPO_PUSH
, switch_case_list
[i
]);
909 add_opcode
(splev
, SPO_JE
, NULL
);
912 if
(switch_default_case
) {
913 set_opvar_int
(switch_default_case
,
914 switch_default_case
->vardata.l
- splev
->n_opcodes
-1);
915 add_opcode
(splev
, SPO_PUSH
, switch_default_case
);
916 add_opcode
(splev
, SPO_JMP
, NULL
);
919 set_opvar_int
(endjump
, splev
->n_opcodes
- endjump
->vardata.l
);
921 break_stmt_end
(splev
);
923 add_opcode
(splev
, SPO_POP
, NULL
); /* get rid of the value in stack */
924 in_switch_statement
--;
930 switchcases
: /* nothing */
931 | switchcase switchcases
934 switchcase
: CASE_ID all_integers
':'
936 if
(n_switch_case_list
< MAX_SWITCH_CASES
) {
937 struct opvar
*tmppush
= New
(struct opvar
);
938 set_opvar_int
(tmppush
, splev
->n_opcodes
);
939 switch_case_value
[n_switch_case_list
] = $2;
940 switch_case_list
[n_switch_case_list
++] = tmppush
;
941 } else lc_error
("Too many cases in a switch.");
948 struct opvar
*tmppush
= New
(struct opvar
);
950 if
(switch_default_case
)
951 lc_error
("Switch default case already used.");
953 set_opvar_int
(tmppush
, splev
->n_opcodes
);
954 switch_default_case
= tmppush
;
961 breakstatement
: BREAK_ID
963 if
(!allow_break_statements
)
964 lc_error
("Cannot use BREAK outside a statement block.");
966 break_stmt_new
(splev
, splev
->n_opcodes
);
971 for_to_span
: '.' '.'
975 forstmt_start
: FOR_ID any_var_or_unk
'=' math_expr_var for_to_span math_expr_var
977 char buf
[256], buf2
[256];
979 if
(n_forloops
>= MAX_NESTED_IFS
) {
980 lc_error
("FOR: Too deeply nested loops.");
981 n_forloops
= MAX_NESTED_IFS
- 1;
984 /* first, define a variable for the for-loop end value */
985 Sprintf
(buf
, "%s end", $2);
986 /* the value of which is already in stack (the 2nd math_expr) */
987 add_opvars
(splev
, "iso", VA_PASS3
(0, buf
, SPO_VAR_INIT
));
989 variable_definitions
= add_vardef_type
(variable_definitions
,
991 /* define the for-loop variable. value is in stack (1st math_expr) */
992 add_opvars
(splev
, "iso", VA_PASS3
(0, $2, SPO_VAR_INIT
));
994 /* calculate value for the loop "step" variable */
995 Sprintf
(buf2
, "%s step", $2);
997 add_opvars
(splev
, "vvo",
998 VA_PASS3
(buf
, $2, SPO_MATH_SUB
));
1000 add_opvars
(splev
, "o", VA_PASS1
(SPO_MATH_SIGN
));
1001 /* save the sign into the step var */
1002 add_opvars
(splev
, "iso",
1003 VA_PASS3
(0, buf2
, SPO_VAR_INIT
));
1005 forloop_list
[n_forloops
].varname
= strdup
($2);
1006 forloop_list
[n_forloops
].jmp_point
= splev
->n_opcodes
;
1013 forstatement
: forstmt_start
1020 char buf
[256], buf2
[256];
1023 Sprintf
(buf
, "%s step", forloop_list
[n_forloops
].varname
);
1024 Sprintf
(buf2
, "%s end", forloop_list
[n_forloops
].varname
);
1025 /* compare for-loop var to end value */
1026 add_opvars
(splev
, "vvo",
1027 VA_PASS3
(forloop_list
[n_forloops
].varname
,
1030 add_opvars
(splev
, "vvo",
1031 VA_PASS3
(buf
, forloop_list
[n_forloops
].varname
,
1033 /* for-loop var = (for-loop var + step) */
1034 add_opvars
(splev
, "iso",
1035 VA_PASS3
(0, forloop_list
[n_forloops
].varname
,
1037 /* jump back if compared values were not equal */
1038 add_opvars
(splev
, "io",
1040 forloop_list
[n_forloops
].jmp_point
- splev
->n_opcodes
- 1,
1042 Free
(forloop_list
[n_forloops
].varname
);
1043 break_stmt_end
(splev
);
1047 loopstatement
: LOOP_ID
'[' integer_or_var
']'
1049 struct opvar
*tmppush
= New
(struct opvar
);
1051 if
(n_if_list
>= MAX_NESTED_IFS
) {
1052 lc_error
("LOOP: Too deeply nested conditionals.");
1053 n_if_list
= MAX_NESTED_IFS
- 1;
1055 set_opvar_int
(tmppush
, splev
->n_opcodes
);
1056 if_list
[n_if_list
++] = tmppush
;
1058 add_opvars
(splev
, "o", VA_PASS1
(SPO_DEC
));
1063 struct opvar
*tmppush
;
1065 add_opvars
(splev
, "oio", VA_PASS3
(SPO_COPY
, 0, SPO_CMP
));
1067 tmppush
= (struct opvar
*) if_list
[--n_if_list
];
1068 set_opvar_int
(tmppush
, tmppush
->vardata.l
- splev
->n_opcodes
-1);
1069 add_opcode
(splev
, SPO_PUSH
, tmppush
);
1070 add_opcode
(splev
, SPO_JG
, NULL
);
1071 add_opcode
(splev
, SPO_POP
, NULL
); /* get rid of the count value in stack */
1072 break_stmt_end
(splev
);
1076 chancestatement
: comparestmt
':'
1078 struct opvar
*tmppush2
= New
(struct opvar
);
1080 if
(n_if_list
>= MAX_NESTED_IFS
) {
1081 lc_error
("IF: Too deeply nested conditionals.");
1082 n_if_list
= MAX_NESTED_IFS
- 1;
1085 add_opcode
(splev
, SPO_CMP
, NULL
);
1087 set_opvar_int
(tmppush2
, splev
->n_opcodes
+1);
1089 if_list
[n_if_list
++] = tmppush2
;
1091 add_opcode
(splev
, SPO_PUSH
, tmppush2
);
1093 add_opcode
(splev
, reverse_jmp_opcode
( $1 ), NULL
);
1098 if
(n_if_list
> 0) {
1099 struct opvar
*tmppush
;
1100 tmppush
= (struct opvar
*) if_list
[--n_if_list
];
1101 set_opvar_int
(tmppush
, splev
->n_opcodes
- tmppush
->vardata.l
);
1102 } else lc_error
("IF: Huh?! No start address?");
1106 ifstatement
: IF_ID comparestmt
1108 struct opvar
*tmppush2
= New
(struct opvar
);
1110 if
(n_if_list
>= MAX_NESTED_IFS
) {
1111 lc_error
("IF: Too deeply nested conditionals.");
1112 n_if_list
= MAX_NESTED_IFS
- 1;
1115 add_opcode
(splev
, SPO_CMP
, NULL
);
1117 set_opvar_int
(tmppush2
, splev
->n_opcodes
+1);
1119 if_list
[n_if_list
++] = tmppush2
;
1121 add_opcode
(splev
, SPO_PUSH
, tmppush2
);
1123 add_opcode
(splev
, reverse_jmp_opcode
( $2 ), NULL
);
1132 if_ending
: stmt_block
1134 if
(n_if_list
> 0) {
1135 struct opvar
*tmppush
;
1136 tmppush
= (struct opvar
*) if_list
[--n_if_list
];
1137 set_opvar_int
(tmppush
, splev
->n_opcodes
- tmppush
->vardata.l
);
1138 } else lc_error
("IF: Huh?! No start address?");
1142 if
(n_if_list
> 0) {
1143 struct opvar
*tmppush
= New
(struct opvar
);
1144 struct opvar
*tmppush2
;
1146 set_opvar_int
(tmppush
, splev
->n_opcodes
+1);
1147 add_opcode
(splev
, SPO_PUSH
, tmppush
);
1149 add_opcode
(splev
, SPO_JMP
, NULL
);
1151 tmppush2
= (struct opvar
*) if_list
[--n_if_list
];
1153 set_opvar_int
(tmppush2
, splev
->n_opcodes
- tmppush2
->vardata.l
);
1154 if_list
[n_if_list
++] = tmppush
;
1155 } else lc_error
("IF: Huh?! No else-part address?");
1159 if
(n_if_list
> 0) {
1160 struct opvar
*tmppush
;
1161 tmppush
= (struct opvar
*) if_list
[--n_if_list
];
1162 set_opvar_int
(tmppush
, splev
->n_opcodes
- tmppush
->vardata.l
);
1163 } else lc_error
("IF: Huh?! No end address?");
1167 message
: MESSAGE_ID
':' string_expr
1169 add_opvars
(splev
, "o", VA_PASS1
(SPO_MESSAGE
));
1173 random_corridors: RAND_CORRIDOR_ID
1175 add_opvars
(splev
, "iiiiiio",
1176 VA_PASS7
(-1, 0, -1, -1, -1, -1, SPO_CORRIDOR
));
1178 | RAND_CORRIDOR_ID
':' all_integers
1180 add_opvars
(splev
, "iiiiiio",
1181 VA_PASS7
(-1, $3, -1, -1, -1, -1, SPO_CORRIDOR
));
1183 | RAND_CORRIDOR_ID
':' RANDOM_TYPE
1185 add_opvars
(splev
, "iiiiiio",
1186 VA_PASS7
(-1, -1, -1, -1, -1, -1, SPO_CORRIDOR
));
1190 corridor
: CORRIDOR_ID
':' corr_spec
',' corr_spec
1192 add_opvars
(splev
, "iiiiiio",
1193 VA_PASS7
($3.room
, $3.door
, $3.wall
,
1194 $5.room
, $5.door
, $5.wall
,
1197 | CORRIDOR_ID
':' corr_spec
',' all_integers
1199 add_opvars
(splev
, "iiiiiio",
1200 VA_PASS7
($3.room
, $3.door
, $3.wall
,
1206 corr_spec
: '(' INTEGER
',' DIRECTION
',' door_pos
')'
1214 room_begin
: room_type opt_percent
',' light_state
1216 if
(($2 < 100) && ($1 == OROOM
))
1217 lc_error
("Only typed rooms can have a chance.");
1219 add_opvars
(splev
, "iii",
1220 VA_PASS3
((long)$1, (long)$2, (long)$4));
1225 subroom_def
: SUBROOM_ID
':' room_begin
',' subroom_pos
',' room_size optroomregionflags
1229 if
(rflags
== -1) rflags
= (1 << 0);
1230 add_opvars
(splev
, "iiiiiiio",
1231 VA_PASS8
(rflags
, ERR
, ERR
,
1232 $5.x
, $5.y
, $7.width
, $7.height
,
1238 break_stmt_end
(splev
);
1239 add_opcode
(splev
, SPO_ENDROOM
, NULL
);
1243 room_def
: ROOM_ID
':' room_begin
',' room_pos
',' room_align
',' room_size optroomregionflags
1247 if
(rflags
== -1) rflags
= (1 << 0);
1248 add_opvars
(splev
, "iiiiiiio",
1250 $7.x
, $7.y
, $5.x
, $5.y
,
1251 $9.width
, $9.height
, SPO_ROOM
));
1256 break_stmt_end
(splev
);
1257 add_opcode
(splev
, SPO_ENDROOM
, NULL
);
1261 roomfill
: /* nothing */
1271 room_pos
: '(' INTEGER
',' INTEGER
')'
1273 if
( $2 < 1 ||
$2 > 5 ||
1274 $4 < 1 ||
$4 > 5 ) {
1275 lc_error
("Room positions should be between 1-5: (%li,%li)!", $2, $4);
1287 subroom_pos
: '(' INTEGER
',' INTEGER
')'
1289 if
( $2 < 0 ||
$4 < 0) {
1290 lc_error
("Invalid subroom position (%li,%li)!", $2, $4);
1302 room_align
: '(' h_justif
',' v_justif
')'
1313 room_size
: '(' INTEGER
',' INTEGER
')'
1320 $$.height
= $$.width
= ERR
;
1324 door_detail
: ROOMDOOR_ID
':' secret
',' door_state
',' door_wall
',' door_pos
1326 /* ERR means random here */
1327 if
($7 == ERR
&& $9 != ERR
) {
1328 lc_error
("If the door wall is random, so must be its pos!");
1330 add_opvars
(splev
, "iiiio",
1331 VA_PASS5
((long)$9, (long)$5, (long)$3,
1332 (long)$7, SPO_ROOM_DOOR
));
1335 | DOOR_ID
':' door_state
',' ter_selection
1337 add_opvars
(splev
, "io", VA_PASS2
((long)$3, SPO_DOOR
));
1345 door_wall
: dir_list
1349 dir_list
: DIRECTION
1353 | DIRECTION
'|' dir_list
1363 map_definition
: NOMAP_ID
1365 add_opvars
(splev
, "ciisiio",
1366 VA_PASS7
(0, 0, 1, (char *)0, 0, 0, SPO_MAP
));
1367 max_x_map
= COLNO
-1;
1370 | GEOMETRY_ID
':' h_justif
',' v_justif roomfill MAP_ID
1372 add_opvars
(splev
, "cii",
1373 VA_PASS3
(SP_COORD_PACK
(($3),($5)),
1375 scan_map
($7, splev
);
1378 | GEOMETRY_ID
':' coord_or_var roomfill MAP_ID
1380 add_opvars
(splev
, "ii", VA_PASS2
(2, (long)$4));
1381 scan_map
($5, splev
);
1386 h_justif
: LEFT_OR_RIGHT
1390 v_justif
: TOP_OR_BOT
1394 monster_detail
: MONSTER_ID
':' monster_desc
1396 add_opvars
(splev
, "io", VA_PASS2
(0, SPO_MONSTER
));
1398 | MONSTER_ID
':' monster_desc
1400 add_opvars
(splev
, "io", VA_PASS2
(1, SPO_MONSTER
));
1406 break_stmt_end
(splev
);
1408 add_opvars
(splev
, "o", VA_PASS1
(SPO_END_MONINVENT
));
1412 monster_desc
: monster_or_var
',' coord_or_var monster_infos
1418 monster_infos
: /* nothing */
1420 struct opvar
*stopit
= New
(struct opvar
);
1421 set_opvar_int
(stopit
, SP_M_V_END
);
1422 add_opcode
(splev
, SPO_PUSH
, stopit
);
1425 | monster_infos
',' monster_info
1428 lc_error
("MONSTER extra info defined twice.");
1433 monster_info
: string_expr
1435 add_opvars
(splev
, "i", VA_PASS1
(SP_M_V_NAME
));
1440 add_opvars
(splev
, "ii",
1441 VA_PASS2
((long)$
<i
>1, SP_M_V_PEACEFUL
));
1446 add_opvars
(splev
, "ii",
1447 VA_PASS2
((long)$
<i
>1, SP_M_V_ASLEEP
));
1452 add_opvars
(splev
, "ii",
1453 VA_PASS2
((long)$1, SP_M_V_ALIGN
));
1456 | MON_APPEARANCE string_expr
1458 add_opvars
(splev
, "ii",
1459 VA_PASS2
((long)$
<i
>1, SP_M_V_APPEAR
));
1464 add_opvars
(splev
, "ii", VA_PASS2
(1, SP_M_V_FEMALE
));
1469 add_opvars
(splev
, "ii", VA_PASS2
(1, SP_M_V_INVIS
));
1474 add_opvars
(splev
, "ii", VA_PASS2
(1, SP_M_V_CANCELLED
));
1479 add_opvars
(splev
, "ii", VA_PASS2
(1, SP_M_V_REVIVED
));
1484 add_opvars
(splev
, "ii", VA_PASS2
(1, SP_M_V_AVENGE
));
1487 | FLEEING_ID
':' integer_or_var
1489 add_opvars
(splev
, "i", VA_PASS1
(SP_M_V_FLEEING
));
1492 | BLINDED_ID
':' integer_or_var
1494 add_opvars
(splev
, "i", VA_PASS1
(SP_M_V_BLINDED
));
1497 | PARALYZED_ID
':' integer_or_var
1499 add_opvars
(splev
, "i", VA_PASS1
(SP_M_V_PARALYZED
));
1504 add_opvars
(splev
, "ii", VA_PASS2
(1, SP_M_V_STUNNED
));
1509 add_opvars
(splev
, "ii", VA_PASS2
(1, SP_M_V_CONFUSED
));
1512 | SEENTRAPS_ID
':' seen_trap_mask
1514 add_opvars
(splev
, "ii",
1515 VA_PASS2
((long)$3, SP_M_V_SEENTRAPS
));
1520 seen_trap_mask
: STRING
1522 int token
= get_trap_type
($1);
1523 if
(token
== ERR || token
== 0)
1524 lc_error
("Unknown trap type '%s'!", $1);
1526 $$
= (1L << (token
- 1));
1532 | STRING
'|' seen_trap_mask
1534 int token
= get_trap_type
($1);
1535 if
(token
== ERR || token
== 0)
1536 lc_error
("Unknown trap type '%s'!", $1);
1538 if
((1L << (token
- 1)) & $3)
1539 lc_error
("Monster seen_traps, trap '%s' listed twice.", $1);
1541 $$
= ((1L << (token
- 1)) |
$3);
1545 object_detail
: OBJECT_ID
':' object_desc
1548 if
(in_container_obj
) cnt |
= SP_OBJ_CONTENT
;
1549 add_opvars
(splev
, "io", VA_PASS2
(cnt
, SPO_OBJECT
));
1551 | COBJECT_ID
':' object_desc
1553 long cnt
= SP_OBJ_CONTAINER
;
1554 if
(in_container_obj
) cnt |
= SP_OBJ_CONTENT
;
1555 add_opvars
(splev
, "io", VA_PASS2
(cnt
, SPO_OBJECT
));
1561 break_stmt_end
(splev
);
1563 add_opcode
(splev
, SPO_POP_CONTAINER
, NULL
);
1567 object_desc
: object_or_var object_infos
1569 if
(( $2 & 0x4000) && in_container_obj
)
1570 lc_error
("Object cannot have a coord when contained.");
1571 else if
(!( $2 & 0x4000) && !in_container_obj
)
1572 lc_error
("Object needs a coord when not contained.");
1576 object_infos
: /* nothing */
1578 struct opvar
*stopit
= New
(struct opvar
);
1579 set_opvar_int
(stopit
, SP_O_V_END
);
1580 add_opcode
(splev
, SPO_PUSH
, stopit
);
1583 | object_infos
',' object_info
1586 lc_error
("OBJECT extra info '%s' defined twice.", curr_token
);
1591 object_info
: CURSE_TYPE
1593 add_opvars
(splev
, "ii",
1594 VA_PASS2
((long)$1, SP_O_V_CURSE
));
1597 | MONTYPE_ID
':' monster_or_var
1599 add_opvars
(splev
, "i", VA_PASS1
(SP_O_V_CORPSENM
));
1604 add_opvars
(splev
, "i", VA_PASS1
(SP_O_V_SPE
));
1607 | NAME_ID
':' string_expr
1609 add_opvars
(splev
, "i", VA_PASS1
(SP_O_V_NAME
));
1612 | QUANTITY_ID
':' integer_or_var
1614 add_opvars
(splev
, "i", VA_PASS1
(SP_O_V_QUAN
));
1619 add_opvars
(splev
, "ii", VA_PASS2
(1, SP_O_V_BURIED
));
1624 add_opvars
(splev
, "ii", VA_PASS2
((long)$1, SP_O_V_LIT
));
1627 | ERODED_ID
':' integer_or_var
1629 add_opvars
(splev
, "i", VA_PASS1
(SP_O_V_ERODED
));
1634 add_opvars
(splev
, "ii", VA_PASS2
(-1, SP_O_V_ERODED
));
1639 if
($1 == D_LOCKED
) {
1640 add_opvars
(splev
, "ii", VA_PASS2
(1, SP_O_V_LOCKED
));
1642 } else if
($1 == D_BROKEN
) {
1643 add_opvars
(splev
, "ii", VA_PASS2
(1, SP_O_V_BROKEN
));
1646 lc_error
("DOOR state can only be locked or broken.");
1650 add_opvars
(splev
, "ii", VA_PASS2
($1, SP_O_V_TRAPPED
));
1653 | RECHARGED_ID
':' integer_or_var
1655 add_opvars
(splev
, "i", VA_PASS1
(SP_O_V_RECHARGED
));
1660 add_opvars
(splev
, "ii", VA_PASS2
(1, SP_O_V_INVIS
));
1665 add_opvars
(splev
, "ii", VA_PASS2
(1, SP_O_V_GREASED
));
1670 add_opvars
(splev
, "i", VA_PASS1
(SP_O_V_COORD
));
1675 trap_detail
: TRAP_ID
':' trap_name
',' coord_or_var
1677 add_opvars
(splev
, "io", VA_PASS2
((long)$3, SPO_TRAP
));
1681 drawbridge_detail: DRAWBRIDGE_ID
':' coord_or_var
',' DIRECTION
',' door_state
1683 long dir
, state
= 0;
1685 /* convert dir from a DIRECTION to a DB_DIR */
1688 case W_NORTH
: dir
= DB_NORTH
; break
;
1689 case W_SOUTH
: dir
= DB_SOUTH
; break
;
1690 case W_EAST
: dir
= DB_EAST
; break
;
1691 case W_WEST
: dir
= DB_WEST
; break
;
1693 lc_error
("Invalid drawbridge direction.");
1697 if
( $7 == D_ISOPEN
)
1699 else if
( $7 == D_CLOSED
)
1701 else if
( $7 == -1 )
1704 lc_error
("A drawbridge can only be open, closed or random!");
1705 add_opvars
(splev
, "iio",
1706 VA_PASS3
(state
, dir
, SPO_DRAWBRIDGE
));
1710 mazewalk_detail
: MAZEWALK_ID
':' coord_or_var
',' DIRECTION
1712 add_opvars
(splev
, "iiio",
1713 VA_PASS4
((long)$5, 1, 0, SPO_MAZEWALK
));
1715 | MAZEWALK_ID
':' coord_or_var
',' DIRECTION
',' BOOLEAN opt_fillchar
1717 add_opvars
(splev
, "iiio",
1718 VA_PASS4
((long)$5, (long)$
<i
>7,
1719 (long)$8, SPO_MAZEWALK
));
1723 wallify_detail
: WALLIFY_ID
1725 add_opvars
(splev
, "rio",
1726 VA_PASS3
(SP_REGION_PACK
(-1,-1,-1,-1),
1729 | WALLIFY_ID
':' ter_selection
1731 add_opvars
(splev
, "io", VA_PASS2
(1, SPO_WALLIFY
));
1735 ladder_detail
: LADDER_ID
':' coord_or_var
',' UP_OR_DOWN
1737 add_opvars
(splev
, "io",
1738 VA_PASS2
((long)$
<i
>5, SPO_LADDER
));
1742 stair_detail
: STAIR_ID
':' coord_or_var
',' UP_OR_DOWN
1744 add_opvars
(splev
, "io",
1745 VA_PASS2
((long)$
<i
>5, SPO_STAIR
));
1749 stair_region
: STAIR_ID
':' lev_region
',' lev_region
',' UP_OR_DOWN
1751 add_opvars
(splev
, "iiiii iiiii iiso",
1752 VA_PASS14
($3.x1
, $3.y1
, $3.x2
, $3.y2
, $3.area
,
1753 $5.x1
, $5.y1
, $5.x2
, $5.y2
, $5.area
,
1754 (long) (($7) ? LR_UPSTAIR
: LR_DOWNSTAIR
),
1755 0, (char *) 0, SPO_LEVREGION
));
1759 portal_region
: PORTAL_ID
':' lev_region
',' lev_region
',' STRING
1761 add_opvars
(splev
, "iiiii iiiii iiso",
1762 VA_PASS14
($3.x1
, $3.y1
, $3.x2
, $3.y2
, $3.area
,
1763 $5.x1
, $5.y1
, $5.x2
, $5.y2
, $5.area
,
1764 LR_PORTAL
, 0, $7, SPO_LEVREGION
));
1769 teleprt_region
: TELEPRT_ID
':' lev_region
',' lev_region teleprt_detail
1773 case
-1: rtyp
= LR_TELE
; break
;
1774 case
0: rtyp
= LR_DOWNTELE
; break
;
1775 case
1: rtyp
= LR_UPTELE
; break
;
1777 add_opvars
(splev
, "iiiii iiiii iiso",
1778 VA_PASS14
($3.x1
, $3.y1
, $3.x2
, $3.y2
, $3.area
,
1779 $5.x1
, $5.y1
, $5.x2
, $5.y2
, $5.area
,
1780 rtyp
, 0, (char *)0, SPO_LEVREGION
));
1784 branch_region
: BRANCH_ID
':' lev_region
',' lev_region
1786 add_opvars
(splev
, "iiiii iiiii iiso",
1787 VA_PASS14
($3.x1
, $3.y1
, $3.x2
, $3.y2
, $3.area
,
1788 $5.x1
, $5.y1
, $5.x2
, $5.y2
, $5.area
,
1789 (long) LR_BRANCH
, 0,
1790 (char *) 0, SPO_LEVREGION
));
1794 teleprt_detail
: /* empty */
1804 fountain_detail
: FOUNTAIN_ID
':' ter_selection
1806 add_opvars
(splev
, "o", VA_PASS1
(SPO_FOUNTAIN
));
1810 sink_detail
: SINK_ID
':' ter_selection
1812 add_opvars
(splev
, "o", VA_PASS1
(SPO_SINK
));
1816 pool_detail
: POOL_ID
':' ter_selection
1818 add_opvars
(splev
, "o", VA_PASS1
(SPO_POOL
));
1825 $$.ter
= what_map_char
((char) $
<i
>1);
1827 |
'(' CHAR
',' light_state
')'
1830 $$.ter
= what_map_char
((char) $
<i
>2);
1834 replace_terrain_detail
: REPLACE_TERRAIN_ID
':' region_or_var
',' mapchar_or_var
',' mapchar_or_var
',' SPERCENT
1836 add_opvars
(splev
, "io",
1837 VA_PASS2
($9, SPO_REPLACETERRAIN
));
1841 terrain_detail
: TERRAIN_ID
':' ter_selection
',' mapchar_or_var
1843 add_opvars
(splev
, "o", VA_PASS1
(SPO_TERRAIN
));
1847 diggable_detail
: NON_DIGGABLE_ID
':' region_or_var
1849 add_opvars
(splev
, "o", VA_PASS1
(SPO_NON_DIGGABLE
));
1853 passwall_detail
: NON_PASSWALL_ID
':' region_or_var
1855 add_opvars
(splev
, "o", VA_PASS1
(SPO_NON_PASSWALL
));
1859 region_detail
: REGION_ID
':' region_or_var
',' light_state
',' room_type optroomregionflags
1865 if
(rflags
== -1) rflags
= (1 << 0);
1866 if
(!(rflags
& 1)) rt
+= MAXRTYPE
+1;
1867 irr
= ((rflags
& 2) != 0);
1868 add_opvars
(splev
, "iiio",
1869 VA_PASS4
((long)$5, rt
, rflags
, SPO_REGION
));
1870 $
<i
>$
= (irr ||
(rflags
& 1) || rt
!= OROOM
);
1875 break_stmt_end
(splev
);
1877 add_opcode
(splev
, SPO_ENDROOM
, NULL
);
1878 } else if
( $
<i
>10 )
1879 lc_error
("Cannot use lev statements in non-permanent REGION");
1883 region_detail_end
: /* nothing */
1893 altar_detail
: ALTAR_ID
':' coord_or_var
',' alignment
',' altar_type
1895 add_opvars
(splev
, "iio",
1896 VA_PASS3
((long)$7, (long)$5, SPO_ALTAR
));
1900 grave_detail
: GRAVE_ID
':' coord_or_var
',' string_expr
1902 add_opvars
(splev
, "io", VA_PASS2
(2, SPO_GRAVE
));
1904 | GRAVE_ID
':' coord_or_var
',' RANDOM_TYPE
1906 add_opvars
(splev
, "sio",
1907 VA_PASS3
((char *)0, 1, SPO_GRAVE
));
1909 | GRAVE_ID
':' coord_or_var
1911 add_opvars
(splev
, "sio",
1912 VA_PASS3
((char *)0, 0, SPO_GRAVE
));
1916 gold_detail
: GOLD_ID
':' math_expr_var
',' coord_or_var
1918 add_opvars
(splev
, "o", VA_PASS1
(SPO_GOLD
));
1922 engraving_detail: ENGRAVING_ID
':' coord_or_var
',' engraving_type
',' string_expr
1924 add_opvars
(splev
, "io",
1925 VA_PASS2
((long)$5, SPO_ENGRAVING
));
1929 mineralize
: MINERALIZE_ID
':' integer_or_var
',' integer_or_var
',' integer_or_var
',' integer_or_var
1931 add_opvars
(splev
, "o", VA_PASS1
(SPO_MINERALIZE
));
1935 add_opvars
(splev
, "iiiio",
1936 VA_PASS5
(-1L, -1L, -1L, -1L, SPO_MINERALIZE
));
1942 int token
= get_trap_type
($1);
1944 lc_error
("Unknown trap type '%s'!", $1);
1953 int token
= get_room_type
($1);
1955 lc_warning
("Unknown room type \"%s\"! Making ordinary room...", $1);
1964 optroomregionflags
: /* empty */
1968 |
',' roomregionflags
1974 roomregionflags
: roomregionflag
1978 | roomregionflag
',' roomregionflags
1984 /* 0 is the "default" here */
1985 roomregionflag
: FILLING
1999 door_state
: DOOR_STATE
2003 light_state
: LIGHT_STATE
2007 alignment
: ALIGNMENT
2011 $$
= - MAX_REGISTERS
- 1;
2015 alignment_prfx
: ALIGNMENT
2017 | A_REGISTER
':' RANDOM_TYPE
2019 $$
= - MAX_REGISTERS
- 1;
2023 altar_type
: ALTAR_TYPE
2027 a_register
: A_REGISTER
'[' INTEGER
']'
2030 lc_error
("Register Index overflow!");
2036 string_or_var
: STRING
2038 add_opvars
(splev
, "s", VA_PASS1
($1));
2043 check_vardef_type
(variable_definitions
, $1, SPOVAR_STRING
);
2044 vardef_used
(variable_definitions
, $1);
2045 add_opvars
(splev
, "v", VA_PASS1
($1));
2048 | VARSTRING_STRING_ARRAY
'[' math_expr_var
']'
2050 check_vardef_type
(variable_definitions
, $1, SPOVAR_STRING|SPOVAR_ARRAY
);
2051 vardef_used
(variable_definitions
, $1);
2052 add_opvars
(splev
, "v", VA_PASS1
($1));
2058 integer_or_var
: math_expr_var
2064 coord_or_var
: encodecoord
2066 add_opvars
(splev
, "c", VA_PASS1
($1));
2068 | rndcoord_ID
'(' ter_selection
')'
2070 add_opvars
(splev
, "o", VA_PASS1
(SPO_SEL_RNDCOORD
));
2074 check_vardef_type
(variable_definitions
, $1, SPOVAR_COORD
);
2075 vardef_used
(variable_definitions
, $1);
2076 add_opvars
(splev
, "v", VA_PASS1
($1));
2079 | VARSTRING_COORD_ARRAY
'[' math_expr_var
']'
2081 check_vardef_type
(variable_definitions
, $1, SPOVAR_COORD|SPOVAR_ARRAY
);
2082 vardef_used
(variable_definitions
, $1);
2083 add_opvars
(splev
, "v", VA_PASS1
($1));
2088 encodecoord
: '(' INTEGER
',' INTEGER
')'
2090 if
($2 < 0 ||
$4 < 0 ||
$2 >= COLNO ||
$4 >= ROWNO
)
2091 lc_error
("Coordinates (%li,%li) out of map range!", $2, $4);
2092 $$
= SP_COORD_PACK
($2, $4);
2096 $$
= SP_COORD_PACK_RANDOM
(0);
2098 | RANDOM_TYPE_BRACKET humidity_flags
']'
2100 $$
= SP_COORD_PACK_RANDOM
( $2 );
2104 humidity_flags
: HUMIDITY_TYPE
2108 | HUMIDITY_TYPE
',' humidity_flags
2111 lc_warning
("Humidity flag used twice.");
2116 region_or_var
: encoderegion
2122 check_vardef_type
(variable_definitions
, $1, SPOVAR_REGION
);
2123 vardef_used
(variable_definitions
, $1);
2124 add_opvars
(splev
, "v", VA_PASS1
($1));
2127 | VARSTRING_REGION_ARRAY
'[' math_expr_var
']'
2129 check_vardef_type
(variable_definitions
, $1, SPOVAR_REGION|SPOVAR_ARRAY
);
2130 vardef_used
(variable_definitions
, $1);
2131 add_opvars
(splev
, "v", VA_PASS1
($1));
2136 encoderegion
: '(' INTEGER
',' INTEGER
',' INTEGER
',' INTEGER
')'
2138 long r
= SP_REGION_PACK
($2, $4, $6, $8);
2139 if
( $2 > $6 ||
$4 > $8 )
2140 lc_error
("Region start > end: (%li,%li,%li,%li)!", $2, $4, $6, $8);
2142 add_opvars
(splev
, "r", VA_PASS1
(r
));
2147 mapchar_or_var
: mapchar
2149 add_opvars
(splev
, "m", VA_PASS1
($1));
2153 check_vardef_type
(variable_definitions
, $1, SPOVAR_MAPCHAR
);
2154 vardef_used
(variable_definitions
, $1);
2155 add_opvars
(splev
, "v", VA_PASS1
($1));
2158 | VARSTRING_MAPCHAR_ARRAY
'[' math_expr_var
']'
2160 check_vardef_type
(variable_definitions
, $1, SPOVAR_MAPCHAR|SPOVAR_ARRAY
);
2161 vardef_used
(variable_definitions
, $1);
2162 add_opvars
(splev
, "v", VA_PASS1
($1));
2169 if
(what_map_char
((char) $1) != INVALID_TYPE
)
2170 $$
= SP_MAPCHAR_PACK
(what_map_char
((char) $1), -2);
2172 lc_error
("Unknown map char type '%c'!", $1);
2173 $$
= SP_MAPCHAR_PACK
(STONE
, -2);
2176 |
'(' CHAR
',' light_state
')'
2178 if
(what_map_char
((char) $2) != INVALID_TYPE
)
2179 $$
= SP_MAPCHAR_PACK
(what_map_char
((char) $2), $4);
2181 lc_error
("Unknown map char type '%c'!", $2);
2182 $$
= SP_MAPCHAR_PACK
(STONE
, $4);
2187 monster_or_var
: encodemonster
2189 add_opvars
(splev
, "M", VA_PASS1
($1));
2193 check_vardef_type
(variable_definitions
, $1, SPOVAR_MONST
);
2194 vardef_used
(variable_definitions
, $1);
2195 add_opvars
(splev
, "v", VA_PASS1
($1));
2198 | VARSTRING_MONST_ARRAY
'[' math_expr_var
']'
2200 check_vardef_type
(variable_definitions
, $1, SPOVAR_MONST|SPOVAR_ARRAY
);
2201 vardef_used
(variable_definitions
, $1);
2202 add_opvars
(splev
, "v", VA_PASS1
($1));
2207 encodemonster
: STRING
2209 long m
= get_monster_id
($1, (char)0);
2211 lc_error
("Unknown monster \"%s\"!", $1);
2214 $$
= SP_MONST_PACK
(m
,
2215 def_monsyms
[(int) mons
[m
].mlet
].sym
);
2220 if
(check_monster_char
((char) $1))
2221 $$
= SP_MONST_PACK
(-1, $1);
2223 lc_error
("Unknown monster class '%c'!", $1);
2227 |
'(' CHAR
',' STRING
')'
2229 long m
= get_monster_id
($4, (char) $2);
2231 lc_error
("Unknown monster ('%c', \"%s\")!", $2, $4);
2234 $$
= SP_MONST_PACK
(m
, $2);
2243 object_or_var
: encodeobj
2245 add_opvars
(splev
, "O", VA_PASS1
($1));
2249 check_vardef_type
(variable_definitions
, $1, SPOVAR_OBJ
);
2250 vardef_used
(variable_definitions
, $1);
2251 add_opvars
(splev
, "v", VA_PASS1
($1));
2254 | VARSTRING_OBJ_ARRAY
'[' math_expr_var
']'
2256 check_vardef_type
(variable_definitions
, $1, SPOVAR_OBJ|SPOVAR_ARRAY
);
2257 vardef_used
(variable_definitions
, $1);
2258 add_opvars
(splev
, "v", VA_PASS1
($1));
2265 long m
= get_object_id
($1, (char)0);
2267 lc_error
("Unknown object \"%s\"!", $1);
2270 $$
= SP_OBJ_PACK
(m
, 1); /* obj class != 0 to force generation of a specific item */
2275 if
(check_object_char
((char) $1))
2276 $$
= SP_OBJ_PACK
(-1, $1);
2278 lc_error
("Unknown object class '%c'!", $1);
2282 |
'(' CHAR
',' STRING
')'
2284 long m
= get_object_id
($4, (char) $2);
2286 lc_error
("Unknown object ('%c', \"%s\")!", $2, $4);
2289 $$
= SP_OBJ_PACK
(m
, $2);
2299 string_expr
: string_or_var
{ }
2300 | string_expr
'.' string_or_var
2302 add_opvars
(splev
, "o", VA_PASS1
(SPO_MATH_ADD
));
2306 math_expr_var
: INTEGER
2308 add_opvars
(splev
, "i", VA_PASS1
($1));
2312 is_inconstant_number
= 1;
2314 |
'(' MINUS_INTEGER
')'
2316 add_opvars
(splev
, "i", VA_PASS1
($2));
2320 check_vardef_type
(variable_definitions
, $1, SPOVAR_INT
);
2321 vardef_used
(variable_definitions
, $1);
2322 add_opvars
(splev
, "v", VA_PASS1
($1));
2324 is_inconstant_number
= 1;
2326 | VARSTRING_INT_ARRAY
'[' math_expr_var
']'
2328 check_vardef_type
(variable_definitions
,
2329 $1, SPOVAR_INT|SPOVAR_ARRAY
);
2330 vardef_used
(variable_definitions
, $1);
2331 add_opvars
(splev
, "v", VA_PASS1
($1));
2333 is_inconstant_number
= 1;
2335 | math_expr_var
'+' math_expr_var
2337 add_opvars
(splev
, "o", VA_PASS1
(SPO_MATH_ADD
));
2339 | math_expr_var
'-' math_expr_var
2341 add_opvars
(splev
, "o", VA_PASS1
(SPO_MATH_SUB
));
2343 | math_expr_var
'*' math_expr_var
2345 add_opvars
(splev
, "o", VA_PASS1
(SPO_MATH_MUL
));
2347 | math_expr_var
'/' math_expr_var
2349 add_opvars
(splev
, "o", VA_PASS1
(SPO_MATH_DIV
));
2351 | math_expr_var
'%' math_expr_var
2353 add_opvars
(splev
, "o", VA_PASS1
(SPO_MATH_MOD
));
2355 |
'(' math_expr_var
')' { }
2358 func_param_type
: CFUNC_INT
2360 if
(!strcmp
("int", $1) ||
!strcmp
("integer", $1)) {
2363 lc_error
("Unknown function parameter type '%s'", $1);
2367 if
(!strcmp
("str", $1) ||
!strcmp
("string", $1)) {
2370 lc_error
("Unknown function parameter type '%s'", $1);
2374 func_param_part
: any_var_or_arr
':' func_param_type
2376 struct lc_funcdefs_parm
*tmp
= New
(struct lc_funcdefs_parm
);
2378 if
(!curr_function
) {
2379 lc_error
("Function parameters outside function definition.");
2381 lc_error
("Could not alloc function params.");
2384 tmp
->name
= strdup
($1);
2385 tmp
->parmtype
= (char) $3;
2386 tmp
->next
= curr_function
->params
;
2387 curr_function
->params
= tmp
;
2388 curr_function
->n_params
++;
2389 switch
(tmp
->parmtype
) {
2390 case
'i': vt
= SPOVAR_INT
; break
;
2391 case
's': vt
= SPOVAR_STRING
; break
;
2392 default
: lc_error
("Unknown func param conversion."); break
;
2394 variable_definitions
= add_vardef_type
(
2395 variable_definitions
,
2402 func_param_list
: func_param_part
2403 | func_param_list
',' func_param_part
2406 func_params_list
: /* nothing */
2410 func_call_param_part
: math_expr_var
2421 func_call_param_list
: func_call_param_part
2424 tmpbuf
[0] = (char) $1;
2426 $$
= strdup
(tmpbuf
);
2428 | func_call_param_list
',' func_call_param_part
2430 long len
= strlen
( $1 );
2431 char *tmp
= (char *) alloc
(len
+ 2);
2432 sprintf
(tmp
, "%c%s", (char) $3, $1 );
2438 func_call_params_list
: /* nothing */
2442 | func_call_param_list
2444 char *tmp
= strdup
( $1 );
2450 ter_selection_x
: coord_or_var
2452 add_opvars
(splev
, "o", VA_PASS1
(SPO_SEL_POINT
));
2454 | rect_ID region_or_var
2456 add_opvars
(splev
, "o", VA_PASS1
(SPO_SEL_RECT
));
2458 | fillrect_ID region_or_var
2460 add_opvars
(splev
, "o", VA_PASS1
(SPO_SEL_FILLRECT
));
2462 | line_ID coord_or_var
',' coord_or_var
2464 add_opvars
(splev
, "o", VA_PASS1
(SPO_SEL_LINE
));
2466 | randline_ID coord_or_var
',' coord_or_var
',' math_expr_var
2468 /* randline (x1,y1),(x2,y2), roughness */
2469 add_opvars
(splev
, "o", VA_PASS1
(SPO_SEL_RNDLINE
));
2471 | grow_ID
'(' ter_selection
')'
2473 add_opvars
(splev
, "io", VA_PASS2
(W_ANY
, SPO_SEL_GROW
));
2475 | grow_ID
'(' dir_list
',' ter_selection
')'
2477 add_opvars
(splev
, "io", VA_PASS2
($3, SPO_SEL_GROW
));
2479 | filter_ID
'(' SPERCENT
',' ter_selection
')'
2481 add_opvars
(splev
, "iio",
2482 VA_PASS3
($3, SPOFILTER_PERCENT
, SPO_SEL_FILTER
));
2484 | filter_ID
'(' ter_selection
',' ter_selection
')'
2486 add_opvars
(splev
, "io",
2487 VA_PASS2
(SPOFILTER_SELECTION
, SPO_SEL_FILTER
));
2489 | filter_ID
'(' mapchar_or_var
',' ter_selection
')'
2491 add_opvars
(splev
, "io",
2492 VA_PASS2
(SPOFILTER_MAPCHAR
, SPO_SEL_FILTER
));
2494 | flood_ID coord_or_var
2496 add_opvars
(splev
, "o", VA_PASS1
(SPO_SEL_FLOOD
));
2498 | circle_ID
'(' coord_or_var
',' math_expr_var
')'
2500 add_opvars
(splev
, "oio",
2501 VA_PASS3
(SPO_COPY
, 1, SPO_SEL_ELLIPSE
));
2503 | circle_ID
'(' coord_or_var
',' math_expr_var
',' FILLING
')'
2505 add_opvars
(splev
, "oio",
2506 VA_PASS3
(SPO_COPY
, $7, SPO_SEL_ELLIPSE
));
2508 | ellipse_ID
'(' coord_or_var
',' math_expr_var
',' math_expr_var
')'
2510 add_opvars
(splev
, "io", VA_PASS2
(1, SPO_SEL_ELLIPSE
));
2512 | ellipse_ID
'(' coord_or_var
',' math_expr_var
',' math_expr_var
',' FILLING
')'
2514 add_opvars
(splev
, "io", VA_PASS2
($9, SPO_SEL_ELLIPSE
));
2516 | gradient_ID
'(' GRADIENT_TYPE
',' '(' math_expr_var
'-' math_expr_var opt_limited
')' ',' coord_or_var opt_coord_or_var
')'
2518 add_opvars
(splev
, "iio",
2519 VA_PASS3
($9, $3, SPO_SEL_GRADIENT
));
2521 | complement_ID ter_selection_x
2523 add_opvars
(splev
, "o", VA_PASS1
(SPO_SEL_COMPLEMENT
));
2527 check_vardef_type
(variable_definitions
, $1, SPOVAR_SEL
);
2528 vardef_used
(variable_definitions
, $1);
2529 add_opvars
(splev
, "v", VA_PASS1
($1));
2532 |
'(' ter_selection
')'
2538 ter_selection
: ter_selection_x
2542 | ter_selection_x
'&' ter_selection
2544 add_opvars
(splev
, "o", VA_PASS1
(SPO_SEL_ADD
));
2550 add_opvars
(splev
, "iio",
2551 VA_PASS3
($1.num
, $1.die
, SPO_DICE
));
2555 all_integers
: MINUS_INTEGER
2560 all_ints_push
: MINUS_INTEGER
2562 add_opvars
(splev
, "i", VA_PASS1
($1));
2566 add_opvars
(splev
, "i", VA_PASS1
($1));
2570 add_opvars
(splev
, "i", VA_PASS1
($1));
2578 objectid
: object_ID
2582 monsterid
: monster_ID
2586 terrainid
: terrain_ID
2590 engraving_type
: ENGRAVING_TYPE
2598 | LEV
'(' INTEGER
',' INTEGER
',' INTEGER
',' INTEGER
')'
2600 if
($3 <= 0 ||
$3 >= COLNO
)
2602 "Region (%ld,%ld,%ld,%ld) out of level range (x1)!",
2604 else if
($5 < 0 ||
$5 >= ROWNO
)
2606 "Region (%ld,%ld,%ld,%ld) out of level range (y1)!",
2608 else if
($7 <= 0 ||
$7 >= COLNO
)
2610 "Region (%ld,%ld,%ld,%ld) out of level range (x2)!",
2612 else if
($9 < 0 ||
$9 >= ROWNO
)
2614 "Region (%ld,%ld,%ld,%ld) out of level range (y2)!",
2624 region
: '(' INTEGER
',' INTEGER
',' INTEGER
',' INTEGER
')'
2626 /* This series of if statements is a hack for MSC 5.1. It seems that its
2627 tiny little brain cannot compile if these are all one big if statement. */
2628 if
($2 < 0 ||
$2 > (int) max_x_map
)
2630 "Region (%ld,%ld,%ld,%ld) out of map range (x1)!",
2632 else if
($4 < 0 ||
$4 > (int) max_y_map
)
2634 "Region (%ld,%ld,%ld,%ld) out of map range (y1)!",
2636 else if
($6 < 0 ||
$6 > (int) max_x_map
)
2638 "Region (%ld,%ld,%ld,%ld) out of map range (x2)!",
2640 else if
($8 < 0 ||
$8 > (int) max_y_map
)
2642 "Region (%ld,%ld,%ld,%ld) out of map range (y2)!",