1 /* ------------------------------------------------------------------------- */
2 /* "expressp" : The expression parser */
4 /* Part of Inform 6.35 */
5 /* copyright (c) Graham Nelson 1993 - 2021 */
7 /* Inform is free software: you can redistribute it and/or modify */
8 /* it under the terms of the GNU General Public License as published by */
9 /* the Free Software Foundation, either version 3 of the License, or */
10 /* (at your option) any later version. */
12 /* Inform is distributed in the hope that it will be useful, */
13 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
14 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
15 /* GNU General Public License for more details. */
17 /* You should have received a copy of the GNU General Public License */
18 /* along with Inform. If not, see https://gnu.org/licenses/ */
20 /* ------------------------------------------------------------------------- */
24 /* --- Interface to lexer -------------------------------------------------- */
26 static char separators_to_operators[103];
27 static char conditionals_to_operators[7];
28 static char token_type_allowable[301];
30 #define NOT_AN_OPERATOR (char) 0x7e
32 static void make_lexical_interface_tables(void)
35 separators_to_operators[i] = NOT_AN_OPERATOR;
36 for (i=0;i<NUM_OPERATORS;i++)
37 if (operators[i].token_type == SEP_TT)
38 separators_to_operators[operators[i].token_value] = i;
40 for (i=0;i<7;i++) /* 7 being the size of keyword_group "conditions" */
41 conditionals_to_operators[i] = NOT_AN_OPERATOR;
42 for (i=0;i<NUM_OPERATORS;i++)
43 if (operators[i].token_type == CND_TT)
44 conditionals_to_operators[operators[i].token_value] = i;
46 for (i=0;i<301;i++) token_type_allowable[i] = 0;
48 token_type_allowable[VARIABLE_TT] = 1;
49 token_type_allowable[SYSFUN_TT] = 1;
50 token_type_allowable[DQ_TT] = 1;
51 token_type_allowable[DICTWORD_TT] = 1;
52 token_type_allowable[SUBOPEN_TT] = 1;
53 token_type_allowable[SUBCLOSE_TT] = 1;
54 token_type_allowable[SMALL_NUMBER_TT] = 1;
55 token_type_allowable[LARGE_NUMBER_TT] = 1;
56 token_type_allowable[ACTION_TT] = 1;
57 token_type_allowable[SYSTEM_CONSTANT_TT] = 1;
58 token_type_allowable[OP_TT] = 1;
61 static token_data current_token, previous_token, heldback_token;
63 static int comma_allowed, arrow_allowed, superclass_allowed,
65 array_init_ambiguity, action_ambiguity,
66 etoken_count, inserting_token, bracket_level;
68 extern int *variable_usage;
70 /* Must be at least as many as keyword_group system_functions (currently 12) */
71 int system_function_usage[32];
73 static int get_next_etoken(void)
74 { int v, symbol = 0, mark_symbol_as_used = FALSE,
75 initial_bracket_level = bracket_level;
80 { current_token = heldback_token;
81 inserting_token = FALSE;
85 current_token.text = token_text;
86 current_token.value = token_value;
87 current_token.type = token_type;
88 current_token.marker = 0;
89 current_token.symtype = 0;
90 current_token.symflags = -1;
93 switch(current_token.type)
94 { case LOCAL_VARIABLE_TT:
95 current_token.type = VARIABLE_TT;
96 variable_usage[current_token.value] = TRUE;
100 current_token.marker = STRING_MV;
104 { int32 unicode = text_to_unicode(token_text);
105 if (token_text[textual_form_length] == 0)
108 current_token.value = unicode_to_zscii(unicode);
109 if (current_token.value == 5)
110 { unicode_char_error("Character can be printed \
111 but not used as a value:", unicode);
112 current_token.value = '?';
114 if (current_token.value >= 0x100)
115 current_token.type = LARGE_NUMBER_TT;
116 else current_token.type = SMALL_NUMBER_TT;
119 current_token.value = unicode;
120 if (current_token.value >= 0x8000
121 || current_token.value < -0x8000)
122 current_token.type = LARGE_NUMBER_TT;
123 else current_token.type = SMALL_NUMBER_TT;
127 { current_token.type = DICTWORD_TT;
128 current_token.marker = DWORD_MV;
135 symbol = current_token.value;
137 mark_symbol_as_used = TRUE;
141 current_token.symtype = stypes[symbol];
142 current_token.symflags = sflags[symbol];
143 switch(stypes[symbol])
145 /* Replaced functions must always be backpatched
146 because there could be another definition coming. */
147 if (sflags[symbol] & REPLACE_SFLAG)
148 { current_token.marker = SYMBOL_MV;
149 if (module_switch) import_symbol(symbol);
153 current_token.marker = IROUTINE_MV;
155 case GLOBAL_VARIABLE_T:
156 current_token.marker = VARIABLE_MV;
160 /* All objects must be backpatched in Glulx. */
161 if (module_switch || glulx_mode)
162 current_token.marker = OBJECT_MV;
165 current_token.marker = ARRAY_MV;
168 current_token.marker = STATIC_ARRAY_MV;
170 case INDIVIDUAL_PROPERTY_T:
171 if (module_switch) current_token.marker = IDENT_MV;
174 if (sflags[symbol] & (UNKNOWN_SFLAG + CHANGE_SFLAG))
175 { current_token.marker = SYMBOL_MV;
176 if (module_switch) import_symbol(symbol);
179 else current_token.marker = 0;
182 error_named("Label name used as value:", token_text);
185 current_token.marker = 0;
188 if (sflags[symbol] & SYSTEM_SFLAG)
189 current_token.marker = 0;
191 current_token.value = v;
194 if (((current_token.marker != 0)
195 && (current_token.marker != VARIABLE_MV))
196 || (v < 0) || (v > 255))
197 current_token.type = LARGE_NUMBER_TT;
198 else current_token.type = SMALL_NUMBER_TT;
201 if (((current_token.marker != 0)
202 && (current_token.marker != VARIABLE_MV))
203 || (v < -0x8000) || (v >= 0x8000))
204 current_token.type = LARGE_NUMBER_TT;
205 else current_token.type = SMALL_NUMBER_TT;
208 if (stypes[symbol] == GLOBAL_VARIABLE_T)
209 { current_token.type = VARIABLE_TT;
210 variable_usage[current_token.value] = TRUE;
216 if (current_token.value >= 256)
217 current_token.type = LARGE_NUMBER_TT;
219 current_token.type = SMALL_NUMBER_TT;
222 if (current_token.value < -0x8000
223 || current_token.value >= 0x8000)
224 current_token.type = LARGE_NUMBER_TT;
226 current_token.type = SMALL_NUMBER_TT;
231 switch(current_token.value)
234 current_token.type = ENDEXP_TT;
238 if ((bracket_level==0) && (!comma_allowed))
239 current_token.type = ENDEXP_TT;
243 if ((bracket_level==0) && (!superclass_allowed))
244 current_token.type = ENDEXP_TT;
249 if ((token_type == SEP_TT)
250 &&((token_value == SEMICOLON_SEP)
251 || (token_value == GREATER_SEP)))
252 current_token.type = ENDEXP_TT;
258 if (expr_trace_level>=3)
259 { printf("Previous token type = %d\n",previous_token.type);
260 printf("Previous token val = %d\n",previous_token.value);
262 if ((previous_token.type == OP_TT)
263 || (previous_token.type == SUBOPEN_TT)
264 || (previous_token.type == ENDEXP_TT)
265 || (array_init_ambiguity)
266 || ((bracket_level == 1) && (action_ambiguity)))
267 current_token.type = SUBOPEN_TT;
269 { inserting_token = TRUE;
270 heldback_token = current_token;
271 current_token.text = "<call>";
278 if (bracket_level < 0)
279 current_token.type = ENDEXP_TT;
280 else current_token.type = SUBCLOSE_TT;
284 current_token.type = ENDEXP_TT; break;
287 if ((previous_token.type == OP_TT)
288 || (previous_token.type == SUBOPEN_TT)
289 || (previous_token.type == ENDEXP_TT))
290 current_token.value = UNARY_MINUS_SEP; break;
293 if ((previous_token.type == VARIABLE_TT)
294 || (previous_token.type == SUBCLOSE_TT)
295 || (previous_token.type == LARGE_NUMBER_TT)
296 || (previous_token.type == SMALL_NUMBER_TT))
297 current_token.value = POST_INC_SEP; break;
300 if ((previous_token.type == VARIABLE_TT)
301 || (previous_token.type == SUBCLOSE_TT)
302 || (previous_token.type == LARGE_NUMBER_TT)
303 || (previous_token.type == SMALL_NUMBER_TT))
304 current_token.value = POST_DEC_SEP; break;
307 token_text = current_token.text + 2;
309 ActionUsedAsConstant:
311 current_token.type = ACTION_TT;
312 current_token.text = token_text;
313 current_token.value = 0;
314 current_token.marker = ACTION_MV;
318 case HASHADOLLAR_SEP:
319 obsolete_warning("'#a$Act' is now superseded by '##Act'");
320 token_text = current_token.text + 3;
321 goto ActionUsedAsConstant;
323 case HASHGDOLLAR_SEP:
325 /* This form generates the position of a global variable
326 in the global variables array. So Glob is the same as
327 #globals_array --> #g$Glob */
329 current_token.text += 3;
330 current_token.type = SYMBOL_TT;
331 symbol = symbol_index(current_token.text, -1);
332 if (stypes[symbol] != GLOBAL_VARIABLE_T) {
334 "global variable name after '#g$'",
336 current_token.value = 0;
337 current_token.type = SMALL_NUMBER_TT;
338 current_token.marker = 0;
341 mark_symbol_as_used = TRUE;
342 current_token.value = svals[symbol] - MAX_LOCAL_VARIABLES;
343 current_token.marker = 0;
345 if (current_token.value >= 0x100)
346 current_token.type = LARGE_NUMBER_TT;
347 else current_token.type = SMALL_NUMBER_TT;
350 if (current_token.value >= 0x8000
351 || current_token.value < -0x8000)
352 current_token.type = LARGE_NUMBER_TT;
353 else current_token.type = SMALL_NUMBER_TT;
357 case HASHNDOLLAR_SEP:
359 /* This form is still needed for constants like #n$a (the
360 dictionary address of the word "a"), since 'a' means
361 the ASCII value of 'a' */
363 if (strlen(token_text) > 4)
365 "'#n$word' is now superseded by ''word''");
366 current_token.type = DICTWORD_TT;
367 current_token.value = 0;
368 current_token.text = token_text + 3;
369 current_token.marker = DWORD_MV;
372 case HASHRDOLLAR_SEP:
374 /* This form -- #r$Routinename, to return the routine's */
375 /* packed address -- is needed far less often in Inform 6, */
376 /* where just giving the name Routine returns the packed */
377 /* address. But it's used in a lot of Inform 5 code. */
380 "'#r$Routine' can now be written just 'Routine'");
381 current_token.text += 3;
382 current_token.type = SYMBOL_TT;
383 current_token.value = symbol_index(current_token.text, -1);
386 case HASHWDOLLAR_SEP:
387 error("The obsolete '#w$word' construct has been removed");
391 system_constants.enabled = TRUE;
393 system_constants.enabled = FALSE;
394 if (token_type != SYSTEM_CONSTANT_TT)
396 "'r$', 'n$', 'g$' or internal Inform constant name after '#'",
401 { current_token.type = token_type;
402 current_token.value = token_value;
403 current_token.text = token_text;
404 current_token.marker = INCON_MV;
411 v = conditionals_to_operators[current_token.value];
412 if (v != NOT_AN_OPERATOR)
413 { current_token.type = OP_TT; current_token.value = v;
418 if (current_token.type == SEP_TT)
419 { v = separators_to_operators[current_token.value];
420 if (v != NOT_AN_OPERATOR)
422 || ((v!=MESSAGE_OP) && (v!=MPROP_NUM_OP) && (v!=MPROP_NUM_OP)))
423 { current_token.type = OP_TT; current_token.value = v;
424 if (array_init_ambiguity &&
425 ((v==MINUS_OP) || (v==UNARY_MINUS_OP)) &&
426 (initial_bracket_level == 0) &&
428 warning("Without bracketing, the minus sign '-' is ambiguous");
433 /* A feature of Inform making it annoyingly hard to parse left-to-right
434 is that there is no clear delimiter for expressions; that is, the
435 legal syntax often includes sequences of expressions with no
436 intervening markers such as commas. We therefore need to use some
437 internal context to determine whether an end is in sight... */
439 if (token_type_allowable[current_token.type]==0)
440 { if (expr_trace_level >= 3)
441 { printf("Discarding as not allowable: '%s' ", current_token.text);
442 describe_token(current_token);
445 current_token.type = ENDEXP_TT;
448 if ((!((initial_bracket_level > 0)
449 || (previous_token.type == ENDEXP_TT)
450 || ((previous_token.type == OP_TT)
451 && (operators[previous_token.value].usage != POST_U))
452 || (previous_token.type == SYSFUN_TT)))
453 && ((current_token.type != OP_TT)
454 || (operators[current_token.value].usage == PRE_U)))
455 { if (expr_trace_level >= 3)
456 { printf("Discarding as no longer part: '%s' ", current_token.text);
457 describe_token(current_token);
460 current_token.type = ENDEXP_TT;
463 { if (mark_symbol_as_used) sflags[symbol] |= USED_SFLAG;
464 if (expr_trace_level >= 3)
465 { printf("Expr token = '%s' ", current_token.text);
466 describe_token(current_token);
471 if ((previous_token.type == ENDEXP_TT)
472 && (current_token.type == ENDEXP_TT)) return FALSE;
474 previous_token = current_token;
479 /* --- Operator precedences ------------------------------------------------ */
483 #define GREATER_P 103
485 #define e1 1 /* Missing operand error */
486 #define e2 2 /* Unexpected close bracket */
487 #define e3 3 /* Missing operator error */
488 #define e4 4 /* Expression ends with an open bracket */
489 #define e5 5 /* Associativity illegal error */
491 const int prec_table[] = {
493 /* a .......... ( ) end op term */
495 /* b ( */ LOWER_P, e3, LOWER_P, LOWER_P, e3,
496 /* . ) */ EQUAL_P, GREATER_P, e2, GREATER_P, GREATER_P,
497 /* . end */ e4, GREATER_P, e1, GREATER_P, GREATER_P,
498 /* . op */ LOWER_P, GREATER_P, LOWER_P, -1, GREATER_P,
499 /* . term */ LOWER_P, e3, LOWER_P, LOWER_P, e3
503 static int find_prec(token_data a, token_data b)
505 /* We are comparing the precedence of tokens a and b
506 (where a occurs to the left of b). If the expression is correct,
507 the only possible values are GREATER_P, LOWER_P or EQUAL_P;
508 if it is malformed then one of e1 to e5 results.
510 Note that this routine is not symmetrical and that the relation
513 If a and b are equal (and aren't brackets), then
515 a LOWER_P a if a right-associative
516 a GREATER_P a if a left-associative
522 { case SUBOPEN_TT: i=0; break;
523 case SUBCLOSE_TT: i=1; break;
524 case ENDEXP_TT: i=2; break;
525 case OP_TT: i=3; break;
529 { case SUBOPEN_TT: i+=0; break;
530 case SUBCLOSE_TT: i+=5; break;
531 case ENDEXP_TT: i+=10; break;
532 case OP_TT: i+=15; break;
533 default: i+=20; break;
536 j = prec_table[i]; if (j != -1) return j;
538 l1 = operators[a.value].precedence;
539 l2 = operators[b.value].precedence;
540 if (operators[b.value].usage == PRE_U) return LOWER_P;
541 if (operators[a.value].usage == POST_U) return GREATER_P;
543 /* Anomalous rule to resolve the function call precedence, which is
544 different on the right from on the left, e.g., in:
550 if ((l1 == 11) && (l2 > 11)) return GREATER_P;
552 if (l1 < l2) return LOWER_P;
553 if (l1 > l2) return GREATER_P;
554 switch(operators[a.value].associativity)
555 { case L_A: return GREATER_P;
556 case R_A: return LOWER_P;
562 /* --- Converting token to operand ----------------------------------------- */
564 /* Must match the switch statement below */
565 int z_system_constant_list[] =
566 { adjectives_table_SC,
569 identifiers_table_SC,
574 actual_largest_object_SC,
575 static_memory_offset_SC,
576 array_names_offset_SC,
577 readable_memory_offset_SC,
584 highest_attribute_number_SC,
585 attribute_names_array_SC,
586 highest_property_number_SC,
587 property_names_array_SC,
588 highest_action_number_SC,
589 action_names_array_SC,
590 highest_fake_action_number_SC,
591 fake_action_names_array_SC,
592 highest_routine_number_SC,
593 routine_names_array_SC,
595 routine_flags_array_SC,
596 highest_global_number_SC,
597 global_names_array_SC,
599 global_flags_array_SC,
600 highest_array_number_SC,
601 array_names_array_SC,
602 array_flags_array_SC,
603 highest_constant_number_SC,
604 constant_names_array_SC,
605 highest_class_number_SC,
606 class_objects_array_SC,
607 highest_object_number_SC,
610 static int32 value_of_system_constant_z(int t)
612 { case adjectives_table_SC:
613 return adjectives_offset;
614 case actions_table_SC:
615 return actions_offset;
616 case classes_table_SC:
617 return class_numbers_offset;
618 case identifiers_table_SC:
619 return identifier_names_offset;
620 case preactions_table_SC:
621 return preactions_offset;
622 case largest_object_SC:
623 return 256 + no_objects - 1;
624 case strings_offset_SC:
625 return strings_offset/scale_factor;
627 return code_offset/scale_factor;
628 case actual_largest_object_SC:
630 case static_memory_offset_SC:
631 return static_memory_offset;
632 case array_names_offset_SC:
633 return array_names_offset;
634 case readable_memory_offset_SC:
635 return Write_Code_At;
637 return prop_values_offset;
639 return class_numbers_offset;
641 return individuals_offset;
643 return variables_offset;
644 case array__start_SC:
645 return variables_offset + (MAX_GLOBAL_VARIABLES*WORDSIZE);
647 return static_memory_offset;
649 case highest_attribute_number_SC:
650 return no_attributes-1;
651 case attribute_names_array_SC:
652 return attribute_names_offset;
654 case highest_property_number_SC:
655 return no_individual_properties-1;
656 case property_names_array_SC:
657 return identifier_names_offset + 2;
659 case highest_action_number_SC:
661 case action_names_array_SC:
662 return action_names_offset;
664 case highest_fake_action_number_SC:
665 return ((grammar_version_number==1)?256:4096) + no_fake_actions-1;
666 case fake_action_names_array_SC:
667 return fake_action_names_offset;
669 case highest_routine_number_SC:
670 return no_named_routines-1;
671 case routine_names_array_SC:
672 return routine_names_offset;
673 case routines_array_SC:
674 return routines_array_offset;
675 case routine_flags_array_SC:
676 return routine_flags_array_offset;
677 case highest_global_number_SC:
678 return 16 + no_globals-1;
679 case global_names_array_SC:
680 return global_names_offset;
681 case globals_array_SC:
682 return variables_offset;
683 case global_flags_array_SC:
684 return global_flags_array_offset;
685 case highest_array_number_SC:
687 case array_names_array_SC:
688 return array_names_offset;
689 case array_flags_array_SC:
690 return array_flags_array_offset;
691 case highest_constant_number_SC:
692 return no_named_constants-1;
693 case constant_names_array_SC:
694 return constant_names_offset;
695 case highest_class_number_SC:
697 case class_objects_array_SC:
698 return class_numbers_offset;
699 case highest_object_number_SC:
703 error_named("System constant not implemented in Z-code",
704 system_constants.keywords[t]);
709 /* Must match the switch statement below */
710 int glulx_system_constant_list[] =
712 identifiers_table_SC,
713 array_names_offset_SC,
717 dynam_string_table_SC,
721 highest_class_number_SC,
722 highest_object_number_SC,
725 static int32 value_of_system_constant_g(int t)
728 case classes_table_SC:
729 return Write_RAM_At + class_numbers_offset;
730 case identifiers_table_SC:
731 return Write_RAM_At + identifier_names_offset;
732 case array_names_offset_SC:
733 return Write_RAM_At + array_names_offset;
735 return prop_defaults_offset;
737 return Write_RAM_At + class_numbers_offset;
738 case dictionary_table_SC:
739 return dictionary_offset;
740 case dynam_string_table_SC:
741 return abbreviations_offset;
742 case grammar_table_SC:
743 return grammar_table_offset;
744 case actions_table_SC:
745 return actions_offset;
746 case globals_array_SC:
747 return variables_offset;
748 case highest_class_number_SC:
750 case highest_object_number_SC:
754 error_named("System constant not implemented in Glulx",
755 system_constants.keywords[t]);
760 extern int32 value_of_system_constant(int t)
763 return value_of_system_constant_z(t);
765 return value_of_system_constant_g(t);
768 static int evaluate_term(token_data t, assembly_operand *o)
770 /* If the given token is a constant, evaluate it into the operand.
771 For now, the identifiers are considered variables.
773 Returns FALSE if it fails to understand type. */
777 o->marker = t.marker;
778 o->symtype = t.symtype;
779 o->symflags = t.symflags;
782 { case LARGE_NUMBER_TT:
785 if (v < 0) v = v + 0x10000;
786 o->type = LONG_CONSTANT_OT;
791 o->type = CONSTANT_OT;
794 case SMALL_NUMBER_TT:
797 if (v < 0) v = v + 0x10000;
798 o->type = SHORT_CONSTANT_OT;
807 /* Find the dictionary address, adding to dictionary if absent */
809 o->type = LONG_CONSTANT_OT;
811 o->type = CONSTANT_OT;
812 o->value = dictionary_add(t.text, 0x80, 0, 0);
815 /* Create as a static string */
817 o->type = LONG_CONSTANT_OT;
819 o->type = CONSTANT_OT;
820 o->value = compile_string(t.text, STRCTX_GAME);
824 o->type = VARIABLE_OT;
827 if (t.value >= MAX_LOCAL_VARIABLES) {
828 o->type = GLOBALVAR_OT;
831 /* This includes "local variable zero", which is really
832 the stack-pointer magic variable. */
833 o->type = LOCALVAR_OT;
840 o->type = VARIABLE_OT;
841 o->value = t.value + 256;
847 system_function_usage[t.value] = 1;
850 *o = action_of_name(t.text);
852 case SYSTEM_CONSTANT_TT:
853 /* Certain system constants depend only on the
854 version number and need no backpatching, as they
855 are known in advance. We can therefore evaluate
858 o->type = LONG_CONSTANT_OT;
861 case version_number_SC:
862 o->type = SHORT_CONSTANT_OT;
864 v = version_number; break;
866 o->type = SHORT_CONSTANT_OT;
868 v = (version_number==3)?4:6; break;
870 o->type = SHORT_CONSTANT_OT;
872 v = (version_number==3)?5:7; break;
874 o->type = SHORT_CONSTANT_OT;
876 v = (version_number==3)?6:8; break;
877 case lowest_attribute_number_SC:
878 case lowest_action_number_SC:
879 case lowest_routine_number_SC:
880 case lowest_array_number_SC:
881 case lowest_constant_number_SC:
882 case lowest_class_number_SC:
883 o->type = SHORT_CONSTANT_OT; o->marker = 0; v = 0; break;
884 case lowest_object_number_SC:
885 case lowest_property_number_SC:
886 o->type = SHORT_CONSTANT_OT; o->marker = 0; v = 1; break;
887 case lowest_global_number_SC:
888 o->type = SHORT_CONSTANT_OT; o->marker = 0; v = 16; break;
889 case lowest_fake_action_number_SC:
890 o->type = LONG_CONSTANT_OT; o->marker = 0;
891 v = ((grammar_version_number==1)?256:4096); break;
892 case oddeven_packing_SC:
893 o->type = SHORT_CONSTANT_OT; o->marker = 0;
894 v = oddeven_packing_switch; break;
897 o->marker = INCON_MV;
903 o->type = CONSTANT_OT;
906 /* The three dict_par flags point at the lower byte
907 of the flag field, because the library is written
908 to expect one-byte fields, even though the compiler
909 generates a dictionary with room for two. */
911 o->type = BYTECONSTANT_OT;
913 v = DICT_ENTRY_FLAG_POS+1;
916 o->type = BYTECONSTANT_OT;
918 v = DICT_ENTRY_FLAG_POS+3;
921 o->type = BYTECONSTANT_OT;
923 v = DICT_ENTRY_FLAG_POS+5;
926 case lowest_attribute_number_SC:
927 case lowest_action_number_SC:
928 case lowest_routine_number_SC:
929 case lowest_array_number_SC:
930 case lowest_constant_number_SC:
931 case lowest_class_number_SC:
932 o->type = BYTECONSTANT_OT;
936 case lowest_object_number_SC:
937 case lowest_property_number_SC:
938 o->type = BYTECONSTANT_OT;
943 /* ###fix: need to fill more of these in! */
947 o->marker = INCON_MV;
958 /* --- Emitter ------------------------------------------------------------- */
960 expression_tree_node *ET;
963 extern void clear_expression_space(void)
967 static assembly_operand *emitter_stack;
968 static int *emitter_markers;
969 static int *emitter_bracket_counts;
971 #define FUNCTION_VALUE_MARKER 1
972 #define ARGUMENT_VALUE_MARKER 2
973 #define OR_VALUE_MARKER 3
975 static int emitter_sp;
977 static int is_property_t(int symbol_type)
978 { return ((symbol_type == PROPERTY_T) || (symbol_type == INDIVIDUAL_PROPERTY_T));
981 static void mark_top_of_emitter_stack(int marker, token_data t)
982 { if (emitter_sp < 1)
983 { compiler_error("SR error: Attempt to add a marker to the top of an empty emitter stack");
986 if (expr_trace_level >= 2)
987 { printf("Marking top of emitter stack (which is ");
988 print_operand(emitter_stack[emitter_sp-1]);
992 case FUNCTION_VALUE_MARKER:
995 case ARGUMENT_VALUE_MARKER:
998 case OR_VALUE_MARKER:
1007 if (emitter_markers[emitter_sp-1])
1008 { if (marker == ARGUMENT_VALUE_MARKER)
1010 warning("Ignoring spurious leading comma");
1013 error_named("Missing operand for", t.text);
1014 if (emitter_sp == MAX_EXPRESSION_NODES)
1015 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1016 emitter_markers[emitter_sp] = 0;
1017 emitter_bracket_counts[emitter_sp] = 0;
1018 emitter_stack[emitter_sp] = zero_operand;
1021 emitter_markers[emitter_sp-1] = marker;
1024 static void add_bracket_layer_to_emitter_stack(int depth)
1025 { /* There's no point in tracking bracket layers that don't fence off any values. */
1026 if (emitter_sp < depth + 1) return;
1027 if (expr_trace_level >= 2)
1028 printf("Adding bracket layer\n");
1029 ++emitter_bracket_counts[emitter_sp-depth-1];
1032 static void remove_bracket_layer_from_emitter_stack()
1033 { /* Bracket layers that don't fence off any values will not have been tracked. */
1034 if (emitter_sp < 2) return;
1035 if (expr_trace_level >= 2)
1036 printf("Removing bracket layer\n");
1037 if (emitter_bracket_counts[emitter_sp-2] <= 0)
1038 { compiler_error("SR error: Attempt to remove a nonexistent bracket layer from the emitter stack");
1041 --emitter_bracket_counts[emitter_sp-2];
1044 static void emit_token(token_data t)
1045 { assembly_operand o1, o2; int arity, stack_size, i;
1046 int op_node_number, operand_node_number, previous_node_number;
1049 if (expr_trace_level >= 2)
1050 { printf("Output: %-19s%21s ", t.text, "");
1051 for (i=0; i<emitter_sp; i++)
1052 { print_operand(emitter_stack[i]); printf(" ");
1053 if (emitter_markers[i] == FUNCTION_VALUE_MARKER) printf(":FUNCTION ");
1054 if (emitter_markers[i] == ARGUMENT_VALUE_MARKER) printf(":ARGUMENT ");
1055 if (emitter_markers[i] == OR_VALUE_MARKER) printf(":OR ");
1056 if (emitter_bracket_counts[i]) printf(":BRACKETS(%d) ", emitter_bracket_counts[i]);
1061 if (t.type == SUBOPEN_TT) return;
1064 while ((stack_size < emitter_sp) &&
1065 !emitter_markers[emitter_sp-stack_size-1] &&
1066 !emitter_bracket_counts[emitter_sp-stack_size-1])
1069 if (t.type == SUBCLOSE_TT)
1070 { if (stack_size < emitter_sp && emitter_bracket_counts[emitter_sp-stack_size-1])
1071 { if (stack_size == 0)
1072 { error("No expression between brackets '(' and ')'");
1073 emitter_stack[emitter_sp] = zero_operand;
1074 emitter_markers[emitter_sp] = 0;
1075 emitter_bracket_counts[emitter_sp] = 0;
1078 else if (stack_size < 1)
1079 compiler_error("SR error: emitter stack empty in subexpression");
1080 else if (stack_size > 1)
1081 compiler_error("SR error: emitter stack overfull in subexpression");
1082 remove_bracket_layer_from_emitter_stack();
1087 if (t.type != OP_TT)
1088 { emitter_markers[emitter_sp] = 0;
1089 emitter_bracket_counts[emitter_sp] = 0;
1091 if (emitter_sp == MAX_EXPRESSION_NODES)
1092 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1093 if (!evaluate_term(t, &(emitter_stack[emitter_sp++])))
1094 compiler_error_named("Emit token error:", t.text);
1098 /* A comma is argument-separating if it follows an argument (or a function
1099 call, since we ignore spurious leading commas in function argument lists)
1100 with no intervening brackets. Function calls are variadic, so we don't
1101 apply argument-separating commas. */
1102 if (t.value == COMMA_OP &&
1103 stack_size < emitter_sp &&
1104 (emitter_markers[emitter_sp-stack_size-1] == ARGUMENT_VALUE_MARKER ||
1105 emitter_markers[emitter_sp-stack_size-1] == FUNCTION_VALUE_MARKER) &&
1106 !emitter_bracket_counts[emitter_sp-stack_size-1])
1107 { if (expr_trace_level >= 2)
1108 printf("Treating comma as argument-separating\n");
1112 if (t.value == OR_OP)
1116 if (t.value == FCALL_OP)
1117 { if (expr_trace_level >= 3)
1118 { printf("FCALL_OP finds marker stack: ");
1119 for (x=0; x<emitter_sp; x++) printf("%d ", emitter_markers[x]);
1122 if (emitter_markers[emitter_sp-1] == ARGUMENT_VALUE_MARKER)
1123 warning("Ignoring spurious trailing comma");
1124 while (emitter_markers[emitter_sp-arity] != FUNCTION_VALUE_MARKER)
1127 emitter_stack[emitter_sp-arity].type == SYSFUN_OT) ||
1129 emitter_stack[emitter_sp-arity].type == VARIABLE_OT &&
1130 emitter_stack[emitter_sp-arity].value >= 256 &&
1131 emitter_stack[emitter_sp-arity].value < 288))
1132 { int index = emitter_stack[emitter_sp-arity].value;
1135 if(index >= 0 && index < NUMBER_SYSTEM_FUNCTIONS)
1136 error_named("System function name used as a value:", system_functions.keywords[index]);
1138 compiler_error("Found unnamed system function used as a value");
1139 emitter_stack[emitter_sp-arity] = zero_operand;
1146 if (operators[t.value].usage == IN_U) arity = 2;
1148 if (operators[t.value].precedence == 3)
1151 if(!emitter_markers[x] && !emitter_bracket_counts[x])
1152 { for (--x; emitter_markers[x] == OR_VALUE_MARKER && !emitter_bracket_counts[x]; --x)
1156 for (;x >= 0 && !emitter_markers[x] && !emitter_bracket_counts[x]; --x)
1161 if (arity > stack_size)
1162 { error_named("Missing operand for", t.text);
1163 while (arity > stack_size)
1164 { if (emitter_sp == MAX_EXPRESSION_NODES)
1165 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1166 emitter_markers[emitter_sp] = 0;
1167 emitter_bracket_counts[emitter_sp] = 0;
1168 emitter_stack[emitter_sp] = zero_operand;
1175 /* pseudo-typecheck in 6.30 */
1176 for (i = 1; i <= arity; i++)
1178 o1 = emitter_stack[emitter_sp - i];
1179 if (is_property_t(o1.symtype) ) {
1183 case SETEQUALS_OP: case NOTEQUAL_OP:
1185 case PROVIDES_OP: case NOTPROVIDES_OP:
1186 case PROP_ADD_OP: case PROP_NUM_OP:
1188 case MPROP_ADD_OP: case MESSAGE_OP:
1190 if (i < arity) break;
1191 case GE_OP: case LE_OP:
1192 if ((i < arity) && (o1.symflags & STAR_SFLAG)) break;
1194 warning("Property name in expression is not qualified by object");
1196 } /* if (is_property_t */
1201 o1 = emitter_stack[emitter_sp - 1];
1202 if ((o1.marker == 0) && is_constant_ot(o1.type))
1204 { case UNARY_MINUS_OP: x = -o1.value; goto FoldConstant;
1207 x = (~o1.value) & 0xffff;
1209 x = (~o1.value) & 0xffffffff;
1212 if (o1.value != 0) x=0; else x=1;
1219 o1 = emitter_stack[emitter_sp - 2];
1220 o2 = emitter_stack[emitter_sp - 1];
1222 if ((o1.marker == 0) && (o2.marker == 0)
1223 && is_constant_ot(o1.type) && is_constant_ot(o2.type))
1231 { ov1 = (o1.value >= 0x8000) ? (o1.value - 0x10000) : o1.value;
1232 ov2 = (o2.value >= 0x8000) ? (o2.value - 0x10000) : o2.value;
1237 case PLUS_OP: x = ov1 + ov2; goto FoldConstantC;
1238 case MINUS_OP: x = ov1 - ov2; goto FoldConstantC;
1239 case TIMES_OP: x = ov1 * ov2; goto FoldConstantC;
1243 error("Division of constant by zero");
1245 if (t.value == DIVIDE_OP) {
1253 x = -((-ov1) / ov2);
1262 x = -((-ov1) % ov2);
1265 case ARTAND_OP: x = o1.value & o2.value; goto FoldConstant;
1266 case ARTOR_OP: x = o1.value | o2.value; goto FoldConstant;
1268 if (o1.value == o2.value) x = 1; else x = 0;
1271 if (o1.value != o2.value) x = 1; else x = 0;
1274 if (o1.value >= o2.value) x = 1; else x = 0;
1277 if (o1.value > o2.value) x = 1; else x = 0;
1280 if (o1.value <= o2.value) x = 1; else x = 0;
1283 if (o1.value < o2.value) x = 1; else x = 0;
1286 if ((o1.value != 0) && (o2.value != 0)) x=1; else x=0;
1289 if ((o1.value != 0) || (o2.value != 0)) x=1; else x=0;
1296 op_node_number = ET_used++;
1297 if (op_node_number == MAX_EXPRESSION_NODES)
1298 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1300 ET[op_node_number].operator_number = t.value;
1301 ET[op_node_number].up = -1;
1302 ET[op_node_number].down = -1;
1303 ET[op_node_number].right = -1;
1305 /* This statement is redundant, but prevents compilers from wrongly
1306 issuing a "used before it was assigned a value" error: */
1307 previous_node_number = 0;
1309 for (i = emitter_sp-arity; i != emitter_sp; i++)
1311 if (expr_trace_level >= 3)
1312 printf("i=%d, emitter_sp=%d, arity=%d, ETU=%d\n",
1313 i, emitter_sp, arity, ET_used);
1314 if (emitter_stack[i].type == EXPRESSION_OT)
1315 operand_node_number = emitter_stack[i].value;
1317 { operand_node_number = ET_used++;
1318 if (operand_node_number == MAX_EXPRESSION_NODES)
1319 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1320 ET[operand_node_number].down = -1;
1321 ET[operand_node_number].value = emitter_stack[i];
1323 ET[operand_node_number].up = op_node_number;
1324 ET[operand_node_number].right = -1;
1325 if (i == emitter_sp - arity)
1326 { ET[op_node_number].down = operand_node_number;
1329 { ET[previous_node_number].right = operand_node_number;
1331 previous_node_number = operand_node_number;
1334 emitter_sp = emitter_sp - arity + 1;
1336 emitter_stack[emitter_sp - 1].type = EXPRESSION_OT;
1337 emitter_stack[emitter_sp - 1].value = op_node_number;
1338 emitter_stack[emitter_sp - 1].marker = 0;
1339 emitter_markers[emitter_sp - 1] = 0;
1340 emitter_bracket_counts[emitter_sp - 1] = 0;
1341 /* Remove the marker for the brackets implied by operator precedence */
1342 remove_bracket_layer_from_emitter_stack();
1348 /* In Glulx, skip this test; we can't check out-of-range errors
1349 for 32-bit arithmetic. */
1351 if (!glulx_mode && ((x<-32768) || (x > 32767)))
1352 { char folding_error[40];
1353 int32 ov1 = (o1.value >= 0x8000) ? (o1.value - 0x10000) : o1.value;
1354 int32 ov2 = (o2.value >= 0x8000) ? (o2.value - 0x10000) : o2.value;
1358 sprintf(folding_error, "%d + %d = %d", ov1, ov2, x);
1361 sprintf(folding_error, "%d - %d = %d", ov1, ov2, x);
1364 sprintf(folding_error, "%d * %d = %d", ov1, ov2, x);
1367 error_named("Signed arithmetic on compile-time constants overflowed \
1368 the range -32768 to +32767:", folding_error);
1374 while (x < 0) x = x + 0x10000;
1381 emitter_sp = emitter_sp - arity + 1;
1385 emitter_stack[emitter_sp - 1].type = SHORT_CONSTANT_OT;
1386 else emitter_stack[emitter_sp - 1].type = LONG_CONSTANT_OT;
1390 emitter_stack[emitter_sp - 1].type = ZEROCONSTANT_OT;
1391 else if (x >= -128 && x <= 127)
1392 emitter_stack[emitter_sp - 1].type = BYTECONSTANT_OT;
1393 else if (x >= -32768 && x <= 32767)
1394 emitter_stack[emitter_sp - 1].type = HALFCONSTANT_OT;
1396 emitter_stack[emitter_sp - 1].type = CONSTANT_OT;
1399 emitter_stack[emitter_sp - 1].value = x;
1400 emitter_stack[emitter_sp - 1].marker = 0;
1401 emitter_markers[emitter_sp - 1] = 0;
1402 emitter_bracket_counts[emitter_sp - 1] = 0;
1404 if (expr_trace_level >= 2)
1405 { printf("Folding constant to: ");
1406 print_operand(emitter_stack[emitter_sp - 1]);
1410 /* Remove the marker for the brackets implied by operator precedence */
1411 remove_bracket_layer_from_emitter_stack();
1415 /* --- Pretty printing ----------------------------------------------------- */
1417 static void show_node(int n, int depth, int annotate)
1419 for (j=0; j<2*depth+2; j++) printf(" ");
1421 if (ET[n].down == -1)
1422 { print_operand(ET[n].value);
1423 if (annotate && (ET[n].value.marker != 0))
1424 printf(" [%s]", describe_mv(ET[n].value.marker));
1428 { printf("%s ", operators[ET[n].operator_number].description);
1429 j = operators[ET[n].operator_number].precedence;
1430 if ((annotate) && ((j==2) || (j==3)))
1431 { printf(" %d|%d ", ET[n].true_label, ET[n].false_label);
1432 if (ET[n].label_after != -1) printf(" def %d after ",
1434 if (ET[n].to_expression) printf(" con to expr ");
1437 show_node(ET[n].down, depth+1, annotate);
1440 if (ET[n].right != -1) show_node(ET[n].right, depth, annotate);
1443 extern void show_tree(assembly_operand AO, int annotate)
1444 { if (AO.type == EXPRESSION_OT) show_node(AO.value, 0, annotate);
1446 { printf("Constant: "); print_operand(AO);
1447 if (annotate && (AO.marker != 0))
1448 printf(" [%s]", describe_mv(AO.marker));
1453 /* --- Lvalue transformations ---------------------------------------------- */
1455 /* This only gets called in Z-code, since Glulx doesn't distinguish
1456 individual property operators from general ones. */
1457 static void check_property_operator(int from_node)
1458 { int below = ET[from_node].down;
1459 int opnum = ET[from_node].operator_number;
1463 if (veneer_mode) return;
1465 if ((below != -1) && (ET[below].right != -1))
1466 { int n = ET[below].right, flag = FALSE;
1468 /* Can we handle this dot operator as a native @get_prop (etc)
1469 opcode? Only if we recognize the property value as a declared
1470 common property constant. */
1471 if ((ET[n].down == -1)
1472 && ((ET[n].value.type == LONG_CONSTANT_OT)
1473 || (ET[n].value.type == SHORT_CONSTANT_OT))
1474 && ((ET[n].value.value > 0) && (ET[n].value.value < 64))
1476 && (ET[n].value.marker == 0))
1481 { case PROPERTY_OP: opnum = MESSAGE_OP; break;
1482 case PROP_ADD_OP: opnum = MPROP_ADD_OP; break;
1483 case PROP_NUM_OP: opnum = MPROP_NUM_OP; break;
1487 ET[from_node].operator_number = opnum;
1491 check_property_operator(below);
1492 if (ET[from_node].right != -1)
1493 check_property_operator(ET[from_node].right);
1496 static void check_lvalues(int from_node)
1497 { int below = ET[from_node].down;
1498 int opnum = ET[from_node].operator_number, opnum_below;
1499 int lvalue_form, i, j = 0;
1503 if ((opnum == FCALL_OP) && (ET[below].down != -1))
1504 { opnum_below = ET[below].operator_number;
1505 if ((opnum_below == PROPERTY_OP) || (opnum_below == MESSAGE_OP))
1506 { i = ET[ET[from_node].down].right;
1507 ET[from_node].down = ET[below].down;
1508 ET[ET[below].down].up = from_node;
1509 ET[ET[ET[below].down].right].up = from_node;
1510 ET[ET[ET[below].down].right].right = i;
1511 opnum = PROP_CALL_OP;
1512 ET[from_node].operator_number = opnum;
1516 if (operators[opnum].requires_lvalue)
1517 { opnum_below = ET[below].operator_number;
1519 if (ET[below].down == -1)
1520 { if (!is_variable_ot(ET[below].value.type))
1521 { error("'=' applied to undeclared variable");
1528 { case SETEQUALS_OP:
1530 { case ARROW_OP: lvalue_form = ARROW_SETEQUALS_OP; break;
1531 case DARROW_OP: lvalue_form = DARROW_SETEQUALS_OP; break;
1532 case MESSAGE_OP: lvalue_form = MESSAGE_SETEQUALS_OP; break;
1533 case PROPERTY_OP: lvalue_form = PROPERTY_SETEQUALS_OP; break;
1538 { case ARROW_OP: lvalue_form = ARROW_INC_OP; break;
1539 case DARROW_OP: lvalue_form = DARROW_INC_OP; break;
1540 case MESSAGE_OP: lvalue_form = MESSAGE_INC_OP; break;
1541 case PROPERTY_OP: lvalue_form = PROPERTY_INC_OP; break;
1546 { case ARROW_OP: lvalue_form = ARROW_POST_INC_OP; break;
1547 case DARROW_OP: lvalue_form = DARROW_POST_INC_OP; break;
1548 case MESSAGE_OP: lvalue_form = MESSAGE_POST_INC_OP; break;
1549 case PROPERTY_OP: lvalue_form = PROPERTY_POST_INC_OP; break;
1554 { case ARROW_OP: lvalue_form = ARROW_DEC_OP; break;
1555 case DARROW_OP: lvalue_form = DARROW_DEC_OP; break;
1556 case MESSAGE_OP: lvalue_form = MESSAGE_DEC_OP; break;
1557 case PROPERTY_OP: lvalue_form = PROPERTY_DEC_OP; break;
1562 { case ARROW_OP: lvalue_form = ARROW_POST_DEC_OP; break;
1563 case DARROW_OP: lvalue_form = DARROW_POST_DEC_OP; break;
1564 case MESSAGE_OP: lvalue_form = MESSAGE_POST_DEC_OP; break;
1565 case PROPERTY_OP: lvalue_form = PROPERTY_POST_DEC_OP; break;
1569 if (lvalue_form == 0)
1570 { error_named("'=' applied to",
1571 (char *) operators[opnum_below].description);
1575 /* Transform from_node from_node
1577 below value to value
1581 ET[from_node].operator_number = lvalue_form;
1583 ET[from_node].down = i;
1585 { ET[i].up = from_node;
1589 ET[j].right = ET[below].right;
1592 check_lvalues(below);
1594 if (ET[from_node].right != -1)
1595 check_lvalues(ET[from_node].right);
1599 ET[from_node].down = -1;
1600 ET[from_node].value = zero_operand;
1601 if (ET[from_node].right != -1)
1602 check_lvalues(ET[from_node].right);
1605 /* --- Tree surgery for conditionals --------------------------------------- */
1607 static void negate_condition(int n)
1610 if (ET[n].right != -1) negate_condition(ET[n].right);
1611 if (ET[n].down == -1) return;
1612 i = operators[ET[n].operator_number].negation;
1613 if (i!=0) ET[n].operator_number = i;
1614 if (operators[i].precedence==2) negate_condition(ET[n].down);
1617 static void delete_negations(int n, int context)
1619 /* Recursively apply
1621 ~~(x && y) = ~~x || ~~y
1622 ~~(x || y) = ~~x && ~~y
1625 (etc) to delete the ~~ operator from the tree. Since this is
1626 depth first, the ~~ being deleted has no ~~s beneath it, which
1627 is important to make "negate_condition" work. */
1631 if (ET[n].right != -1) delete_negations(ET[n].right, context);
1632 if (ET[n].down == -1) return;
1633 delete_negations(ET[n].down, context);
1635 if (ET[n].operator_number == LOGNOT_OP)
1636 { negate_condition(ET[n].down);
1637 ET[n].operator_number
1638 = ET[ET[n].down].operator_number;
1639 ET[n].down = ET[ET[n].down].down;
1641 while(i != -1) { ET[i].up = n; i = ET[i].right; }
1645 static void insert_exp_to_cond(int n, int context)
1647 /* Insert a ~= test when an expression is used as a condition.
1649 Check for possible confusion over = and ==, e.g. "if (a = 1) ..." */
1653 if (ET[n].right != -1) insert_exp_to_cond(ET[n].right, context);
1655 if (ET[n].down == -1)
1656 { if (context==CONDITION_CONTEXT)
1658 if (new == MAX_EXPRESSION_NODES)
1659 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1661 ET[n].down = new; ET[n].operator_number = NONZERO_OP;
1662 ET[new].up = n; ET[new].right = -1;
1667 switch(operators[ET[n].operator_number].precedence)
1668 { case 3: /* Conditionals have level 3 */
1669 context = QUANTITY_CONTEXT;
1671 case 2: /* Logical operators level 2 */
1672 context = CONDITION_CONTEXT;
1674 case 1: /* Forms of '=' have level 1 */
1675 if (context == CONDITION_CONTEXT)
1676 warning("'=' used as condition: '==' intended?");
1678 if (context != CONDITION_CONTEXT) break;
1681 if (new == MAX_EXPRESSION_NODES)
1682 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1684 ET[n].down = new; ET[n].operator_number = NONZERO_OP;
1685 ET[new].up = n; ET[new].right = -1;
1688 while (i!= -1) { ET[i].up = new; i = ET[i].right; }
1689 context = QUANTITY_CONTEXT; n = new;
1692 insert_exp_to_cond(ET[n].down, context);
1695 static unsigned int etoken_num_children(int n)
1700 if (i == -1) { return 0; }
1708 static void func_args_on_stack(int n, int context)
1710 /* Make sure that the arguments of every function-call expression
1711 are stored to the stack. If any aren't (ie, if any arguments are
1712 constants or variables), cover them with push operators.
1713 (The very first argument does not need to be so treated, because
1714 it's the function address, not a function argument. We also
1715 skip the treatment for most system functions.) */
1717 int new, pn, fnaddr, opnum;
1721 if (ET[n].right != -1)
1722 func_args_on_stack(ET[n].right, context);
1723 if (ET[n].down == -1) {
1726 opnum = ET[pn].operator_number;
1727 if (opnum == FCALL_OP
1728 || opnum == MESSAGE_CALL_OP
1729 || opnum == PROP_CALL_OP) {
1730 /* If it's an FCALL, get the operand which contains the function
1731 address (or system-function number) */
1732 if (opnum == MESSAGE_CALL_OP
1733 || opnum == PROP_CALL_OP
1734 || ((fnaddr=ET[pn].down) != n
1735 && (ET[fnaddr].value.type != SYSFUN_OT
1736 || ET[fnaddr].value.value == INDIRECT_SYSF
1737 || ET[fnaddr].value.value == GLK_SYSF))) {
1738 if (etoken_num_children(pn) > (unsigned int)(opnum == FCALL_OP ? 4:3)) {
1740 if (new == MAX_EXPRESSION_NODES)
1741 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1744 ET[n].operator_number = PUSH_OP;
1754 func_args_on_stack(ET[n].down, context);
1757 static assembly_operand check_conditions(assembly_operand AO, int context)
1760 if (AO.type != EXPRESSION_OT)
1761 { if (context != CONDITION_CONTEXT) return AO;
1763 if (n == MAX_EXPRESSION_NODES)
1764 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1769 INITAOT(&AO, EXPRESSION_OT);
1773 insert_exp_to_cond(AO.value, context);
1774 delete_negations(AO.value, context);
1777 func_args_on_stack(AO.value, context);
1782 /* --- Shift-reduce parser ------------------------------------------------- */
1785 static token_data *sr_stack;
1787 extern assembly_operand parse_expression(int context)
1789 /* Parses an expression, evaluating it as a constant if possible.
1791 Possible contexts are:
1793 VOID_CONTEXT the expression is used as a statement, so that
1794 its value will be thrown away and it only
1795 needs to exist for any resulting side-effects
1796 (function calls and assignments)
1798 CONDITION_CONTEXT the result must be a condition
1800 CONSTANT_CONTEXT there is required to be a constant result
1801 (so that, for instance, comma becomes illegal)
1803 QUANTITY_CONTEXT the default: a quantity is to be specified
1805 ACTION_Q_CONTEXT like QUANTITY_CONTEXT, but postfixed brackets
1806 at the top level do not indicate function call:
1808 <Insert button (random(pocket1, pocket2))>
1810 RETURN_Q_CONTEXT like QUANTITY_CONTEXT, but a single property
1811 name does not generate a warning
1813 ASSEMBLY_CONTEXT a quantity which cannot use the '->' operator
1814 (needed for assembly language to indicate
1817 FORINIT_CONTEXT a quantity which cannot use an (unbracketed)
1820 ARRAY_CONTEXT like CONSTANT_CONTEXT, but where an unbracketed
1821 minus sign is ambiguous, and brackets always
1822 indicate subexpressions, not function calls
1824 Return value: an assembly operand.
1826 If the type is OMITTED_OT, then the expression has no resulting value.
1828 If the type is EXPRESSION_OT, then the value will need to be
1829 calculated at run-time by code compiled from the expression tree
1830 whose root node-number is the operand value.
1832 Otherwise the assembly operand is the value of the expression, which
1833 is constant and thus known at compile time.
1835 If an error has occurred in the expression, which recovery from was
1836 not possible, then the return is (short constant) 0. This should
1837 minimise the chance of a cascade of further error messages.
1840 token_data a, b, pop; int i;
1841 assembly_operand AO;
1843 superclass_allowed = (context != FORINIT_CONTEXT);
1844 if (context == FORINIT_CONTEXT) context = VOID_CONTEXT;
1846 comma_allowed = (context == VOID_CONTEXT);
1847 arrow_allowed = (context != ASSEMBLY_CONTEXT);
1848 bare_prop_allowed = (context == RETURN_Q_CONTEXT);
1849 array_init_ambiguity = ((context == ARRAY_CONTEXT) ||
1850 (context == ASSEMBLY_CONTEXT));
1852 action_ambiguity = (context == ACTION_Q_CONTEXT);
1854 if (context == ASSEMBLY_CONTEXT) context = QUANTITY_CONTEXT;
1855 if (context == ACTION_Q_CONTEXT) context = QUANTITY_CONTEXT;
1856 if (context == RETURN_Q_CONTEXT) context = QUANTITY_CONTEXT;
1857 if (context == ARRAY_CONTEXT) context = CONSTANT_CONTEXT;
1860 inserting_token = FALSE;
1865 previous_token.text = "$";
1866 previous_token.type = ENDEXP_TT;
1867 previous_token.value = 0;
1870 sr_stack[0] = previous_token;
1874 statements.enabled = FALSE;
1875 directives.enabled = FALSE;
1877 if (get_next_etoken() == FALSE)
1878 { ebf_error("expression", token_text);
1883 { if (expr_trace_level >= 2)
1884 { printf("Input: %-20s", current_token.text);
1885 for (i=0; i<sr_sp; i++) printf("%s ", sr_stack[i].text);
1888 if (expr_trace_level >= 3) printf("ET_used = %d\n", ET_used);
1891 { compiler_error("SR error: stack empty");
1895 a = sr_stack[sr_sp-1]; b = current_token;
1897 if ((a.type == ENDEXP_TT) && (b.type == ENDEXP_TT))
1898 { if (emitter_sp == 0)
1899 { error("No expression between brackets '(' and ')'");
1904 { compiler_error("SR error: emitter stack overfull");
1908 AO = emitter_stack[0];
1909 if (AO.type == EXPRESSION_OT)
1910 { if (expr_trace_level >= 3)
1911 { printf("Tree before lvalue checking:\n");
1912 show_tree(AO, FALSE);
1915 check_property_operator(AO.value);
1916 check_lvalues(AO.value);
1917 ET[AO.value].up = -1;
1920 if ((context != CONSTANT_CONTEXT) && is_property_t(AO.symtype)
1921 && (arrow_allowed) && (!bare_prop_allowed))
1922 warning("Bare property name found. \"self.prop\" intended?");
1925 check_conditions(AO, context);
1927 if (context == CONSTANT_CONTEXT)
1928 if (!is_constant_ot(AO.type))
1929 { AO = zero_operand;
1930 ebf_error("constant", "<expression>");
1937 switch(find_prec(a,b))
1939 case e5: /* Associativity error */
1940 error_named("Brackets mandatory to clarify order of:",
1945 if (sr_sp == MAX_EXPRESSION_NODES)
1946 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1947 sr_stack[sr_sp++] = b;
1951 if (sr_sp >= 2 && sr_stack[sr_sp-2].type == OP_TT && sr_stack[sr_sp-2].value == FCALL_OP)
1952 mark_top_of_emitter_stack(FUNCTION_VALUE_MARKER, b);
1954 add_bracket_layer_to_emitter_stack(0);
1959 if (sr_stack[sr_sp-2].type == OP_TT &&
1960 operators[sr_stack[sr_sp-2].value].precedence == 3)
1961 mark_top_of_emitter_stack(OR_VALUE_MARKER, b);
1963 { error("'or' not between values to the right of a condition");
1964 /* Convert to + for error recovery purposes */
1965 sr_stack[sr_sp-1].value = PLUS_OP;
1970 /* A comma separates arguments only if the shallowest open bracket belongs to a function call. */
1971 int shallowest_open_bracket_index = sr_sp - 2;
1972 while (shallowest_open_bracket_index > 0 && sr_stack[shallowest_open_bracket_index].type != SUBOPEN_TT)
1973 --shallowest_open_bracket_index;
1974 if (shallowest_open_bracket_index > 0 &&
1975 sr_stack[shallowest_open_bracket_index-1].type == OP_TT &&
1976 sr_stack[shallowest_open_bracket_index-1].value == FCALL_OP)
1977 { mark_top_of_emitter_stack(ARGUMENT_VALUE_MARKER, b);
1980 /* Non-argument-separating commas get treated like any other operator; we fall through to the default case. */
1984 /* Add a marker for the brackets implied by operator precedence */
1985 int operands_on_left = (operators[b.value].usage == PRE_U) ? 0 : 1;
1986 add_bracket_layer_to_emitter_stack(operands_on_left);
1994 { pop = sr_stack[sr_sp - 1];
1997 } while (find_prec(sr_stack[sr_sp-1], pop) != LOWER_P);
2000 case e1: /* Missing operand error */
2001 error_named("Missing operand after", a.text);
2003 current_token.type = NUMBER_TT;
2004 current_token.value = 0;
2005 current_token.marker = 0;
2006 current_token.text = "0";
2009 case e2: /* Unexpected close bracket */
2010 error("Found '(' without matching ')'");
2014 case e3: /* Missing operator error */
2015 error("Missing operator: inserting '+'");
2017 current_token.type = OP_TT;
2018 current_token.value = PLUS_OP;
2019 current_token.marker = 0;
2020 current_token.text = "+";
2023 case e4: /* Expression ends with an open bracket */
2024 error("Found '(' without matching ')'");
2033 /* --- Test for simple ++ or -- usage: used to optimise "for" loop code ---- */
2035 extern int test_for_incdec(assembly_operand AO)
2037 if (AO.type != EXPRESSION_OT) return 0;
2038 if (ET[AO.value].down == -1) return 0;
2039 switch(ET[AO.value].operator_number)
2040 { case INC_OP: s = 1; break;
2041 case POST_INC_OP: s = 1; break;
2042 case DEC_OP: s = -1; break;
2043 case POST_DEC_OP: s = -1; break;
2046 if (ET[ET[AO.value].down].down != -1) return 0;
2047 if (!is_variable_ot(ET[ET[AO.value].down].value.type)) return 0;
2048 return s*(ET[ET[AO.value].down].value.value);
2051 /* ========================================================================= */
2052 /* Data structure management routines */
2053 /* ------------------------------------------------------------------------- */
2055 extern void init_expressp_vars(void)
2057 /* make_operands(); */
2058 make_lexical_interface_tables();
2059 for (i=0;i<32;i++) system_function_usage[i] = 0;
2062 extern void expressp_begin_pass(void)
2066 extern void expressp_allocate_arrays(void)
2067 { ET = my_calloc(sizeof(expression_tree_node), MAX_EXPRESSION_NODES,
2068 "expression parse trees");
2069 emitter_markers = my_calloc(sizeof(int), MAX_EXPRESSION_NODES,
2071 emitter_bracket_counts = my_calloc(sizeof(int), MAX_EXPRESSION_NODES,
2072 "emitter bracket layer counts");
2073 emitter_stack = my_calloc(sizeof(assembly_operand), MAX_EXPRESSION_NODES,
2075 sr_stack = my_calloc(sizeof(token_data), MAX_EXPRESSION_NODES,
2076 "shift-reduce parser stack");
2079 extern void expressp_free_arrays(void)
2080 { my_free(&ET, "expression parse trees");
2081 my_free(&emitter_markers, "emitter markers");
2082 my_free(&emitter_bracket_counts, "emitter bracket layer counts");
2083 my_free(&emitter_stack, "emitter stack");
2084 my_free(&sr_stack, "shift-reduce parser stack");
2087 /* ========================================================================= */