1 /* ------------------------------------------------------------------------- */
2 /* "expressp" : The expression parser */
4 /* Copyright (c) Graham Nelson 1993 - 2018 */
6 /* This file is part of Inform. */
8 /* Inform is free software: you can redistribute it and/or modify */
9 /* it under the terms of the GNU General Public License as published by */
10 /* the Free Software Foundation, either version 3 of the License, or */
11 /* (at your option) any later version. */
13 /* Inform is distributed in the hope that it will be useful, */
14 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
15 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
16 /* GNU General Public License for more details. */
18 /* You should have received a copy of the GNU General Public License */
19 /* along with Inform. If not, see https://gnu.org/licenses/ */
21 /* ------------------------------------------------------------------------- */
25 /* --- Interface to lexer -------------------------------------------------- */
27 static char separators_to_operators[103];
28 static char conditionals_to_operators[7];
29 static char token_type_allowable[301];
31 #define NOT_AN_OPERATOR (char) 0x7e
33 static void make_lexical_interface_tables(void)
36 separators_to_operators[i] = NOT_AN_OPERATOR;
37 for (i=0;i<NUM_OPERATORS;i++)
38 if (operators[i].token_type == SEP_TT)
39 separators_to_operators[operators[i].token_value] = i;
41 for (i=0;i<7;i++) /* 7 being the size of keyword_group "conditions" */
42 conditionals_to_operators[i] = NOT_AN_OPERATOR;
43 for (i=0;i<NUM_OPERATORS;i++)
44 if (operators[i].token_type == CND_TT)
45 conditionals_to_operators[operators[i].token_value] = i;
47 for (i=0;i<301;i++) token_type_allowable[i] = 0;
49 token_type_allowable[VARIABLE_TT] = 1;
50 token_type_allowable[SYSFUN_TT] = 1;
51 token_type_allowable[DQ_TT] = 1;
52 token_type_allowable[DICTWORD_TT] = 1;
53 token_type_allowable[SUBOPEN_TT] = 1;
54 token_type_allowable[SUBCLOSE_TT] = 1;
55 token_type_allowable[SMALL_NUMBER_TT] = 1;
56 token_type_allowable[LARGE_NUMBER_TT] = 1;
57 token_type_allowable[ACTION_TT] = 1;
58 token_type_allowable[SYSTEM_CONSTANT_TT] = 1;
59 token_type_allowable[OP_TT] = 1;
62 static token_data current_token, previous_token, heldback_token;
64 static int comma_allowed, arrow_allowed, superclass_allowed,
66 array_init_ambiguity, action_ambiguity,
67 etoken_count, inserting_token, bracket_level;
69 extern int *variable_usage;
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;
167 case INDIVIDUAL_PROPERTY_T:
168 if (module_switch) current_token.marker = IDENT_MV;
171 if (sflags[symbol] & (UNKNOWN_SFLAG + CHANGE_SFLAG))
172 { current_token.marker = SYMBOL_MV;
173 if (module_switch) import_symbol(symbol);
176 else current_token.marker = 0;
179 error_named("Label name used as value:", token_text);
182 current_token.marker = 0;
185 if (sflags[symbol] & SYSTEM_SFLAG)
186 current_token.marker = 0;
188 current_token.value = v;
191 if (((current_token.marker != 0)
192 && (current_token.marker != VARIABLE_MV))
193 || (v < 0) || (v > 255))
194 current_token.type = LARGE_NUMBER_TT;
195 else current_token.type = SMALL_NUMBER_TT;
198 if (((current_token.marker != 0)
199 && (current_token.marker != VARIABLE_MV))
200 || (v < -0x8000) || (v >= 0x8000))
201 current_token.type = LARGE_NUMBER_TT;
202 else current_token.type = SMALL_NUMBER_TT;
205 if (stypes[symbol] == GLOBAL_VARIABLE_T)
206 { current_token.type = VARIABLE_TT;
207 variable_usage[current_token.value] = TRUE;
213 if (current_token.value >= 256)
214 current_token.type = LARGE_NUMBER_TT;
216 current_token.type = SMALL_NUMBER_TT;
219 if (current_token.value < -0x8000
220 || current_token.value >= 0x8000)
221 current_token.type = LARGE_NUMBER_TT;
223 current_token.type = SMALL_NUMBER_TT;
228 switch(current_token.value)
231 current_token.type = ENDEXP_TT;
235 if ((bracket_level==0) && (!comma_allowed))
236 current_token.type = ENDEXP_TT;
240 if ((bracket_level==0) && (!superclass_allowed))
241 current_token.type = ENDEXP_TT;
246 if ((token_type == SEP_TT)
247 &&((token_value == SEMICOLON_SEP)
248 || (token_value == GREATER_SEP)))
249 current_token.type = ENDEXP_TT;
255 if (expr_trace_level>=3)
256 { printf("Previous token type = %d\n",previous_token.type);
257 printf("Previous token val = %d\n",previous_token.value);
259 if ((previous_token.type == OP_TT)
260 || (previous_token.type == SUBOPEN_TT)
261 || (previous_token.type == ENDEXP_TT)
262 || (array_init_ambiguity)
263 || ((bracket_level == 1) && (action_ambiguity)))
264 current_token.type = SUBOPEN_TT;
266 { inserting_token = TRUE;
267 heldback_token = current_token;
268 current_token.text = "<call>";
275 if (bracket_level < 0)
276 current_token.type = ENDEXP_TT;
277 else current_token.type = SUBCLOSE_TT;
281 current_token.type = ENDEXP_TT; break;
284 if ((previous_token.type == OP_TT)
285 || (previous_token.type == SUBOPEN_TT)
286 || (previous_token.type == ENDEXP_TT))
287 current_token.value = UNARY_MINUS_SEP; break;
290 if ((previous_token.type == VARIABLE_TT)
291 || (previous_token.type == SUBCLOSE_TT)
292 || (previous_token.type == LARGE_NUMBER_TT)
293 || (previous_token.type == SMALL_NUMBER_TT))
294 current_token.value = POST_INC_SEP; break;
297 if ((previous_token.type == VARIABLE_TT)
298 || (previous_token.type == SUBCLOSE_TT)
299 || (previous_token.type == LARGE_NUMBER_TT)
300 || (previous_token.type == SMALL_NUMBER_TT))
301 current_token.value = POST_DEC_SEP; break;
304 token_text = current_token.text + 2;
306 ActionUsedAsConstant:
308 current_token.type = ACTION_TT;
309 current_token.text = token_text;
310 current_token.value = 0;
311 current_token.marker = ACTION_MV;
315 case HASHADOLLAR_SEP:
316 obsolete_warning("'#a$Act' is now superseded by '##Act'");
317 token_text = current_token.text + 3;
318 goto ActionUsedAsConstant;
320 case HASHGDOLLAR_SEP:
322 /* This form generates the position of a global variable
323 in the global variables array. So Glob is the same as
324 #globals_array --> #g$Glob */
326 current_token.text += 3;
327 current_token.type = SYMBOL_TT;
328 symbol = symbol_index(current_token.text, -1);
329 if (stypes[symbol] != GLOBAL_VARIABLE_T) {
331 "global variable name after '#g$'",
333 current_token.value = 0;
334 current_token.type = SMALL_NUMBER_TT;
335 current_token.marker = 0;
338 mark_symbol_as_used = TRUE;
339 current_token.value = svals[symbol] - MAX_LOCAL_VARIABLES;
340 current_token.marker = 0;
342 if (current_token.value >= 0x100)
343 current_token.type = LARGE_NUMBER_TT;
344 else current_token.type = SMALL_NUMBER_TT;
347 if (current_token.value >= 0x8000
348 || current_token.value < -0x8000)
349 current_token.type = LARGE_NUMBER_TT;
350 else current_token.type = SMALL_NUMBER_TT;
354 case HASHNDOLLAR_SEP:
356 /* This form is still needed for constants like #n$a (the
357 dictionary address of the word "a"), since 'a' means
358 the ASCII value of 'a' */
360 if (strlen(token_text) > 4)
362 "'#n$word' is now superseded by ''word''");
363 current_token.type = DICTWORD_TT;
364 current_token.value = 0;
365 current_token.text = token_text + 3;
366 current_token.marker = DWORD_MV;
369 case HASHRDOLLAR_SEP:
371 /* This form -- #r$Routinename, to return the routine's */
372 /* packed address -- is needed far less often in Inform 6, */
373 /* where just giving the name Routine returns the packed */
374 /* address. But it's used in a lot of Inform 5 code. */
377 "'#r$Routine' can now be written just 'Routine'");
378 current_token.text += 3;
379 current_token.type = SYMBOL_TT;
380 current_token.value = symbol_index(current_token.text, -1);
383 case HASHWDOLLAR_SEP:
384 error("The obsolete '#w$word' construct has been removed");
388 system_constants.enabled = TRUE;
390 system_constants.enabled = FALSE;
391 if (token_type != SYSTEM_CONSTANT_TT)
393 "'r$', 'n$', 'g$' or internal Inform constant name after '#'",
398 { current_token.type = token_type;
399 current_token.value = token_value;
400 current_token.text = token_text;
401 current_token.marker = INCON_MV;
408 v = conditionals_to_operators[current_token.value];
409 if (v != NOT_AN_OPERATOR)
410 { current_token.type = OP_TT; current_token.value = v;
415 if (current_token.type == SEP_TT)
416 { v = separators_to_operators[current_token.value];
417 if (v != NOT_AN_OPERATOR)
419 || ((v!=MESSAGE_OP) && (v!=MPROP_NUM_OP) && (v!=MPROP_NUM_OP)))
420 { current_token.type = OP_TT; current_token.value = v;
421 if (array_init_ambiguity &&
422 ((v==MINUS_OP) || (v==UNARY_MINUS_OP)) &&
423 (initial_bracket_level == 0) &&
425 warning("Without bracketing, the minus sign '-' is ambiguous");
430 /* A feature of Inform making it annoyingly hard to parse left-to-right
431 is that there is no clear delimiter for expressions; that is, the
432 legal syntax often includes sequences of expressions with no
433 intervening markers such as commas. We therefore need to use some
434 internal context to determine whether an end is in sight... */
436 if (token_type_allowable[current_token.type]==0)
437 { if (expr_trace_level >= 3)
438 { printf("Discarding as not allowable: '%s' ", current_token.text);
439 describe_token(current_token);
442 current_token.type = ENDEXP_TT;
445 if ((!((initial_bracket_level > 0)
446 || (previous_token.type == ENDEXP_TT)
447 || ((previous_token.type == OP_TT)
448 && (operators[previous_token.value].usage != POST_U))
449 || (previous_token.type == SYSFUN_TT)))
450 && ((current_token.type != OP_TT)
451 || (operators[current_token.value].usage == PRE_U)))
452 { if (expr_trace_level >= 3)
453 { printf("Discarding as no longer part: '%s' ", current_token.text);
454 describe_token(current_token);
457 current_token.type = ENDEXP_TT;
460 { if (mark_symbol_as_used) sflags[symbol] |= USED_SFLAG;
461 if (expr_trace_level >= 3)
462 { printf("Expr token = '%s' ", current_token.text);
463 describe_token(current_token);
468 if ((previous_token.type == ENDEXP_TT)
469 && (current_token.type == ENDEXP_TT)) return FALSE;
471 previous_token = current_token;
476 /* --- Operator precedences ------------------------------------------------ */
480 #define GREATER_P 103
482 #define e1 1 /* Missing operand error */
483 #define e2 2 /* Unexpected close bracket */
484 #define e3 3 /* Missing operator error */
485 #define e4 4 /* Expression ends with an open bracket */
486 #define e5 5 /* Associativity illegal error */
488 const int prec_table[] = {
490 /* a .......... ( ) end op term */
492 /* b ( */ LOWER_P, e3, LOWER_P, LOWER_P, e3,
493 /* . ) */ EQUAL_P, GREATER_P, e2, GREATER_P, GREATER_P,
494 /* . end */ e4, GREATER_P, e1, GREATER_P, GREATER_P,
495 /* . op */ LOWER_P, GREATER_P, LOWER_P, -1, GREATER_P,
496 /* . term */ LOWER_P, e3, LOWER_P, LOWER_P, e3
500 static int find_prec(token_data a, token_data b)
502 /* We are comparing the precedence of tokens a and b
503 (where a occurs to the left of b). If the expression is correct,
504 the only possible values are GREATER_P, LOWER_P or EQUAL_P;
505 if it is malformed then one of e1 to e5 results.
507 Note that this routine is not symmetrical and that the relation
510 If a and b are equal (and aren't brackets), then
512 a LOWER_P a if a right-associative
513 a GREATER_P a if a left-associative
519 { case SUBOPEN_TT: i=0; break;
520 case SUBCLOSE_TT: i=1; break;
521 case ENDEXP_TT: i=2; break;
522 case OP_TT: i=3; break;
526 { case SUBOPEN_TT: i+=0; break;
527 case SUBCLOSE_TT: i+=5; break;
528 case ENDEXP_TT: i+=10; break;
529 case OP_TT: i+=15; break;
530 default: i+=20; break;
533 j = prec_table[i]; if (j != -1) return j;
535 l1 = operators[a.value].precedence;
536 l2 = operators[b.value].precedence;
537 if (operators[b.value].usage == PRE_U) return LOWER_P;
538 if (operators[a.value].usage == POST_U) return GREATER_P;
540 /* Anomalous rule to resolve the function call precedence, which is
541 different on the right from on the left, e.g., in:
547 if ((l1 == 11) && (l2 > 11)) return GREATER_P;
549 if (l1 < l2) return LOWER_P;
550 if (l1 > l2) return GREATER_P;
551 switch(operators[a.value].associativity)
552 { case L_A: return GREATER_P;
553 case R_A: return LOWER_P;
559 /* --- Converting token to operand ----------------------------------------- */
561 /* Must match the switch statement below */
562 int z_system_constant_list[] =
563 { adjectives_table_SC,
566 identifiers_table_SC,
571 actual_largest_object_SC,
572 static_memory_offset_SC,
573 array_names_offset_SC,
574 readable_memory_offset_SC,
581 highest_attribute_number_SC,
582 attribute_names_array_SC,
583 highest_property_number_SC,
584 property_names_array_SC,
585 highest_action_number_SC,
586 action_names_array_SC,
587 highest_fake_action_number_SC,
588 fake_action_names_array_SC,
589 highest_routine_number_SC,
590 routine_names_array_SC,
592 routine_flags_array_SC,
593 highest_global_number_SC,
594 global_names_array_SC,
596 global_flags_array_SC,
597 highest_array_number_SC,
598 array_names_array_SC,
599 array_flags_array_SC,
600 highest_constant_number_SC,
601 constant_names_array_SC,
602 highest_class_number_SC,
603 class_objects_array_SC,
604 highest_object_number_SC,
607 static int32 value_of_system_constant_z(int t)
609 { case adjectives_table_SC:
610 return adjectives_offset;
611 case actions_table_SC:
612 return actions_offset;
613 case classes_table_SC:
614 return class_numbers_offset;
615 case identifiers_table_SC:
616 return identifier_names_offset;
617 case preactions_table_SC:
618 return preactions_offset;
619 case largest_object_SC:
620 return 256 + no_objects - 1;
621 case strings_offset_SC:
622 return strings_offset/scale_factor;
624 return code_offset/scale_factor;
625 case actual_largest_object_SC:
627 case static_memory_offset_SC:
628 return static_memory_offset;
629 case array_names_offset_SC:
630 return array_names_offset;
631 case readable_memory_offset_SC:
632 return Write_Code_At;
634 return prop_values_offset;
636 return class_numbers_offset;
638 return individuals_offset;
640 return variables_offset;
641 case array__start_SC:
642 return variables_offset + (MAX_GLOBAL_VARIABLES*WORDSIZE);
644 return static_memory_offset;
646 case highest_attribute_number_SC:
647 return no_attributes-1;
648 case attribute_names_array_SC:
649 return attribute_names_offset;
651 case highest_property_number_SC:
652 return no_individual_properties-1;
653 case property_names_array_SC:
654 return identifier_names_offset + 2;
656 case highest_action_number_SC:
658 case action_names_array_SC:
659 return action_names_offset;
661 case highest_fake_action_number_SC:
662 return ((grammar_version_number==1)?256:4096) + no_fake_actions-1;
663 case fake_action_names_array_SC:
664 return fake_action_names_offset;
666 case highest_routine_number_SC:
667 return no_named_routines-1;
668 case routine_names_array_SC:
669 return routine_names_offset;
670 case routines_array_SC:
671 return routines_array_offset;
672 case routine_flags_array_SC:
673 return routine_flags_array_offset;
674 case highest_global_number_SC:
675 return 16 + no_globals-1;
676 case global_names_array_SC:
677 return global_names_offset;
678 case globals_array_SC:
679 return variables_offset;
680 case global_flags_array_SC:
681 return global_flags_array_offset;
682 case highest_array_number_SC:
684 case array_names_array_SC:
685 return array_names_offset;
686 case array_flags_array_SC:
687 return array_flags_array_offset;
688 case highest_constant_number_SC:
689 return no_named_constants-1;
690 case constant_names_array_SC:
691 return constant_names_offset;
692 case highest_class_number_SC:
694 case class_objects_array_SC:
695 return class_numbers_offset;
696 case highest_object_number_SC:
700 error_named("System constant not implemented in Z-code",
701 system_constants.keywords[t]);
706 /* Must match the switch statement below */
707 int glulx_system_constant_list[] =
709 identifiers_table_SC,
710 array_names_offset_SC,
714 dynam_string_table_SC,
718 highest_class_number_SC,
719 highest_object_number_SC,
722 static int32 value_of_system_constant_g(int t)
725 case classes_table_SC:
726 return Write_RAM_At + class_numbers_offset;
727 case identifiers_table_SC:
728 return Write_RAM_At + identifier_names_offset;
729 case array_names_offset_SC:
730 return Write_RAM_At + array_names_offset;
732 return prop_defaults_offset;
734 return Write_RAM_At + class_numbers_offset;
735 case dictionary_table_SC:
736 return dictionary_offset;
737 case dynam_string_table_SC:
738 return abbreviations_offset;
739 case grammar_table_SC:
740 return grammar_table_offset;
741 case actions_table_SC:
742 return actions_offset;
743 case globals_array_SC:
744 return variables_offset;
745 case highest_class_number_SC:
747 case highest_object_number_SC:
751 error_named("System constant not implemented in Glulx",
752 system_constants.keywords[t]);
757 extern int32 value_of_system_constant(int t)
760 return value_of_system_constant_z(t);
762 return value_of_system_constant_g(t);
765 static int evaluate_term(token_data t, assembly_operand *o)
767 /* If the given token is a constant, evaluate it into the operand.
768 For now, the identifiers are considered variables.
770 Returns FALSE if it fails to understand type. */
774 o->marker = t.marker;
775 o->symtype = t.symtype;
776 o->symflags = t.symflags;
779 { case LARGE_NUMBER_TT:
782 if (v < 0) v = v + 0x10000;
783 o->type = LONG_CONSTANT_OT;
788 o->type = CONSTANT_OT;
791 case SMALL_NUMBER_TT:
794 if (v < 0) v = v + 0x10000;
795 o->type = SHORT_CONSTANT_OT;
804 /* Find the dictionary address, adding to dictionary if absent */
806 o->type = LONG_CONSTANT_OT;
808 o->type = CONSTANT_OT;
809 o->value = dictionary_add(t.text, 0x80, 0, 0);
812 /* Create as a static string */
814 o->type = LONG_CONSTANT_OT;
816 o->type = CONSTANT_OT;
817 o->value = compile_string(t.text, FALSE, FALSE);
821 o->type = VARIABLE_OT;
824 if (t.value >= MAX_LOCAL_VARIABLES) {
825 o->type = GLOBALVAR_OT;
828 /* This includes "local variable zero", which is really
829 the stack-pointer magic variable. */
830 o->type = LOCALVAR_OT;
837 o->type = VARIABLE_OT;
838 o->value = t.value + 256;
844 system_function_usage[t.value] = 1;
847 *o = action_of_name(t.text);
849 case SYSTEM_CONSTANT_TT:
850 /* Certain system constants depend only on the
851 version number and need no backpatching, as they
852 are known in advance. We can therefore evaluate
855 o->type = LONG_CONSTANT_OT;
858 case version_number_SC:
859 o->type = SHORT_CONSTANT_OT;
861 v = version_number; break;
863 o->type = SHORT_CONSTANT_OT;
865 v = (version_number==3)?4:6; break;
867 o->type = SHORT_CONSTANT_OT;
869 v = (version_number==3)?5:7; break;
871 o->type = SHORT_CONSTANT_OT;
873 v = (version_number==3)?6:8; break;
874 case lowest_attribute_number_SC:
875 case lowest_action_number_SC:
876 case lowest_routine_number_SC:
877 case lowest_array_number_SC:
878 case lowest_constant_number_SC:
879 case lowest_class_number_SC:
880 o->type = SHORT_CONSTANT_OT; o->marker = 0; v = 0; break;
881 case lowest_object_number_SC:
882 case lowest_property_number_SC:
883 o->type = SHORT_CONSTANT_OT; o->marker = 0; v = 1; break;
884 case lowest_global_number_SC:
885 o->type = SHORT_CONSTANT_OT; o->marker = 0; v = 16; break;
886 case lowest_fake_action_number_SC:
887 o->type = LONG_CONSTANT_OT; o->marker = 0;
888 v = ((grammar_version_number==1)?256:4096); break;
889 case oddeven_packing_SC:
890 o->type = SHORT_CONSTANT_OT; o->marker = 0;
891 v = oddeven_packing_switch; break;
894 o->marker = INCON_MV;
900 o->type = CONSTANT_OT;
903 /* The three dict_par flags point at the lower byte
904 of the flag field, because the library is written
905 to expect one-byte fields, even though the compiler
906 generates a dictionary with room for two. */
908 o->type = BYTECONSTANT_OT;
910 v = DICT_ENTRY_FLAG_POS+1;
913 o->type = BYTECONSTANT_OT;
915 v = DICT_ENTRY_FLAG_POS+3;
918 o->type = BYTECONSTANT_OT;
920 v = DICT_ENTRY_FLAG_POS+5;
923 case lowest_attribute_number_SC:
924 case lowest_action_number_SC:
925 case lowest_routine_number_SC:
926 case lowest_array_number_SC:
927 case lowest_constant_number_SC:
928 case lowest_class_number_SC:
929 o->type = BYTECONSTANT_OT;
933 case lowest_object_number_SC:
934 case lowest_property_number_SC:
935 o->type = BYTECONSTANT_OT;
940 /* ###fix: need to fill more of these in! */
944 o->marker = INCON_MV;
955 /* --- Emitter ------------------------------------------------------------- */
957 expression_tree_node *ET;
960 extern void clear_expression_space(void)
964 static assembly_operand *emitter_stack;
965 static int *emitter_markers;
966 static int *emitter_bracket_counts;
968 #define FUNCTION_VALUE_MARKER 1
969 #define ARGUMENT_VALUE_MARKER 2
970 #define OR_VALUE_MARKER 3
972 static int emitter_sp;
974 static int is_property_t(int symbol_type)
975 { return ((symbol_type == PROPERTY_T) || (symbol_type == INDIVIDUAL_PROPERTY_T));
978 static void mark_top_of_emitter_stack(int marker, token_data t)
979 { if (emitter_sp < 1)
980 { compiler_error("SR error: Attempt to add a marker to the top of an empty emitter stack");
983 if (expr_trace_level >= 2)
984 { printf("Marking top of emitter stack (which is ");
985 print_operand(emitter_stack[emitter_sp-1]);
989 case FUNCTION_VALUE_MARKER:
992 case ARGUMENT_VALUE_MARKER:
995 case OR_VALUE_MARKER:
1004 if (emitter_markers[emitter_sp-1])
1005 { if (marker == ARGUMENT_VALUE_MARKER)
1007 warning("Ignoring spurious leading comma");
1010 error_named("Missing operand for", t.text);
1011 if (emitter_sp == MAX_EXPRESSION_NODES)
1012 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1013 emitter_markers[emitter_sp] = 0;
1014 emitter_bracket_counts[emitter_sp] = 0;
1015 emitter_stack[emitter_sp] = zero_operand;
1018 emitter_markers[emitter_sp-1] = marker;
1021 static void add_bracket_layer_to_emitter_stack(int depth)
1022 { /* There's no point in tracking bracket layers that don't fence off any values. */
1023 if (emitter_sp < depth + 1) return;
1024 if (expr_trace_level >= 2)
1025 printf("Adding bracket layer\n");
1026 ++emitter_bracket_counts[emitter_sp-depth-1];
1029 static void remove_bracket_layer_from_emitter_stack()
1030 { /* Bracket layers that don't fence off any values will not have been tracked. */
1031 if (emitter_sp < 2) return;
1032 if (expr_trace_level >= 2)
1033 printf("Removing bracket layer\n");
1034 if (emitter_bracket_counts[emitter_sp-2] <= 0)
1035 { compiler_error("SR error: Attempt to remove a nonexistent bracket layer from the emitter stack");
1038 --emitter_bracket_counts[emitter_sp-2];
1041 static void emit_token(token_data t)
1042 { assembly_operand o1, o2; int arity, stack_size, i;
1043 int op_node_number, operand_node_number, previous_node_number;
1046 if (expr_trace_level >= 2)
1047 { printf("Output: %-19s%21s ", t.text, "");
1048 for (i=0; i<emitter_sp; i++)
1049 { print_operand(emitter_stack[i]); printf(" ");
1050 if (emitter_markers[i] == FUNCTION_VALUE_MARKER) printf(":FUNCTION ");
1051 if (emitter_markers[i] == ARGUMENT_VALUE_MARKER) printf(":ARGUMENT ");
1052 if (emitter_markers[i] == OR_VALUE_MARKER) printf(":OR ");
1053 if (emitter_bracket_counts[i]) printf(":BRACKETS(%d) ", emitter_bracket_counts[i]);
1058 if (t.type == SUBOPEN_TT) return;
1061 while ((stack_size < emitter_sp) &&
1062 !emitter_markers[emitter_sp-stack_size-1] &&
1063 !emitter_bracket_counts[emitter_sp-stack_size-1])
1066 if (t.type == SUBCLOSE_TT)
1067 { if (stack_size < emitter_sp && emitter_bracket_counts[emitter_sp-stack_size-1])
1068 { if (stack_size == 0)
1069 { error("No expression between brackets '(' and ')'");
1070 emitter_stack[emitter_sp] = zero_operand;
1071 emitter_markers[emitter_sp] = 0;
1072 emitter_bracket_counts[emitter_sp] = 0;
1075 else if (stack_size < 1)
1076 compiler_error("SR error: emitter stack empty in subexpression");
1077 else if (stack_size > 1)
1078 compiler_error("SR error: emitter stack overfull in subexpression");
1079 remove_bracket_layer_from_emitter_stack();
1084 if (t.type != OP_TT)
1085 { emitter_markers[emitter_sp] = 0;
1086 emitter_bracket_counts[emitter_sp] = 0;
1088 if (emitter_sp == MAX_EXPRESSION_NODES)
1089 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1090 if (!evaluate_term(t, &(emitter_stack[emitter_sp++])))
1091 compiler_error_named("Emit token error:", t.text);
1095 /* A comma is argument-separating if it follows an argument (or a function
1096 call, since we ignore spurious leading commas in function argument lists)
1097 with no intervening brackets. Function calls are variadic, so we don't
1098 apply argument-separating commas. */
1099 if (t.value == COMMA_OP &&
1100 stack_size < emitter_sp &&
1101 (emitter_markers[emitter_sp-stack_size-1] == ARGUMENT_VALUE_MARKER ||
1102 emitter_markers[emitter_sp-stack_size-1] == FUNCTION_VALUE_MARKER) &&
1103 !emitter_bracket_counts[emitter_sp-stack_size-1])
1104 { if (expr_trace_level >= 2)
1105 printf("Treating comma as argument-separating\n");
1109 if (t.value == OR_OP)
1113 if (t.value == FCALL_OP)
1114 { if (expr_trace_level >= 3)
1115 { printf("FCALL_OP finds marker stack: ");
1116 for (x=0; x<emitter_sp; x++) printf("%d ", emitter_markers[x]);
1119 if (emitter_markers[emitter_sp-1] == ARGUMENT_VALUE_MARKER)
1120 warning("Ignoring spurious trailing comma");
1121 while (emitter_markers[emitter_sp-arity] != FUNCTION_VALUE_MARKER)
1124 emitter_stack[emitter_sp-arity].type == SYSFUN_OT) ||
1126 emitter_stack[emitter_sp-arity].type == VARIABLE_OT &&
1127 emitter_stack[emitter_sp-arity].value >= 256 &&
1128 emitter_stack[emitter_sp-arity].value < 288))
1129 { int index = emitter_stack[emitter_sp-arity].value;
1132 if(index >= 0 && index < NUMBER_SYSTEM_FUNCTIONS)
1133 error_named("System function name used as a value:", system_functions.keywords[index]);
1135 compiler_error("Found unnamed system function used as a value");
1136 emitter_stack[emitter_sp-arity] = zero_operand;
1143 if (operators[t.value].usage == IN_U) arity = 2;
1145 if (operators[t.value].precedence == 3)
1148 if(!emitter_markers[x] && !emitter_bracket_counts[x])
1149 { for (--x; emitter_markers[x] == OR_VALUE_MARKER && !emitter_bracket_counts[x]; --x)
1153 for (;x >= 0 && !emitter_markers[x] && !emitter_bracket_counts[x]; --x)
1158 if (arity > stack_size)
1159 { error_named("Missing operand for", t.text);
1160 while (arity > stack_size)
1161 { if (emitter_sp == MAX_EXPRESSION_NODES)
1162 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1163 emitter_markers[emitter_sp] = 0;
1164 emitter_bracket_counts[emitter_sp] = 0;
1165 emitter_stack[emitter_sp] = zero_operand;
1172 /* pseudo-typecheck in 6.30 */
1173 for (i = 1; i <= arity; i++)
1175 o1 = emitter_stack[emitter_sp - i];
1176 if (is_property_t(o1.symtype) ) {
1180 case SETEQUALS_OP: case NOTEQUAL_OP:
1182 case PROVIDES_OP: case NOTPROVIDES_OP:
1183 case PROP_ADD_OP: case PROP_NUM_OP:
1185 case MPROP_ADD_OP: case MESSAGE_OP:
1187 if (i < arity) break;
1188 case GE_OP: case LE_OP:
1189 if ((i < arity) && (o1.symflags & STAR_SFLAG)) break;
1191 warning("Property name in expression is not qualified by object");
1193 } /* if (is_property_t */
1198 o1 = emitter_stack[emitter_sp - 1];
1199 if ((o1.marker == 0) && is_constant_ot(o1.type))
1201 { case UNARY_MINUS_OP: x = -o1.value; goto FoldConstant;
1204 x = (~o1.value) & 0xffff;
1206 x = (~o1.value) & 0xffffffff;
1209 if (o1.value != 0) x=0; else x=1;
1216 o1 = emitter_stack[emitter_sp - 2];
1217 o2 = emitter_stack[emitter_sp - 1];
1219 if ((o1.marker == 0) && (o2.marker == 0)
1220 && is_constant_ot(o1.type) && is_constant_ot(o2.type))
1228 { ov1 = (o1.value >= 0x8000) ? (o1.value - 0x10000) : o1.value;
1229 ov2 = (o2.value >= 0x8000) ? (o2.value - 0x10000) : o2.value;
1234 case PLUS_OP: x = ov1 + ov2; goto FoldConstantC;
1235 case MINUS_OP: x = ov1 - ov2; goto FoldConstantC;
1236 case TIMES_OP: x = ov1 * ov2; goto FoldConstantC;
1240 error("Division of constant by zero");
1242 if (t.value == DIVIDE_OP) {
1250 x = -((-ov1) / ov2);
1259 x = -((-ov1) % ov2);
1262 case ARTAND_OP: x = o1.value & o2.value; goto FoldConstant;
1263 case ARTOR_OP: x = o1.value | o2.value; goto FoldConstant;
1265 if (o1.value == o2.value) x = 1; else x = 0;
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 != 0) && (o2.value != 0)) x=1; else x=0;
1286 if ((o1.value != 0) || (o2.value != 0)) x=1; else x=0;
1293 op_node_number = ET_used++;
1294 if (op_node_number == MAX_EXPRESSION_NODES)
1295 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1297 ET[op_node_number].operator_number = t.value;
1298 ET[op_node_number].up = -1;
1299 ET[op_node_number].down = -1;
1300 ET[op_node_number].right = -1;
1302 /* This statement is redundant, but prevents compilers from wrongly
1303 issuing a "used before it was assigned a value" error: */
1304 previous_node_number = 0;
1306 for (i = emitter_sp-arity; i != emitter_sp; i++)
1308 if (expr_trace_level >= 3)
1309 printf("i=%d, emitter_sp=%d, arity=%d, ETU=%d\n",
1310 i, emitter_sp, arity, ET_used);
1311 if (emitter_stack[i].type == EXPRESSION_OT)
1312 operand_node_number = emitter_stack[i].value;
1314 { operand_node_number = ET_used++;
1315 if (operand_node_number == MAX_EXPRESSION_NODES)
1316 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1317 ET[operand_node_number].down = -1;
1318 ET[operand_node_number].value = emitter_stack[i];
1320 ET[operand_node_number].up = op_node_number;
1321 ET[operand_node_number].right = -1;
1322 if (i == emitter_sp - arity)
1323 { ET[op_node_number].down = operand_node_number;
1326 { ET[previous_node_number].right = operand_node_number;
1328 previous_node_number = operand_node_number;
1331 emitter_sp = emitter_sp - arity + 1;
1333 emitter_stack[emitter_sp - 1].type = EXPRESSION_OT;
1334 emitter_stack[emitter_sp - 1].value = op_node_number;
1335 emitter_stack[emitter_sp - 1].marker = 0;
1336 emitter_markers[emitter_sp - 1] = 0;
1337 emitter_bracket_counts[emitter_sp - 1] = 0;
1338 /* Remove the marker for the brackets implied by operator precedence */
1339 remove_bracket_layer_from_emitter_stack();
1345 /* In Glulx, skip this test; we can't check out-of-range errors
1346 for 32-bit arithmetic. */
1348 if (!glulx_mode && ((x<-32768) || (x > 32767)))
1349 { char folding_error[40];
1350 int32 ov1 = (o1.value >= 0x8000) ? (o1.value - 0x10000) : o1.value;
1351 int32 ov2 = (o2.value >= 0x8000) ? (o2.value - 0x10000) : o2.value;
1355 sprintf(folding_error, "%d + %d = %d", ov1, ov2, x);
1358 sprintf(folding_error, "%d - %d = %d", ov1, ov2, x);
1361 sprintf(folding_error, "%d * %d = %d", ov1, ov2, x);
1364 error_named("Signed arithmetic on compile-time constants overflowed \
1365 the range -32768 to +32767:", folding_error);
1371 while (x < 0) x = x + 0x10000;
1378 emitter_sp = emitter_sp - arity + 1;
1382 emitter_stack[emitter_sp - 1].type = SHORT_CONSTANT_OT;
1383 else emitter_stack[emitter_sp - 1].type = LONG_CONSTANT_OT;
1387 emitter_stack[emitter_sp - 1].type = ZEROCONSTANT_OT;
1388 else if (x >= -128 && x <= 127)
1389 emitter_stack[emitter_sp - 1].type = BYTECONSTANT_OT;
1390 else if (x >= -32768 && x <= 32767)
1391 emitter_stack[emitter_sp - 1].type = HALFCONSTANT_OT;
1393 emitter_stack[emitter_sp - 1].type = CONSTANT_OT;
1396 emitter_stack[emitter_sp - 1].value = x;
1397 emitter_stack[emitter_sp - 1].marker = 0;
1398 emitter_markers[emitter_sp - 1] = 0;
1399 emitter_bracket_counts[emitter_sp - 1] = 0;
1401 if (expr_trace_level >= 2)
1402 { printf("Folding constant to: ");
1403 print_operand(emitter_stack[emitter_sp - 1]);
1407 /* Remove the marker for the brackets implied by operator precedence */
1408 remove_bracket_layer_from_emitter_stack();
1412 /* --- Pretty printing ----------------------------------------------------- */
1414 static void show_node(int n, int depth, int annotate)
1416 for (j=0; j<2*depth+2; j++) printf(" ");
1418 if (ET[n].down == -1)
1419 { print_operand(ET[n].value);
1420 if (annotate && (ET[n].value.marker != 0))
1421 printf(" [%s]", describe_mv(ET[n].value.marker));
1425 { printf("%s ", operators[ET[n].operator_number].description);
1426 j = operators[ET[n].operator_number].precedence;
1427 if ((annotate) && ((j==2) || (j==3)))
1428 { printf(" %d|%d ", ET[n].true_label, ET[n].false_label);
1429 if (ET[n].label_after != -1) printf(" def %d after ",
1431 if (ET[n].to_expression) printf(" con to expr ");
1434 show_node(ET[n].down, depth+1, annotate);
1437 if (ET[n].right != -1) show_node(ET[n].right, depth, annotate);
1440 extern void show_tree(assembly_operand AO, int annotate)
1441 { if (AO.type == EXPRESSION_OT) show_node(AO.value, 0, annotate);
1443 { printf("Constant: "); print_operand(AO);
1444 if (annotate && (AO.marker != 0))
1445 printf(" [%s]", describe_mv(AO.marker));
1450 /* --- Lvalue transformations ---------------------------------------------- */
1452 /* This only gets called in Z-code, since Glulx doesn't distinguish
1453 individual property operators from general ones. */
1454 static void check_property_operator(int from_node)
1455 { int below = ET[from_node].down;
1456 int opnum = ET[from_node].operator_number;
1460 if (veneer_mode) return;
1462 if ((below != -1) && (ET[below].right != -1))
1463 { int n = ET[below].right, flag = FALSE;
1465 if ((ET[n].down == -1)
1466 && ((ET[n].value.type == LONG_CONSTANT_OT)
1467 || (ET[n].value.type == SHORT_CONSTANT_OT))
1468 && ((ET[n].value.value > 0) && (ET[n].value.value < 64))
1469 && ((!module_switch) || (ET[n].value.marker == 0)))
1474 { case PROPERTY_OP: opnum = MESSAGE_OP; break;
1475 case PROP_ADD_OP: opnum = MPROP_ADD_OP; break;
1476 case PROP_NUM_OP: opnum = MPROP_NUM_OP; break;
1480 ET[from_node].operator_number = opnum;
1484 check_property_operator(below);
1485 if (ET[from_node].right != -1)
1486 check_property_operator(ET[from_node].right);
1489 static void check_lvalues(int from_node)
1490 { int below = ET[from_node].down;
1491 int opnum = ET[from_node].operator_number, opnum_below;
1492 int lvalue_form, i, j = 0;
1496 if ((opnum == FCALL_OP) && (ET[below].down != -1))
1497 { opnum_below = ET[below].operator_number;
1498 if ((opnum_below == PROPERTY_OP) || (opnum_below == MESSAGE_OP))
1499 { i = ET[ET[from_node].down].right;
1500 ET[from_node].down = ET[below].down;
1501 ET[ET[below].down].up = from_node;
1502 ET[ET[ET[below].down].right].up = from_node;
1503 ET[ET[ET[below].down].right].right = i;
1504 opnum = PROP_CALL_OP;
1505 ET[from_node].operator_number = opnum;
1509 if (operators[opnum].requires_lvalue)
1510 { opnum_below = ET[below].operator_number;
1512 if (ET[below].down == -1)
1513 { if (!is_variable_ot(ET[below].value.type))
1514 { error("'=' applied to undeclared variable");
1521 { case SETEQUALS_OP:
1523 { case ARROW_OP: lvalue_form = ARROW_SETEQUALS_OP; break;
1524 case DARROW_OP: lvalue_form = DARROW_SETEQUALS_OP; break;
1525 case MESSAGE_OP: lvalue_form = MESSAGE_SETEQUALS_OP; break;
1526 case PROPERTY_OP: lvalue_form = PROPERTY_SETEQUALS_OP; break;
1531 { case ARROW_OP: lvalue_form = ARROW_INC_OP; break;
1532 case DARROW_OP: lvalue_form = DARROW_INC_OP; break;
1533 case MESSAGE_OP: lvalue_form = MESSAGE_INC_OP; break;
1534 case PROPERTY_OP: lvalue_form = PROPERTY_INC_OP; break;
1539 { case ARROW_OP: lvalue_form = ARROW_POST_INC_OP; break;
1540 case DARROW_OP: lvalue_form = DARROW_POST_INC_OP; break;
1541 case MESSAGE_OP: lvalue_form = MESSAGE_POST_INC_OP; break;
1542 case PROPERTY_OP: lvalue_form = PROPERTY_POST_INC_OP; break;
1547 { case ARROW_OP: lvalue_form = ARROW_DEC_OP; break;
1548 case DARROW_OP: lvalue_form = DARROW_DEC_OP; break;
1549 case MESSAGE_OP: lvalue_form = MESSAGE_DEC_OP; break;
1550 case PROPERTY_OP: lvalue_form = PROPERTY_DEC_OP; break;
1555 { case ARROW_OP: lvalue_form = ARROW_POST_DEC_OP; break;
1556 case DARROW_OP: lvalue_form = DARROW_POST_DEC_OP; break;
1557 case MESSAGE_OP: lvalue_form = MESSAGE_POST_DEC_OP; break;
1558 case PROPERTY_OP: lvalue_form = PROPERTY_POST_DEC_OP; break;
1562 if (lvalue_form == 0)
1563 { error_named("'=' applied to",
1564 (char *) operators[opnum_below].description);
1568 /* Transform from_node from_node
1570 below value to value
1574 ET[from_node].operator_number = lvalue_form;
1576 ET[from_node].down = i;
1578 { ET[i].up = from_node;
1582 ET[j].right = ET[below].right;
1585 check_lvalues(below);
1587 if (ET[from_node].right != -1)
1588 check_lvalues(ET[from_node].right);
1592 ET[from_node].down = -1;
1593 ET[from_node].value = zero_operand;
1594 if (ET[from_node].right != -1)
1595 check_lvalues(ET[from_node].right);
1598 /* --- Tree surgery for conditionals --------------------------------------- */
1600 static void negate_condition(int n)
1603 if (ET[n].right != -1) negate_condition(ET[n].right);
1604 if (ET[n].down == -1) return;
1605 i = operators[ET[n].operator_number].negation;
1606 if (i!=0) ET[n].operator_number = i;
1607 if (operators[i].precedence==2) negate_condition(ET[n].down);
1610 static void delete_negations(int n, int context)
1612 /* Recursively apply
1614 ~~(x && y) = ~~x || ~~y
1615 ~~(x || y) = ~~x && ~~y
1618 (etc) to delete the ~~ operator from the tree. Since this is
1619 depth first, the ~~ being deleted has no ~~s beneath it, which
1620 is important to make "negate_condition" work. */
1624 if (ET[n].right != -1) delete_negations(ET[n].right, context);
1625 if (ET[n].down == -1) return;
1626 delete_negations(ET[n].down, context);
1628 if (ET[n].operator_number == LOGNOT_OP)
1629 { negate_condition(ET[n].down);
1630 ET[n].operator_number
1631 = ET[ET[n].down].operator_number;
1632 ET[n].down = ET[ET[n].down].down;
1634 while(i != -1) { ET[i].up = n; i = ET[i].right; }
1638 static void insert_exp_to_cond(int n, int context)
1640 /* Insert a ~= test when an expression is used as a condition.
1642 Check for possible confusion over = and ==, e.g. "if (a = 1) ..." */
1646 if (ET[n].right != -1) insert_exp_to_cond(ET[n].right, context);
1648 if (ET[n].down == -1)
1649 { if (context==CONDITION_CONTEXT)
1651 if (new == MAX_EXPRESSION_NODES)
1652 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1654 ET[n].down = new; ET[n].operator_number = NONZERO_OP;
1655 ET[new].up = n; ET[new].right = -1;
1660 switch(operators[ET[n].operator_number].precedence)
1661 { case 3: /* Conditionals have level 3 */
1662 context = QUANTITY_CONTEXT;
1664 case 2: /* Logical operators level 2 */
1665 context = CONDITION_CONTEXT;
1667 case 1: /* Forms of '=' have level 1 */
1668 if (context == CONDITION_CONTEXT)
1669 warning("'=' used as condition: '==' intended?");
1671 if (context != CONDITION_CONTEXT) break;
1674 if (new == MAX_EXPRESSION_NODES)
1675 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1677 ET[n].down = new; ET[n].operator_number = NONZERO_OP;
1678 ET[new].up = n; ET[new].right = -1;
1681 while (i!= -1) { ET[i].up = new; i = ET[i].right; }
1682 context = QUANTITY_CONTEXT; n = new;
1685 insert_exp_to_cond(ET[n].down, context);
1688 static unsigned int etoken_num_children(int n)
1693 if (i == -1) { return 0; }
1701 static void func_args_on_stack(int n, int context)
1703 /* Make sure that the arguments of every function-call expression
1704 are stored to the stack. If any aren't (ie, if any arguments are
1705 constants or variables), cover them with push operators.
1706 (The very first argument does not need to be so treated, because
1707 it's the function address, not a function argument. We also
1708 skip the treatment for most system functions.) */
1710 int new, pn, fnaddr, opnum;
1714 if (ET[n].right != -1)
1715 func_args_on_stack(ET[n].right, context);
1716 if (ET[n].down == -1) {
1719 opnum = ET[pn].operator_number;
1720 if (opnum == FCALL_OP
1721 || opnum == MESSAGE_CALL_OP
1722 || opnum == PROP_CALL_OP) {
1723 /* If it's an FCALL, get the operand which contains the function
1724 address (or system-function number) */
1725 if (opnum == MESSAGE_CALL_OP
1726 || opnum == PROP_CALL_OP
1727 || ((fnaddr=ET[pn].down) != n
1728 && (ET[fnaddr].value.type != SYSFUN_OT
1729 || ET[fnaddr].value.value == INDIRECT_SYSF
1730 || ET[fnaddr].value.value == GLK_SYSF))) {
1731 if (etoken_num_children(pn) > (unsigned int)(opnum == FCALL_OP ? 4:3)) {
1733 if (new == MAX_EXPRESSION_NODES)
1734 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1737 ET[n].operator_number = PUSH_OP;
1747 func_args_on_stack(ET[n].down, context);
1750 static assembly_operand check_conditions(assembly_operand AO, int context)
1753 if (AO.type != EXPRESSION_OT)
1754 { if (context != CONDITION_CONTEXT) return AO;
1756 if (n == MAX_EXPRESSION_NODES)
1757 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1762 INITAOT(&AO, EXPRESSION_OT);
1766 insert_exp_to_cond(AO.value, context);
1767 delete_negations(AO.value, context);
1770 func_args_on_stack(AO.value, context);
1775 /* --- Shift-reduce parser ------------------------------------------------- */
1778 static token_data *sr_stack;
1780 extern assembly_operand parse_expression(int context)
1782 /* Parses an expression, evaluating it as a constant if possible.
1784 Possible contexts are:
1786 VOID_CONTEXT the expression is used as a statement, so that
1787 its value will be thrown away and it only
1788 needs to exist for any resulting side-effects
1789 (function calls and assignments)
1791 CONDITION_CONTEXT the result must be a condition
1793 CONSTANT_CONTEXT there is required to be a constant result
1794 (so that, for instance, comma becomes illegal)
1796 QUANTITY_CONTEXT the default: a quantity is to be specified
1798 ACTION_Q_CONTEXT like QUANTITY_CONTEXT, but postfixed brackets
1799 at the top level do not indicate function call:
1801 <Insert button (random(pocket1, pocket2))>
1803 RETURN_Q_CONTEXT like QUANTITY_CONTEXT, but a single property
1804 name does not generate a warning
1806 ASSEMBLY_CONTEXT a quantity which cannot use the '->' operator
1807 (needed for assembly language to indicate
1810 FORINIT_CONTEXT a quantity which cannot use an (unbracketed)
1813 ARRAY_CONTEXT like CONSTANT_CONTEXT, but where an unbracketed
1814 minus sign is ambiguous, and brackets always
1815 indicate subexpressions, not function calls
1817 Return value: an assembly operand.
1819 If the type is OMITTED_OT, then the expression has no resulting value.
1821 If the type is EXPRESSION_OT, then the value will need to be
1822 calculated at run-time by code compiled from the expression tree
1823 whose root node-number is the operand value.
1825 Otherwise the assembly operand is the value of the expression, which
1826 is constant and thus known at compile time.
1828 If an error has occurred in the expression, which recovery from was
1829 not possible, then the return is (short constant) 0. This should
1830 minimise the chance of a cascade of further error messages.
1833 token_data a, b, pop; int i;
1834 assembly_operand AO;
1836 superclass_allowed = (context != FORINIT_CONTEXT);
1837 if (context == FORINIT_CONTEXT) context = VOID_CONTEXT;
1839 comma_allowed = (context == VOID_CONTEXT);
1840 arrow_allowed = (context != ASSEMBLY_CONTEXT);
1841 bare_prop_allowed = (context == RETURN_Q_CONTEXT);
1842 array_init_ambiguity = ((context == ARRAY_CONTEXT) ||
1843 (context == ASSEMBLY_CONTEXT));
1845 action_ambiguity = (context == ACTION_Q_CONTEXT);
1847 if (context == ASSEMBLY_CONTEXT) context = QUANTITY_CONTEXT;
1848 if (context == ACTION_Q_CONTEXT) context = QUANTITY_CONTEXT;
1849 if (context == RETURN_Q_CONTEXT) context = QUANTITY_CONTEXT;
1850 if (context == ARRAY_CONTEXT) context = CONSTANT_CONTEXT;
1853 inserting_token = FALSE;
1858 previous_token.text = "$";
1859 previous_token.type = ENDEXP_TT;
1860 previous_token.value = 0;
1863 sr_stack[0] = previous_token;
1867 statements.enabled = FALSE;
1868 directives.enabled = FALSE;
1870 if (get_next_etoken() == FALSE)
1871 { ebf_error("expression", token_text);
1876 { if (expr_trace_level >= 2)
1877 { printf("Input: %-20s", current_token.text);
1878 for (i=0; i<sr_sp; i++) printf("%s ", sr_stack[i].text);
1881 if (expr_trace_level >= 3) printf("ET_used = %d\n", ET_used);
1884 { compiler_error("SR error: stack empty");
1888 a = sr_stack[sr_sp-1]; b = current_token;
1890 if ((a.type == ENDEXP_TT) && (b.type == ENDEXP_TT))
1891 { if (emitter_sp == 0)
1892 { error("No expression between brackets '(' and ')'");
1897 { compiler_error("SR error: emitter stack overfull");
1901 AO = emitter_stack[0];
1902 if (AO.type == EXPRESSION_OT)
1903 { if (expr_trace_level >= 3)
1904 { printf("Tree before lvalue checking:\n");
1905 show_tree(AO, FALSE);
1908 check_property_operator(AO.value);
1909 check_lvalues(AO.value);
1910 ET[AO.value].up = -1;
1913 if ((context != CONSTANT_CONTEXT) && is_property_t(AO.symtype)
1914 && (arrow_allowed) && (!bare_prop_allowed))
1915 warning("Bare property name found. \"self.prop\" intended?");
1918 check_conditions(AO, context);
1920 if (context == CONSTANT_CONTEXT)
1921 if (!is_constant_ot(AO.type))
1922 { AO = zero_operand;
1923 ebf_error("constant", "<expression>");
1930 switch(find_prec(a,b))
1932 case e5: /* Associativity error */
1933 error_named("Brackets mandatory to clarify order of:",
1938 if (sr_sp == MAX_EXPRESSION_NODES)
1939 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1940 sr_stack[sr_sp++] = b;
1944 if (sr_sp >= 2 && sr_stack[sr_sp-2].type == OP_TT && sr_stack[sr_sp-2].value == FCALL_OP)
1945 mark_top_of_emitter_stack(FUNCTION_VALUE_MARKER, b);
1947 add_bracket_layer_to_emitter_stack(0);
1952 if (sr_stack[sr_sp-2].type == OP_TT &&
1953 operators[sr_stack[sr_sp-2].value].precedence == 3)
1954 mark_top_of_emitter_stack(OR_VALUE_MARKER, b);
1956 { error("'or' not between values to the right of a condition");
1957 /* Convert to + for error recovery purposes */
1958 sr_stack[sr_sp-1].value = PLUS_OP;
1963 /* A comma separates arguments only if the shallowest open bracket belongs to a function call. */
1964 int shallowest_open_bracket_index = sr_sp - 2;
1965 while (shallowest_open_bracket_index > 0 && sr_stack[shallowest_open_bracket_index].type != SUBOPEN_TT)
1966 --shallowest_open_bracket_index;
1967 if (shallowest_open_bracket_index > 0 &&
1968 sr_stack[shallowest_open_bracket_index-1].type == OP_TT &&
1969 sr_stack[shallowest_open_bracket_index-1].value == FCALL_OP)
1970 { mark_top_of_emitter_stack(ARGUMENT_VALUE_MARKER, b);
1973 /* Non-argument-separating commas get treated like any other operator; we fall through to the default case. */
1977 /* Add a marker for the brackets implied by operator precedence */
1978 int operands_on_left = (operators[b.value].usage == PRE_U) ? 0 : 1;
1979 add_bracket_layer_to_emitter_stack(operands_on_left);
1987 { pop = sr_stack[sr_sp - 1];
1990 } while (find_prec(sr_stack[sr_sp-1], pop) != LOWER_P);
1993 case e1: /* Missing operand error */
1994 error_named("Missing operand after", a.text);
1996 current_token.type = NUMBER_TT;
1997 current_token.value = 0;
1998 current_token.marker = 0;
1999 current_token.text = "0";
2002 case e2: /* Unexpected close bracket */
2003 error("Found '(' without matching ')'");
2007 case e3: /* Missing operator error */
2008 error("Missing operator: inserting '+'");
2010 current_token.type = OP_TT;
2011 current_token.value = PLUS_OP;
2012 current_token.marker = 0;
2013 current_token.text = "+";
2016 case e4: /* Expression ends with an open bracket */
2017 error("Found '(' without matching ')'");
2026 /* --- Test for simple ++ or -- usage: used to optimise "for" loop code ---- */
2028 extern int test_for_incdec(assembly_operand AO)
2030 if (AO.type != EXPRESSION_OT) return 0;
2031 if (ET[AO.value].down == -1) return 0;
2032 switch(ET[AO.value].operator_number)
2033 { case INC_OP: s = 1; break;
2034 case POST_INC_OP: s = 1; break;
2035 case DEC_OP: s = -1; break;
2036 case POST_DEC_OP: s = -1; break;
2039 if (ET[ET[AO.value].down].down != -1) return 0;
2040 if (!is_variable_ot(ET[ET[AO.value].down].value.type)) return 0;
2041 return s*(ET[ET[AO.value].down].value.value);
2044 /* ========================================================================= */
2045 /* Data structure management routines */
2046 /* ------------------------------------------------------------------------- */
2048 extern void init_expressp_vars(void)
2050 /* make_operands(); */
2051 make_lexical_interface_tables();
2052 for (i=0;i<32;i++) system_function_usage[i] = 0;
2055 extern void expressp_begin_pass(void)
2059 extern void expressp_allocate_arrays(void)
2060 { ET = my_calloc(sizeof(expression_tree_node), MAX_EXPRESSION_NODES,
2061 "expression parse trees");
2062 emitter_markers = my_calloc(sizeof(int), MAX_EXPRESSION_NODES,
2064 emitter_bracket_counts = my_calloc(sizeof(int), MAX_EXPRESSION_NODES,
2065 "emitter bracket layer counts");
2066 emitter_stack = my_calloc(sizeof(assembly_operand), MAX_EXPRESSION_NODES,
2068 sr_stack = my_calloc(sizeof(token_data), MAX_EXPRESSION_NODES,
2069 "shift-reduce parser stack");
2072 extern void expressp_free_arrays(void)
2073 { my_free(&ET, "expression parse trees");
2074 my_free(&emitter_markers, "emitter markers");
2075 my_free(&emitter_bracket_counts, "emitter bracket layer counts");
2076 my_free(&emitter_stack, "emitter stack");
2077 my_free(&sr_stack, "shift-reduce parser stack");
2080 /* ========================================================================= */