1 /* ------------------------------------------------------------------------- */
2 /* "expressp" : The expression parser */
4 /* Copyright (c) Graham Nelson 1993 - 2016 */
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 current_token.marker = IROUTINE_MV;
147 case GLOBAL_VARIABLE_T:
148 current_token.marker = VARIABLE_MV;
152 /* All objects must be backpatched in Glulx. */
153 if (module_switch || glulx_mode)
154 current_token.marker = OBJECT_MV;
157 current_token.marker = ARRAY_MV;
159 case INDIVIDUAL_PROPERTY_T:
160 if (module_switch) current_token.marker = IDENT_MV;
163 if (sflags[symbol] & (UNKNOWN_SFLAG + CHANGE_SFLAG))
164 { current_token.marker = SYMBOL_MV;
165 if (module_switch) import_symbol(symbol);
168 else current_token.marker = 0;
171 error_named("Label name used as value:", token_text);
174 current_token.marker = 0;
177 if (sflags[symbol] & SYSTEM_SFLAG)
178 current_token.marker = 0;
180 current_token.value = v;
183 if (((current_token.marker != 0)
184 && (current_token.marker != VARIABLE_MV))
185 || (v < 0) || (v > 255))
186 current_token.type = LARGE_NUMBER_TT;
187 else current_token.type = SMALL_NUMBER_TT;
190 if (((current_token.marker != 0)
191 && (current_token.marker != VARIABLE_MV))
192 || (v < -0x8000) || (v >= 0x8000))
193 current_token.type = LARGE_NUMBER_TT;
194 else current_token.type = SMALL_NUMBER_TT;
197 if (stypes[symbol] == GLOBAL_VARIABLE_T)
198 { current_token.type = VARIABLE_TT;
199 variable_usage[current_token.value] = TRUE;
205 if (current_token.value >= 256)
206 current_token.type = LARGE_NUMBER_TT;
208 current_token.type = SMALL_NUMBER_TT;
211 if (current_token.value < -0x8000
212 || current_token.value >= 0x8000)
213 current_token.type = LARGE_NUMBER_TT;
215 current_token.type = SMALL_NUMBER_TT;
220 switch(current_token.value)
223 current_token.type = ENDEXP_TT;
227 if ((bracket_level==0) && (!comma_allowed))
228 current_token.type = ENDEXP_TT;
232 if ((bracket_level==0) && (!superclass_allowed))
233 current_token.type = ENDEXP_TT;
238 if ((token_type == SEP_TT)
239 &&((token_value == SEMICOLON_SEP)
240 || (token_value == GREATER_SEP)))
241 current_token.type = ENDEXP_TT;
247 if (expr_trace_level>=3)
248 { printf("Previous token type = %d\n",previous_token.type);
249 printf("Previous token val = %d\n",previous_token.value);
251 if ((previous_token.type == OP_TT)
252 || (previous_token.type == SUBOPEN_TT)
253 || (previous_token.type == ENDEXP_TT)
254 || (array_init_ambiguity)
255 || ((bracket_level == 1) && (action_ambiguity)))
256 current_token.type = SUBOPEN_TT;
258 { inserting_token = TRUE;
259 heldback_token = current_token;
260 current_token.text = "<call>";
267 if (bracket_level < 0)
268 current_token.type = ENDEXP_TT;
269 else current_token.type = SUBCLOSE_TT;
273 current_token.type = ENDEXP_TT; break;
276 if ((previous_token.type == OP_TT)
277 || (previous_token.type == SUBOPEN_TT)
278 || (previous_token.type == ENDEXP_TT))
279 current_token.value = UNARY_MINUS_SEP; break;
282 if ((previous_token.type == VARIABLE_TT)
283 || (previous_token.type == SUBCLOSE_TT)
284 || (previous_token.type == LARGE_NUMBER_TT)
285 || (previous_token.type == SMALL_NUMBER_TT))
286 current_token.value = POST_INC_SEP; break;
289 if ((previous_token.type == VARIABLE_TT)
290 || (previous_token.type == SUBCLOSE_TT)
291 || (previous_token.type == LARGE_NUMBER_TT)
292 || (previous_token.type == SMALL_NUMBER_TT))
293 current_token.value = POST_DEC_SEP; break;
296 token_text = current_token.text + 2;
298 ActionUsedAsConstant:
300 current_token.type = ACTION_TT;
301 current_token.text = token_text;
302 current_token.value = 0;
303 current_token.marker = ACTION_MV;
307 case HASHADOLLAR_SEP:
308 obsolete_warning("'#a$Act' is now superseded by '##Act'");
309 token_text = current_token.text + 3;
310 goto ActionUsedAsConstant;
312 case HASHGDOLLAR_SEP:
314 /* This form generates the position of a global variable
315 in the global variables array. So Glob is the same as
316 #globals_array --> #g$Glob */
318 current_token.text += 3;
319 current_token.type = SYMBOL_TT;
320 symbol = symbol_index(current_token.text, -1);
321 if (stypes[symbol] != GLOBAL_VARIABLE_T) {
323 "global variable name after '#g$'",
325 current_token.value = 0;
326 current_token.type = SMALL_NUMBER_TT;
327 current_token.marker = 0;
330 mark_symbol_as_used = TRUE;
331 current_token.value = svals[symbol] - MAX_LOCAL_VARIABLES;
332 current_token.marker = 0;
334 if (current_token.value >= 0x100)
335 current_token.type = LARGE_NUMBER_TT;
336 else current_token.type = SMALL_NUMBER_TT;
339 if (current_token.value >= 0x8000
340 || current_token.value < -0x8000)
341 current_token.type = LARGE_NUMBER_TT;
342 else current_token.type = SMALL_NUMBER_TT;
346 case HASHNDOLLAR_SEP:
348 /* This form is still needed for constants like #n$a (the
349 dictionary address of the word "a"), since 'a' means
350 the ASCII value of 'a' */
352 if (strlen(token_text) > 4)
354 "'#n$word' is now superseded by ''word''");
355 current_token.type = DICTWORD_TT;
356 current_token.value = 0;
357 current_token.text = token_text + 3;
358 current_token.marker = DWORD_MV;
361 case HASHRDOLLAR_SEP:
363 /* This form -- #r$Routinename, to return the routine's */
364 /* packed address -- is needed far less often in Inform 6, */
365 /* where just giving the name Routine returns the packed */
366 /* address. But it's used in a lot of Inform 5 code. */
369 "'#r$Routine' can now be written just 'Routine'");
370 current_token.text += 3;
371 current_token.type = SYMBOL_TT;
372 current_token.value = symbol_index(current_token.text, -1);
375 case HASHWDOLLAR_SEP:
376 error("The obsolete '#w$word' construct has been removed");
380 system_constants.enabled = TRUE;
382 system_constants.enabled = FALSE;
383 if (token_type != SYSTEM_CONSTANT_TT)
385 "'r$', 'n$', 'g$' or internal Inform constant name after '#'",
390 { current_token.type = token_type;
391 current_token.value = token_value;
392 current_token.text = token_text;
393 current_token.marker = INCON_MV;
400 v = conditionals_to_operators[current_token.value];
401 if (v != NOT_AN_OPERATOR)
402 { current_token.type = OP_TT; current_token.value = v;
407 if (current_token.type == SEP_TT)
408 { v = separators_to_operators[current_token.value];
409 if (v != NOT_AN_OPERATOR)
411 || ((v!=MESSAGE_OP) && (v!=MPROP_NUM_OP) && (v!=MPROP_NUM_OP)))
412 { current_token.type = OP_TT; current_token.value = v;
413 if (array_init_ambiguity &&
414 ((v==MINUS_OP) || (v==UNARY_MINUS_OP)) &&
415 (initial_bracket_level == 0) &&
417 warning("Without bracketing, the minus sign '-' is ambiguous");
422 /* A feature of Inform making it annoyingly hard to parse left-to-right
423 is that there is no clear delimiter for expressions; that is, the
424 legal syntax often includes sequences of expressions with no
425 intervening markers such as commas. We therefore need to use some
426 internal context to determine whether an end is in sight... */
428 if (token_type_allowable[current_token.type]==0)
429 { if (expr_trace_level >= 3)
430 { printf("Discarding as not allowable: '%s' ", current_token.text);
431 describe_token(current_token);
434 current_token.type = ENDEXP_TT;
437 if ((!((initial_bracket_level > 0)
438 || (previous_token.type == ENDEXP_TT)
439 || ((previous_token.type == OP_TT)
440 && (operators[previous_token.value].usage != POST_U))
441 || (previous_token.type == SYSFUN_TT)))
442 && ((current_token.type != OP_TT)
443 || (operators[current_token.value].usage == PRE_U)))
444 { if (expr_trace_level >= 3)
445 { printf("Discarding as no longer part: '%s' ", current_token.text);
446 describe_token(current_token);
449 current_token.type = ENDEXP_TT;
452 { if (mark_symbol_as_used) sflags[symbol] |= USED_SFLAG;
453 if (expr_trace_level >= 3)
454 { printf("Expr token = '%s' ", current_token.text);
455 describe_token(current_token);
460 if ((previous_token.type == ENDEXP_TT)
461 && (current_token.type == ENDEXP_TT)) return FALSE;
463 previous_token = current_token;
468 /* --- Operator precedences ------------------------------------------------ */
472 #define GREATER_P 103
474 #define e1 1 /* Missing operand error */
475 #define e2 2 /* Unexpected close bracket */
476 #define e3 3 /* Missing operator error */
477 #define e4 4 /* Expression ends with an open bracket */
478 #define e5 5 /* Associativity illegal error */
480 const int prec_table[] = {
482 /* a .......... ( ) end op term */
484 /* b ( */ LOWER_P, e3, LOWER_P, LOWER_P, e3,
485 /* . ) */ EQUAL_P, GREATER_P, e2, GREATER_P, GREATER_P,
486 /* . end */ e4, GREATER_P, e1, GREATER_P, GREATER_P,
487 /* . op */ LOWER_P, GREATER_P, LOWER_P, -1, GREATER_P,
488 /* . term */ LOWER_P, e3, LOWER_P, LOWER_P, e3
492 static int find_prec(token_data a, token_data b)
494 /* We are comparing the precedence of tokens a and b
495 (where a occurs to the left of b). If the expression is correct,
496 the only possible values are GREATER_P, LOWER_P or EQUAL_P;
497 if it is malformed then one of e1 to e5 results.
499 Note that this routine is not symmetrical and that the relation
502 If a and b are equal (and aren't brackets), then
504 a LOWER_P a if a right-associative
505 a GREATER_P a if a left-associative
511 { case SUBOPEN_TT: i=0; break;
512 case SUBCLOSE_TT: i=1; break;
513 case ENDEXP_TT: i=2; break;
514 case OP_TT: i=3; break;
518 { case SUBOPEN_TT: i+=0; break;
519 case SUBCLOSE_TT: i+=5; break;
520 case ENDEXP_TT: i+=10; break;
521 case OP_TT: i+=15; break;
522 default: i+=20; break;
525 j = prec_table[i]; if (j != -1) return j;
527 l1 = operators[a.value].precedence;
528 l2 = operators[b.value].precedence;
529 if (operators[b.value].usage == PRE_U) return LOWER_P;
530 if (operators[a.value].usage == POST_U) return GREATER_P;
532 /* Anomalous rule to resolve the function call precedence, which is
533 different on the right from on the left, e.g., in:
539 if ((l1 == 11) && (l2 > 11)) return GREATER_P;
541 if (l1 < l2) return LOWER_P;
542 if (l1 > l2) return GREATER_P;
543 switch(operators[a.value].associativity)
544 { case L_A: return GREATER_P;
545 case R_A: return LOWER_P;
551 /* --- Converting token to operand ----------------------------------------- */
553 /* Must match the switch statement below */
554 int z_system_constant_list[] =
555 { adjectives_table_SC,
558 identifiers_table_SC,
563 actual_largest_object_SC,
564 static_memory_offset_SC,
565 array_names_offset_SC,
566 readable_memory_offset_SC,
573 highest_attribute_number_SC,
574 attribute_names_array_SC,
575 highest_property_number_SC,
576 property_names_array_SC,
577 highest_action_number_SC,
578 action_names_array_SC,
579 highest_fake_action_number_SC,
580 fake_action_names_array_SC,
581 highest_routine_number_SC,
582 routine_names_array_SC,
584 routine_flags_array_SC,
585 highest_global_number_SC,
586 global_names_array_SC,
588 global_flags_array_SC,
589 highest_array_number_SC,
590 array_names_array_SC,
591 array_flags_array_SC,
592 highest_constant_number_SC,
593 constant_names_array_SC,
594 highest_class_number_SC,
595 class_objects_array_SC,
596 highest_object_number_SC,
599 static int32 value_of_system_constant_z(int t)
601 { case adjectives_table_SC:
602 return adjectives_offset;
603 case actions_table_SC:
604 return actions_offset;
605 case classes_table_SC:
606 return class_numbers_offset;
607 case identifiers_table_SC:
608 return identifier_names_offset;
609 case preactions_table_SC:
610 return preactions_offset;
611 case largest_object_SC:
612 return 256 + no_objects - 1;
613 case strings_offset_SC:
614 return strings_offset/scale_factor;
616 return code_offset/scale_factor;
617 case actual_largest_object_SC:
619 case static_memory_offset_SC:
620 return static_memory_offset;
621 case array_names_offset_SC:
622 return array_names_offset;
623 case readable_memory_offset_SC:
624 return Write_Code_At;
626 return prop_values_offset;
628 return class_numbers_offset;
630 return individuals_offset;
632 return variables_offset;
633 case array__start_SC:
634 return variables_offset + (MAX_GLOBAL_VARIABLES*WORDSIZE);
636 return static_memory_offset;
638 case highest_attribute_number_SC:
639 return no_attributes-1;
640 case attribute_names_array_SC:
641 return attribute_names_offset;
643 case highest_property_number_SC:
644 return no_individual_properties-1;
645 case property_names_array_SC:
646 return identifier_names_offset + 2;
648 case highest_action_number_SC:
650 case action_names_array_SC:
651 return action_names_offset;
653 case highest_fake_action_number_SC:
654 return ((grammar_version_number==1)?256:4096) + no_fake_actions-1;
655 case fake_action_names_array_SC:
656 return fake_action_names_offset;
658 case highest_routine_number_SC:
659 return no_named_routines-1;
660 case routine_names_array_SC:
661 return routine_names_offset;
662 case routines_array_SC:
663 return routines_array_offset;
664 case routine_flags_array_SC:
665 return routine_flags_array_offset;
666 case highest_global_number_SC:
667 return 16 + no_globals-1;
668 case global_names_array_SC:
669 return global_names_offset;
670 case globals_array_SC:
671 return variables_offset;
672 case global_flags_array_SC:
673 return global_flags_array_offset;
674 case highest_array_number_SC:
676 case array_names_array_SC:
677 return array_names_offset;
678 case array_flags_array_SC:
679 return array_flags_array_offset;
680 case highest_constant_number_SC:
681 return no_named_constants-1;
682 case constant_names_array_SC:
683 return constant_names_offset;
684 case highest_class_number_SC:
686 case class_objects_array_SC:
687 return class_numbers_offset;
688 case highest_object_number_SC:
692 error_named("System constant not implemented in Z-code",
693 system_constants.keywords[t]);
698 /* Must match the switch statement below */
699 int glulx_system_constant_list[] =
701 identifiers_table_SC,
702 array_names_offset_SC,
706 dynam_string_table_SC,
710 highest_class_number_SC,
711 highest_object_number_SC,
714 static int32 value_of_system_constant_g(int t)
717 case classes_table_SC:
718 return Write_RAM_At + class_numbers_offset;
719 case identifiers_table_SC:
720 return Write_RAM_At + identifier_names_offset;
721 case array_names_offset_SC:
722 return Write_RAM_At + array_names_offset;
724 return prop_defaults_offset;
726 return Write_RAM_At + class_numbers_offset;
727 case dictionary_table_SC:
728 return dictionary_offset;
729 case dynam_string_table_SC:
730 return abbreviations_offset;
731 case grammar_table_SC:
732 return grammar_table_offset;
733 case actions_table_SC:
734 return actions_offset;
735 case globals_array_SC:
736 return variables_offset;
737 case highest_class_number_SC:
739 case highest_object_number_SC:
743 error_named("System constant not implemented in Glulx",
744 system_constants.keywords[t]);
749 extern int32 value_of_system_constant(int t)
752 return value_of_system_constant_z(t);
754 return value_of_system_constant_g(t);
757 static int evaluate_term(token_data t, assembly_operand *o)
759 /* If the given token is a constant, evaluate it into the operand.
760 For now, the identifiers are considered variables.
762 Returns FALSE if it fails to understand type. */
766 o->marker = t.marker;
767 o->symtype = t.symtype;
768 o->symflags = t.symflags;
771 { case LARGE_NUMBER_TT:
774 if (v < 0) v = v + 0x10000;
775 o->type = LONG_CONSTANT_OT;
780 o->type = CONSTANT_OT;
783 case SMALL_NUMBER_TT:
786 if (v < 0) v = v + 0x10000;
787 o->type = SHORT_CONSTANT_OT;
796 /* Find the dictionary address, adding to dictionary if absent */
798 o->type = LONG_CONSTANT_OT;
800 o->type = CONSTANT_OT;
801 o->value = dictionary_add(t.text, 0x80, 0, 0);
804 /* Create as a static string */
806 o->type = LONG_CONSTANT_OT;
808 o->type = CONSTANT_OT;
809 o->value = compile_string(t.text, FALSE, FALSE);
813 o->type = VARIABLE_OT;
816 if (t.value >= MAX_LOCAL_VARIABLES) {
817 o->type = GLOBALVAR_OT;
820 /* This includes "local variable zero", which is really
821 the stack-pointer magic variable. */
822 o->type = LOCALVAR_OT;
829 o->type = VARIABLE_OT;
830 o->value = t.value + 256;
836 system_function_usage[t.value] = 1;
839 *o = action_of_name(t.text);
841 case SYSTEM_CONSTANT_TT:
842 /* Certain system constants depend only on the
843 version number and need no backpatching, as they
844 are known in advance. We can therefore evaluate
847 o->type = LONG_CONSTANT_OT;
850 case version_number_SC:
851 o->type = SHORT_CONSTANT_OT;
853 v = version_number; break;
855 o->type = SHORT_CONSTANT_OT;
857 v = (version_number==3)?4:6; break;
859 o->type = SHORT_CONSTANT_OT;
861 v = (version_number==3)?5:7; break;
863 o->type = SHORT_CONSTANT_OT;
865 v = (version_number==3)?6:8; break;
866 case lowest_attribute_number_SC:
867 case lowest_action_number_SC:
868 case lowest_routine_number_SC:
869 case lowest_array_number_SC:
870 case lowest_constant_number_SC:
871 case lowest_class_number_SC:
872 o->type = SHORT_CONSTANT_OT; o->marker = 0; v = 0; break;
873 case lowest_object_number_SC:
874 case lowest_property_number_SC:
875 o->type = SHORT_CONSTANT_OT; o->marker = 0; v = 1; break;
876 case lowest_global_number_SC:
877 o->type = SHORT_CONSTANT_OT; o->marker = 0; v = 16; break;
878 case lowest_fake_action_number_SC:
879 o->type = LONG_CONSTANT_OT; o->marker = 0;
880 v = ((grammar_version_number==1)?256:4096); break;
881 case oddeven_packing_SC:
882 o->type = SHORT_CONSTANT_OT; o->marker = 0;
883 v = oddeven_packing_switch; break;
886 o->marker = INCON_MV;
892 o->type = CONSTANT_OT;
895 /* The three dict_par flags point at the lower byte
896 of the flag field, because the library is written
897 to expect one-byte fields, even though the compiler
898 generates a dictionary with room for two. */
900 o->type = BYTECONSTANT_OT;
902 v = DICT_ENTRY_FLAG_POS+1;
905 o->type = BYTECONSTANT_OT;
907 v = DICT_ENTRY_FLAG_POS+3;
910 o->type = BYTECONSTANT_OT;
912 v = DICT_ENTRY_FLAG_POS+5;
915 case lowest_attribute_number_SC:
916 case lowest_action_number_SC:
917 case lowest_routine_number_SC:
918 case lowest_array_number_SC:
919 case lowest_constant_number_SC:
920 case lowest_class_number_SC:
921 o->type = BYTECONSTANT_OT;
925 case lowest_object_number_SC:
926 case lowest_property_number_SC:
927 o->type = BYTECONSTANT_OT;
932 /* ###fix: need to fill more of these in! */
936 o->marker = INCON_MV;
947 /* --- Emitter ------------------------------------------------------------- */
949 expression_tree_node *ET;
952 extern void clear_expression_space(void)
956 static assembly_operand *emitter_stack;
957 static int *emitter_markers;
958 static int *emitter_bracket_counts;
960 #define FUNCTION_VALUE_MARKER 1
961 #define ARGUMENT_VALUE_MARKER 2
962 #define OR_VALUE_MARKER 3
964 static int emitter_sp;
966 static int is_property_t(int symbol_type)
967 { return ((symbol_type == PROPERTY_T) || (symbol_type == INDIVIDUAL_PROPERTY_T));
970 static void mark_top_of_emitter_stack(int marker, token_data t)
971 { if (emitter_sp < 1)
972 { compiler_error("SR error: Attempt to add a marker to the top of an empty emitter stack");
975 if (expr_trace_level >= 2)
976 { printf("Marking top of emitter stack (which is ");
977 print_operand(emitter_stack[emitter_sp-1]);
981 case FUNCTION_VALUE_MARKER:
984 case ARGUMENT_VALUE_MARKER:
987 case OR_VALUE_MARKER:
996 if (emitter_markers[emitter_sp-1])
997 { if (marker == ARGUMENT_VALUE_MARKER)
999 warning("Ignoring spurious leading comma");
1002 error_named("Missing operand for", t.text);
1003 if (emitter_sp == MAX_EXPRESSION_NODES)
1004 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1005 emitter_markers[emitter_sp] = 0;
1006 emitter_bracket_counts[emitter_sp] = 0;
1007 emitter_stack[emitter_sp] = zero_operand;
1010 emitter_markers[emitter_sp-1] = marker;
1013 static void add_bracket_layer_to_emitter_stack(int depth)
1014 { /* There's no point in tracking bracket layers that don't fence off any values. */
1015 if (emitter_sp < depth + 1) return;
1016 if (expr_trace_level >= 2)
1017 printf("Adding bracket layer\n");
1018 ++emitter_bracket_counts[emitter_sp-depth-1];
1021 static void remove_bracket_layer_from_emitter_stack()
1022 { /* Bracket layers that don't fence off any values will not have been tracked. */
1023 if (emitter_sp < 2) return;
1024 if (expr_trace_level >= 2)
1025 printf("Removing bracket layer\n");
1026 if (emitter_bracket_counts[emitter_sp-2] <= 0)
1027 { compiler_error("SR error: Attempt to remove a nonexistent bracket layer from the emitter stack");
1030 --emitter_bracket_counts[emitter_sp-2];
1033 static void emit_token(token_data t)
1034 { assembly_operand o1, o2; int arity, stack_size, i;
1035 int op_node_number, operand_node_number, previous_node_number;
1038 if (expr_trace_level >= 2)
1039 { printf("Output: %-19s%21s ", t.text, "");
1040 for (i=0; i<emitter_sp; i++)
1041 { print_operand(emitter_stack[i]); printf(" ");
1042 if (emitter_markers[i] == FUNCTION_VALUE_MARKER) printf(":FUNCTION ");
1043 if (emitter_markers[i] == ARGUMENT_VALUE_MARKER) printf(":ARGUMENT ");
1044 if (emitter_markers[i] == OR_VALUE_MARKER) printf(":OR ");
1045 if (emitter_bracket_counts[i]) printf(":BRACKETS(%d) ", emitter_bracket_counts[i]);
1050 if (t.type == SUBOPEN_TT) return;
1053 while ((stack_size < emitter_sp) &&
1054 !emitter_markers[emitter_sp-stack_size-1] &&
1055 !emitter_bracket_counts[emitter_sp-stack_size-1])
1058 if (t.type == SUBCLOSE_TT)
1059 { if (stack_size < emitter_sp && emitter_bracket_counts[emitter_sp-stack_size-1])
1060 { if (stack_size == 0)
1061 { error("No expression between brackets '(' and ')'");
1062 emitter_stack[emitter_sp] = zero_operand;
1063 emitter_markers[emitter_sp] = 0;
1064 emitter_bracket_counts[emitter_sp] = 0;
1067 else if (stack_size < 1)
1068 compiler_error("SR error: emitter stack empty in subexpression");
1069 else if (stack_size > 1)
1070 compiler_error("SR error: emitter stack overfull in subexpression");
1071 remove_bracket_layer_from_emitter_stack();
1076 if (t.type != OP_TT)
1077 { emitter_markers[emitter_sp] = 0;
1078 emitter_bracket_counts[emitter_sp] = 0;
1080 if (emitter_sp == MAX_EXPRESSION_NODES)
1081 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1082 if (!evaluate_term(t, &(emitter_stack[emitter_sp++])))
1083 compiler_error_named("Emit token error:", t.text);
1087 /* A comma is argument-separating if it follows an argument (or a function
1088 call, since we ignore spurious leading commas in function argument lists)
1089 with no intervening brackets. Function calls are variadic, so we don't
1090 apply argument-separating commas. */
1091 if (t.value == COMMA_OP &&
1092 stack_size < emitter_sp &&
1093 (emitter_markers[emitter_sp-stack_size-1] == ARGUMENT_VALUE_MARKER ||
1094 emitter_markers[emitter_sp-stack_size-1] == FUNCTION_VALUE_MARKER) &&
1095 !emitter_bracket_counts[emitter_sp-stack_size-1])
1096 { if (expr_trace_level >= 2)
1097 printf("Treating comma as argument-separating\n");
1101 if (t.value == OR_OP)
1105 if (t.value == FCALL_OP)
1106 { if (expr_trace_level >= 3)
1107 { printf("FCALL_OP finds marker stack: ");
1108 for (x=0; x<emitter_sp; x++) printf("%d ", emitter_markers[x]);
1111 if (emitter_markers[emitter_sp-1] == ARGUMENT_VALUE_MARKER)
1112 warning("Ignoring spurious trailing comma");
1113 while (emitter_markers[emitter_sp-arity] != FUNCTION_VALUE_MARKER)
1116 emitter_stack[emitter_sp-arity].type == SYSFUN_OT) ||
1118 emitter_stack[emitter_sp-arity].type == VARIABLE_OT &&
1119 emitter_stack[emitter_sp-arity].value >= 256 &&
1120 emitter_stack[emitter_sp-arity].value < 288))
1121 { int index = emitter_stack[emitter_sp-arity].value;
1124 if(index >= 0 && index < NUMBER_SYSTEM_FUNCTIONS)
1125 error_named("System function name used as a value:", system_functions.keywords[index]);
1127 compiler_error("Found unnamed system function used as a value");
1128 emitter_stack[emitter_sp-arity] = zero_operand;
1135 if (operators[t.value].usage == IN_U) arity = 2;
1137 if (operators[t.value].precedence == 3)
1140 if(!emitter_markers[x] && !emitter_bracket_counts[x])
1141 { for (--x; emitter_markers[x] == OR_VALUE_MARKER && !emitter_bracket_counts[x]; --x)
1145 for (;x >= 0 && !emitter_markers[x] && !emitter_bracket_counts[x]; --x)
1150 if (arity > stack_size)
1151 { error_named("Missing operand for", t.text);
1152 while (arity > stack_size)
1153 { if (emitter_sp == MAX_EXPRESSION_NODES)
1154 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1155 emitter_markers[emitter_sp] = 0;
1156 emitter_bracket_counts[emitter_sp] = 0;
1157 emitter_stack[emitter_sp] = zero_operand;
1164 /* pseudo-typecheck in 6.30 */
1165 for (i = 1; i <= arity; i++)
1167 o1 = emitter_stack[emitter_sp - i];
1168 if (is_property_t(o1.symtype) ) {
1172 case SETEQUALS_OP: case NOTEQUAL_OP:
1174 case PROVIDES_OP: case NOTPROVIDES_OP:
1175 case PROP_ADD_OP: case PROP_NUM_OP:
1177 case MPROP_ADD_OP: case MESSAGE_OP:
1179 if (i < arity) break;
1180 case GE_OP: case LE_OP:
1181 if ((i < arity) && (o1.symflags & STAR_SFLAG)) break;
1183 warning("Property name in expression is not qualified by object");
1185 } /* if (is_property_t */
1190 o1 = emitter_stack[emitter_sp - 1];
1191 if ((o1.marker == 0) && is_constant_ot(o1.type))
1193 { case UNARY_MINUS_OP: x = -o1.value; goto FoldConstant;
1196 x = (~o1.value) & 0xffff;
1198 x = (~o1.value) & 0xffffffff;
1201 if (o1.value != 0) x=0; else x=1;
1208 o1 = emitter_stack[emitter_sp - 2];
1209 o2 = emitter_stack[emitter_sp - 1];
1211 if ((o1.marker == 0) && (o2.marker == 0)
1212 && is_constant_ot(o1.type) && is_constant_ot(o2.type))
1220 { ov1 = (o1.value >= 0x8000) ? (o1.value - 0x10000) : o1.value;
1221 ov2 = (o2.value >= 0x8000) ? (o2.value - 0x10000) : o2.value;
1226 case PLUS_OP: x = ov1 + ov2; goto FoldConstantC;
1227 case MINUS_OP: x = ov1 - ov2; goto FoldConstantC;
1228 case TIMES_OP: x = ov1 * ov2; goto FoldConstantC;
1232 error("Division of constant by zero");
1234 if (t.value == DIVIDE_OP) {
1242 x = -((-ov1) / ov2);
1251 x = -((-ov1) % ov2);
1254 case ARTAND_OP: x = o1.value & o2.value; goto FoldConstant;
1255 case ARTOR_OP: x = o1.value | o2.value; goto FoldConstant;
1257 if (o1.value == o2.value) x = 1; else x = 0;
1260 if (o1.value != o2.value) x = 1; else x = 0;
1263 if (o1.value >= o2.value) x = 1; else x = 0;
1266 if (o1.value > o2.value) x = 1; else x = 0;
1269 if (o1.value <= o2.value) x = 1; else x = 0;
1272 if (o1.value < o2.value) x = 1; else x = 0;
1275 if ((o1.value != 0) && (o2.value != 0)) x=1; else x=0;
1278 if ((o1.value != 0) || (o2.value != 0)) x=1; else x=0;
1285 op_node_number = ET_used++;
1286 if (op_node_number == MAX_EXPRESSION_NODES)
1287 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1289 ET[op_node_number].operator_number = t.value;
1290 ET[op_node_number].up = -1;
1291 ET[op_node_number].down = -1;
1292 ET[op_node_number].right = -1;
1294 /* This statement is redundant, but prevents compilers from wrongly
1295 issuing a "used before it was assigned a value" error: */
1296 previous_node_number = 0;
1298 for (i = emitter_sp-arity; i != emitter_sp; i++)
1300 if (expr_trace_level >= 3)
1301 printf("i=%d, emitter_sp=%d, arity=%d, ETU=%d\n",
1302 i, emitter_sp, arity, ET_used);
1303 if (emitter_stack[i].type == EXPRESSION_OT)
1304 operand_node_number = emitter_stack[i].value;
1306 { operand_node_number = ET_used++;
1307 if (operand_node_number == MAX_EXPRESSION_NODES)
1308 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1309 ET[operand_node_number].down = -1;
1310 ET[operand_node_number].value = emitter_stack[i];
1312 ET[operand_node_number].up = op_node_number;
1313 ET[operand_node_number].right = -1;
1314 if (i == emitter_sp - arity)
1315 { ET[op_node_number].down = operand_node_number;
1318 { ET[previous_node_number].right = operand_node_number;
1320 previous_node_number = operand_node_number;
1323 emitter_sp = emitter_sp - arity + 1;
1325 emitter_stack[emitter_sp - 1].type = EXPRESSION_OT;
1326 emitter_stack[emitter_sp - 1].value = op_node_number;
1327 emitter_stack[emitter_sp - 1].marker = 0;
1328 emitter_markers[emitter_sp - 1] = 0;
1329 emitter_bracket_counts[emitter_sp - 1] = 0;
1330 /* Remove the marker for the brackets implied by operator precedence */
1331 remove_bracket_layer_from_emitter_stack();
1337 /* In Glulx, skip this test; we can't check out-of-range errors
1338 for 32-bit arithmetic. */
1340 if (!glulx_mode && ((x<-32768) || (x > 32767)))
1341 { char folding_error[40];
1342 int32 ov1 = (o1.value >= 0x8000) ? (o1.value - 0x10000) : o1.value;
1343 int32 ov2 = (o2.value >= 0x8000) ? (o2.value - 0x10000) : o2.value;
1347 sprintf(folding_error, "%d + %d = %d", ov1, ov2, x);
1350 sprintf(folding_error, "%d - %d = %d", ov1, ov2, x);
1353 sprintf(folding_error, "%d * %d = %d", ov1, ov2, x);
1356 error_named("Signed arithmetic on compile-time constants overflowed \
1357 the range -32768 to +32767:", folding_error);
1363 while (x < 0) x = x + 0x10000;
1370 emitter_sp = emitter_sp - arity + 1;
1374 emitter_stack[emitter_sp - 1].type = SHORT_CONSTANT_OT;
1375 else emitter_stack[emitter_sp - 1].type = LONG_CONSTANT_OT;
1379 emitter_stack[emitter_sp - 1].type = ZEROCONSTANT_OT;
1380 else if (x >= -128 && x <= 127)
1381 emitter_stack[emitter_sp - 1].type = BYTECONSTANT_OT;
1382 else if (x >= -32768 && x <= 32767)
1383 emitter_stack[emitter_sp - 1].type = HALFCONSTANT_OT;
1385 emitter_stack[emitter_sp - 1].type = CONSTANT_OT;
1388 emitter_stack[emitter_sp - 1].value = x;
1389 emitter_stack[emitter_sp - 1].marker = 0;
1390 emitter_markers[emitter_sp - 1] = 0;
1391 emitter_bracket_counts[emitter_sp - 1] = 0;
1393 if (expr_trace_level >= 2)
1394 { printf("Folding constant to: ");
1395 print_operand(emitter_stack[emitter_sp - 1]);
1399 /* Remove the marker for the brackets implied by operator precedence */
1400 remove_bracket_layer_from_emitter_stack();
1404 /* --- Pretty printing ----------------------------------------------------- */
1406 static void show_node(int n, int depth, int annotate)
1408 for (j=0; j<2*depth+2; j++) printf(" ");
1410 if (ET[n].down == -1)
1411 { print_operand(ET[n].value);
1412 if (annotate && (ET[n].value.marker != 0))
1413 printf(" [%s]", describe_mv(ET[n].value.marker));
1417 { printf("%s ", operators[ET[n].operator_number].description);
1418 j = operators[ET[n].operator_number].precedence;
1419 if ((annotate) && ((j==2) || (j==3)))
1420 { printf(" %d|%d ", ET[n].true_label, ET[n].false_label);
1421 if (ET[n].label_after != -1) printf(" def %d after ",
1423 if (ET[n].to_expression) printf(" con to expr ");
1426 show_node(ET[n].down, depth+1, annotate);
1429 if (ET[n].right != -1) show_node(ET[n].right, depth, annotate);
1432 extern void show_tree(assembly_operand AO, int annotate)
1433 { if (AO.type == EXPRESSION_OT) show_node(AO.value, 0, annotate);
1435 { printf("Constant: "); print_operand(AO);
1436 if (annotate && (AO.marker != 0))
1437 printf(" [%s]", describe_mv(AO.marker));
1442 /* --- Lvalue transformations ---------------------------------------------- */
1444 /* This only gets called in Z-code, since Glulx doesn't distinguish
1445 individual property operators from general ones. */
1446 static void check_property_operator(int from_node)
1447 { int below = ET[from_node].down;
1448 int opnum = ET[from_node].operator_number;
1452 if (veneer_mode) return;
1454 if ((below != -1) && (ET[below].right != -1))
1455 { int n = ET[below].right, flag = FALSE;
1457 if ((ET[n].down == -1)
1458 && ((ET[n].value.type == LONG_CONSTANT_OT)
1459 || (ET[n].value.type == SHORT_CONSTANT_OT))
1460 && ((ET[n].value.value > 0) && (ET[n].value.value < 64))
1461 && ((!module_switch) || (ET[n].value.marker == 0)))
1466 { case PROPERTY_OP: opnum = MESSAGE_OP; break;
1467 case PROP_ADD_OP: opnum = MPROP_ADD_OP; break;
1468 case PROP_NUM_OP: opnum = MPROP_NUM_OP; break;
1472 ET[from_node].operator_number = opnum;
1476 check_property_operator(below);
1477 if (ET[from_node].right != -1)
1478 check_property_operator(ET[from_node].right);
1481 static void check_lvalues(int from_node)
1482 { int below = ET[from_node].down;
1483 int opnum = ET[from_node].operator_number, opnum_below;
1484 int lvalue_form, i, j = 0;
1488 if ((opnum == FCALL_OP) && (ET[below].down != -1))
1489 { opnum_below = ET[below].operator_number;
1490 if ((opnum_below == PROPERTY_OP) || (opnum_below == MESSAGE_OP))
1491 { i = ET[ET[from_node].down].right;
1492 ET[from_node].down = ET[below].down;
1493 ET[ET[below].down].up = from_node;
1494 ET[ET[ET[below].down].right].up = from_node;
1495 ET[ET[ET[below].down].right].right = i;
1496 opnum = PROP_CALL_OP;
1497 ET[from_node].operator_number = opnum;
1501 if (operators[opnum].requires_lvalue)
1502 { opnum_below = ET[below].operator_number;
1504 if (ET[below].down == -1)
1505 { if (!is_variable_ot(ET[below].value.type))
1506 { error("'=' applied to undeclared variable");
1513 { case SETEQUALS_OP:
1515 { case ARROW_OP: lvalue_form = ARROW_SETEQUALS_OP; break;
1516 case DARROW_OP: lvalue_form = DARROW_SETEQUALS_OP; break;
1517 case MESSAGE_OP: lvalue_form = MESSAGE_SETEQUALS_OP; break;
1518 case PROPERTY_OP: lvalue_form = PROPERTY_SETEQUALS_OP; break;
1523 { case ARROW_OP: lvalue_form = ARROW_INC_OP; break;
1524 case DARROW_OP: lvalue_form = DARROW_INC_OP; break;
1525 case MESSAGE_OP: lvalue_form = MESSAGE_INC_OP; break;
1526 case PROPERTY_OP: lvalue_form = PROPERTY_INC_OP; break;
1531 { case ARROW_OP: lvalue_form = ARROW_POST_INC_OP; break;
1532 case DARROW_OP: lvalue_form = DARROW_POST_INC_OP; break;
1533 case MESSAGE_OP: lvalue_form = MESSAGE_POST_INC_OP; break;
1534 case PROPERTY_OP: lvalue_form = PROPERTY_POST_INC_OP; break;
1539 { case ARROW_OP: lvalue_form = ARROW_DEC_OP; break;
1540 case DARROW_OP: lvalue_form = DARROW_DEC_OP; break;
1541 case MESSAGE_OP: lvalue_form = MESSAGE_DEC_OP; break;
1542 case PROPERTY_OP: lvalue_form = PROPERTY_DEC_OP; break;
1547 { case ARROW_OP: lvalue_form = ARROW_POST_DEC_OP; break;
1548 case DARROW_OP: lvalue_form = DARROW_POST_DEC_OP; break;
1549 case MESSAGE_OP: lvalue_form = MESSAGE_POST_DEC_OP; break;
1550 case PROPERTY_OP: lvalue_form = PROPERTY_POST_DEC_OP; break;
1554 if (lvalue_form == 0)
1555 { error_named("'=' applied to",
1556 (char *) operators[opnum_below].description);
1560 /* Transform from_node from_node
1562 below value to value
1566 ET[from_node].operator_number = lvalue_form;
1568 ET[from_node].down = i;
1570 { ET[i].up = from_node;
1574 ET[j].right = ET[below].right;
1577 check_lvalues(below);
1579 if (ET[from_node].right != -1)
1580 check_lvalues(ET[from_node].right);
1584 ET[from_node].down = -1;
1585 ET[from_node].value = zero_operand;
1586 if (ET[from_node].right != -1)
1587 check_lvalues(ET[from_node].right);
1590 /* --- Tree surgery for conditionals --------------------------------------- */
1592 static void negate_condition(int n)
1595 if (ET[n].right != -1) negate_condition(ET[n].right);
1596 if (ET[n].down == -1) return;
1597 i = operators[ET[n].operator_number].negation;
1598 if (i!=0) ET[n].operator_number = i;
1599 if (operators[i].precedence==2) negate_condition(ET[n].down);
1602 static void delete_negations(int n, int context)
1604 /* Recursively apply
1606 ~~(x && y) = ~~x || ~~y
1607 ~~(x || y) = ~~x && ~~y
1610 (etc) to delete the ~~ operator from the tree. Since this is
1611 depth first, the ~~ being deleted has no ~~s beneath it, which
1612 is important to make "negate_condition" work. */
1616 if (ET[n].right != -1) delete_negations(ET[n].right, context);
1617 if (ET[n].down == -1) return;
1618 delete_negations(ET[n].down, context);
1620 if (ET[n].operator_number == LOGNOT_OP)
1621 { negate_condition(ET[n].down);
1622 ET[n].operator_number
1623 = ET[ET[n].down].operator_number;
1624 ET[n].down = ET[ET[n].down].down;
1626 while(i != -1) { ET[i].up = n; i = ET[i].right; }
1630 static void insert_exp_to_cond(int n, int context)
1632 /* Insert a ~= test when an expression is used as a condition.
1634 Check for possible confusion over = and ==, e.g. "if (a = 1) ..." */
1638 if (ET[n].right != -1) insert_exp_to_cond(ET[n].right, context);
1640 if (ET[n].down == -1)
1641 { if (context==CONDITION_CONTEXT)
1643 if (new == MAX_EXPRESSION_NODES)
1644 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1646 ET[n].down = new; ET[n].operator_number = NONZERO_OP;
1647 ET[new].up = n; ET[new].right = -1;
1652 switch(operators[ET[n].operator_number].precedence)
1653 { case 3: /* Conditionals have level 3 */
1654 context = QUANTITY_CONTEXT;
1656 case 2: /* Logical operators level 2 */
1657 context = CONDITION_CONTEXT;
1659 case 1: /* Forms of '=' have level 1 */
1660 if (context == CONDITION_CONTEXT)
1661 warning("'=' used as condition: '==' intended?");
1663 if (context != CONDITION_CONTEXT) break;
1666 if (new == MAX_EXPRESSION_NODES)
1667 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1669 ET[n].down = new; ET[n].operator_number = NONZERO_OP;
1670 ET[new].up = n; ET[new].right = -1;
1673 while (i!= -1) { ET[i].up = new; i = ET[i].right; }
1674 context = QUANTITY_CONTEXT; n = new;
1677 insert_exp_to_cond(ET[n].down, context);
1680 static unsigned int etoken_num_children(int n)
1685 if (i == -1) { return 0; }
1693 static void func_args_on_stack(int n, int context)
1695 /* Make sure that the arguments of every function-call expression
1696 are stored to the stack. If any aren't (ie, if any arguments are
1697 constants or variables), cover them with push operators.
1698 (The very first argument does not need to be so treated, because
1699 it's the function address, not a function argument. We also
1700 skip the treatment for most system functions.) */
1702 int new, pn, fnaddr, opnum;
1706 if (ET[n].right != -1)
1707 func_args_on_stack(ET[n].right, context);
1708 if (ET[n].down == -1) {
1711 opnum = ET[pn].operator_number;
1712 if (opnum == FCALL_OP
1713 || opnum == MESSAGE_CALL_OP
1714 || opnum == PROP_CALL_OP) {
1715 /* If it's an FCALL, get the operand which contains the function
1716 address (or system-function number) */
1717 if (opnum == MESSAGE_CALL_OP
1718 || opnum == PROP_CALL_OP
1719 || ((fnaddr=ET[pn].down) != n
1720 && (ET[fnaddr].value.type != SYSFUN_OT
1721 || ET[fnaddr].value.value == INDIRECT_SYSF
1722 || ET[fnaddr].value.value == GLK_SYSF))) {
1723 if (etoken_num_children(pn) > (unsigned int)(opnum == FCALL_OP ? 4:3)) {
1725 if (new == MAX_EXPRESSION_NODES)
1726 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1729 ET[n].operator_number = PUSH_OP;
1739 func_args_on_stack(ET[n].down, context);
1742 static assembly_operand check_conditions(assembly_operand AO, int context)
1745 if (AO.type != EXPRESSION_OT)
1746 { if (context != CONDITION_CONTEXT) return AO;
1748 if (n == MAX_EXPRESSION_NODES)
1749 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1754 INITAOT(&AO, EXPRESSION_OT);
1758 insert_exp_to_cond(AO.value, context);
1759 delete_negations(AO.value, context);
1762 func_args_on_stack(AO.value, context);
1767 /* --- Shift-reduce parser ------------------------------------------------- */
1770 static token_data *sr_stack;
1772 extern assembly_operand parse_expression(int context)
1774 /* Parses an expression, evaluating it as a constant if possible.
1776 Possible contexts are:
1778 VOID_CONTEXT the expression is used as a statement, so that
1779 its value will be thrown away and it only
1780 needs to exist for any resulting side-effects
1781 (function calls and assignments)
1783 CONDITION_CONTEXT the result must be a condition
1785 CONSTANT_CONTEXT there is required to be a constant result
1786 (so that, for instance, comma becomes illegal)
1788 QUANTITY_CONTEXT the default: a quantity is to be specified
1790 ACTION_Q_CONTEXT like QUANTITY_CONTEXT, but postfixed brackets
1791 at the top level do not indicate function call:
1793 <Insert button (random(pocket1, pocket2))>
1795 RETURN_Q_CONTEXT like QUANTITY_CONTEXT, but a single property
1796 name does not generate a warning
1798 ASSEMBLY_CONTEXT a quantity which cannot use the '->' operator
1799 (needed for assembly language to indicate
1802 FORINIT_CONTEXT a quantity which cannot use an (unbracketed)
1805 ARRAY_CONTEXT like CONSTANT_CONTEXT, but where an unbracketed
1806 minus sign is ambiguous, and brackets always
1807 indicate subexpressions, not function calls
1809 Return value: an assembly operand.
1811 If the type is OMITTED_OT, then the expression has no resulting value.
1813 If the type is EXPRESSION_OT, then the value will need to be
1814 calculated at run-time by code compiled from the expression tree
1815 whose root node-number is the operand value.
1817 Otherwise the assembly operand is the value of the expression, which
1818 is constant and thus known at compile time.
1820 If an error has occurred in the expression, which recovery from was
1821 not possible, then the return is (short constant) 0. This should
1822 minimise the chance of a cascade of further error messages.
1825 token_data a, b, pop; int i;
1826 assembly_operand AO;
1828 superclass_allowed = (context != FORINIT_CONTEXT);
1829 if (context == FORINIT_CONTEXT) context = VOID_CONTEXT;
1831 comma_allowed = (context == VOID_CONTEXT);
1832 arrow_allowed = (context != ASSEMBLY_CONTEXT);
1833 bare_prop_allowed = (context == RETURN_Q_CONTEXT);
1834 array_init_ambiguity = ((context == ARRAY_CONTEXT) ||
1835 (context == ASSEMBLY_CONTEXT));
1837 action_ambiguity = (context == ACTION_Q_CONTEXT);
1839 if (context == ASSEMBLY_CONTEXT) context = QUANTITY_CONTEXT;
1840 if (context == ACTION_Q_CONTEXT) context = QUANTITY_CONTEXT;
1841 if (context == RETURN_Q_CONTEXT) context = QUANTITY_CONTEXT;
1842 if (context == ARRAY_CONTEXT) context = CONSTANT_CONTEXT;
1845 inserting_token = FALSE;
1850 previous_token.text = "$";
1851 previous_token.type = ENDEXP_TT;
1852 previous_token.value = 0;
1855 sr_stack[0] = previous_token;
1859 statements.enabled = FALSE;
1860 directives.enabled = FALSE;
1862 if (get_next_etoken() == FALSE)
1863 { ebf_error("expression", token_text);
1868 { if (expr_trace_level >= 2)
1869 { printf("Input: %-20s", current_token.text);
1870 for (i=0; i<sr_sp; i++) printf("%s ", sr_stack[i].text);
1873 if (expr_trace_level >= 3) printf("ET_used = %d\n", ET_used);
1876 { compiler_error("SR error: stack empty");
1880 a = sr_stack[sr_sp-1]; b = current_token;
1882 if ((a.type == ENDEXP_TT) && (b.type == ENDEXP_TT))
1883 { if (emitter_sp == 0)
1884 { compiler_error("SR error: emitter stack empty");
1888 { compiler_error("SR error: emitter stack overfull");
1892 AO = emitter_stack[0];
1893 if (AO.type == EXPRESSION_OT)
1894 { if (expr_trace_level >= 3)
1895 { printf("Tree before lvalue checking:\n");
1896 show_tree(AO, FALSE);
1899 check_property_operator(AO.value);
1900 check_lvalues(AO.value);
1901 ET[AO.value].up = -1;
1904 if ((context != CONSTANT_CONTEXT) && is_property_t(AO.symtype)
1905 && (arrow_allowed) && (!bare_prop_allowed))
1906 warning("Bare property name found. \"self.prop\" intended?");
1909 check_conditions(AO, context);
1911 if (context == CONSTANT_CONTEXT)
1912 if (!is_constant_ot(AO.type))
1913 { AO = zero_operand;
1914 ebf_error("constant", "<expression>");
1921 switch(find_prec(a,b))
1923 case e5: /* Associativity error */
1924 error_named("Brackets mandatory to clarify order of:",
1929 if (sr_sp == MAX_EXPRESSION_NODES)
1930 memoryerror("MAX_EXPRESSION_NODES", MAX_EXPRESSION_NODES);
1931 sr_stack[sr_sp++] = b;
1935 if (sr_sp >= 2 && sr_stack[sr_sp-2].type == OP_TT && sr_stack[sr_sp-2].value == FCALL_OP)
1936 mark_top_of_emitter_stack(FUNCTION_VALUE_MARKER, b);
1938 add_bracket_layer_to_emitter_stack(0);
1943 if (sr_stack[sr_sp-2].type == OP_TT &&
1944 operators[sr_stack[sr_sp-2].value].precedence == 3)
1945 mark_top_of_emitter_stack(OR_VALUE_MARKER, b);
1947 { error("'or' not between values to the right of a condition");
1948 /* Convert to + for error recovery purposes */
1949 sr_stack[sr_sp-1].value = PLUS_OP;
1954 /* A comma separates arguments only if the shallowest open bracket belongs to a function call. */
1955 int shallowest_open_bracket_index = sr_sp - 2;
1956 while (shallowest_open_bracket_index > 0 && sr_stack[shallowest_open_bracket_index].type != SUBOPEN_TT)
1957 --shallowest_open_bracket_index;
1958 if (shallowest_open_bracket_index > 0 &&
1959 sr_stack[shallowest_open_bracket_index-1].type == OP_TT &&
1960 sr_stack[shallowest_open_bracket_index-1].value == FCALL_OP)
1961 { mark_top_of_emitter_stack(ARGUMENT_VALUE_MARKER, b);
1964 /* Non-argument-separating commas get treated like any other operator; we fall through to the default case. */
1968 /* Add a marker for the brackets implied by operator precedence */
1969 int operands_on_left = (operators[b.value].usage == PRE_U) ? 0 : 1;
1970 add_bracket_layer_to_emitter_stack(operands_on_left);
1978 { pop = sr_stack[sr_sp - 1];
1981 } while (find_prec(sr_stack[sr_sp-1], pop) != LOWER_P);
1984 case e1: /* Missing operand error */
1985 error_named("Missing operand after", a.text);
1987 current_token.type = NUMBER_TT;
1988 current_token.value = 0;
1989 current_token.marker = 0;
1990 current_token.text = "0";
1993 case e2: /* Unexpected close bracket */
1994 error("Found '(' without matching ')'");
1998 case e3: /* Missing operator error */
1999 error("Missing operator: inserting '+'");
2001 current_token.type = OP_TT;
2002 current_token.value = PLUS_OP;
2003 current_token.marker = 0;
2004 current_token.text = "+";
2007 case e4: /* Expression ends with an open bracket */
2008 error("Found '(' without matching ')'");
2017 /* --- Test for simple ++ or -- usage: used to optimise "for" loop code ---- */
2019 extern int test_for_incdec(assembly_operand AO)
2021 if (AO.type != EXPRESSION_OT) return 0;
2022 if (ET[AO.value].down == -1) return 0;
2023 switch(ET[AO.value].operator_number)
2024 { case INC_OP: s = 1; break;
2025 case POST_INC_OP: s = 1; break;
2026 case DEC_OP: s = -1; break;
2027 case POST_DEC_OP: s = -1; break;
2030 if (ET[ET[AO.value].down].down != -1) return 0;
2031 if (!is_variable_ot(ET[ET[AO.value].down].value.type)) return 0;
2032 return s*(ET[ET[AO.value].down].value.value);
2035 /* ========================================================================= */
2036 /* Data structure management routines */
2037 /* ------------------------------------------------------------------------- */
2039 extern void init_expressp_vars(void)
2041 /* make_operands(); */
2042 make_lexical_interface_tables();
2043 for (i=0;i<32;i++) system_function_usage[i] = 0;
2046 extern void expressp_begin_pass(void)
2050 extern void expressp_allocate_arrays(void)
2051 { ET = my_calloc(sizeof(expression_tree_node), MAX_EXPRESSION_NODES,
2052 "expression parse trees");
2053 emitter_markers = my_calloc(sizeof(int), MAX_EXPRESSION_NODES,
2055 emitter_bracket_counts = my_calloc(sizeof(int), MAX_EXPRESSION_NODES,
2056 "emitter bracket layer counts");
2057 emitter_stack = my_calloc(sizeof(assembly_operand), MAX_EXPRESSION_NODES,
2059 sr_stack = my_calloc(sizeof(token_data), MAX_EXPRESSION_NODES,
2060 "shift-reduce parser stack");
2063 extern void expressp_free_arrays(void)
2064 { my_free(&ET, "expression parse trees");
2065 my_free(&emitter_markers, "emitter markers");
2066 my_free(&emitter_bracket_counts, "emitter bracket layer counts");
2067 my_free(&emitter_stack, "emitter stack");
2068 my_free(&sr_stack, "shift-reduce parser stack");
2071 /* ========================================================================= */