2 COND_NEGATED = 1 ; only with COND_EVALUATE
\r
3 COND_TRUE = 1 ; only with COND_DETERMINED
\r
9 ; esi = pointer into preprocessed line or the last embedded line
\r
11 ; esi = pointer advanced past the processed line
\r
12 ; al = logical value
\r
13 mov ebx,[condition_stack_base]
\r
14 mov [condition_stack],ebx
\r
15 mov byte [ebx],COND_EVALUATE
\r
17 call peek_at_constituent_value
\r
19 jne negation_registered
\r
20 and [current_constituent],0
\r
21 mov ebx,[condition_stack]
\r
23 test byte [ebx],COND_EVALUATE
\r
24 jz get_logical_value
\r
25 xor byte [ebx],COND_NEGATED
\r
26 jmp get_logical_value
\r
27 negation_registered:
\r
28 call parse_logical_value
\r
31 jecxz get_logical_operator
\r
32 mov ebx,[condition_stack]
\r
34 cmp eax,[condition_stack_end]
\r
35 jbe condition_stack_ready
\r
38 mov eax,[condition_stack_base]
\r
42 mov [condition_stack_base],eax
\r
44 mov [condition_stack],ebx
\r
46 mov [condition_stack_end],eax
\r
48 condition_stack_ready:
\r
50 test byte [ebx],COND_EVALUATE
\r
51 jz store_opening_parentheses
\r
53 store_opening_parentheses:
\r
56 loop store_opening_parentheses
\r
57 mov [condition_stack],ebx
\r
59 je get_logical_value
\r
60 get_logical_operator:
\r
61 call peek_at_constituent_value
\r
62 jc end_of_logical_expression
\r
64 je close_logical_subexpression
\r
68 jne end_of_logical_expression
\r
70 and [current_constituent],0
\r
71 mov ebx,[condition_stack]
\r
73 test al,COND_EVALUATE
\r
74 jnz evaluate_logical_and
\r
75 test al,COND_DETERMINED
\r
76 jz get_logical_value
\r
79 jmp continue_evaluation
\r
80 evaluate_logical_and:
\r
81 test al,COND_NEGATED
\r
82 jnz evaluate_negated_logical_and
\r
83 call evaluate_logical_value
\r
84 mov ebx,[condition_stack]
\r
86 jnz continue_evaluation
\r
88 mov byte [ebx],COND_DETERMINED
\r
89 jmp get_logical_value
\r
90 evaluate_negated_logical_and:
\r
91 call evaluate_logical_value
\r
92 mov ebx,[condition_stack]
\r
94 jnz determined_false
\r
95 continue_evaluation:
\r
96 mov byte [ebx],COND_EVALUATE
\r
97 jmp get_logical_value
\r
99 and [current_constituent],0
\r
100 mov ebx,[condition_stack]
\r
102 test al,COND_EVALUATE
\r
103 jnz evaluate_logical_or
\r
104 test al,COND_DETERMINED
\r
105 jz get_logical_value
\r
107 jnz determined_true
\r
108 jmp continue_evaluation
\r
109 evaluate_logical_or:
\r
110 test al,COND_NEGATED
\r
111 jnz evaluate_negated_logical_or
\r
112 call evaluate_logical_value
\r
113 mov ebx,[condition_stack]
\r
115 jnz determined_true
\r
116 jmp continue_evaluation
\r
117 evaluate_negated_logical_or:
\r
118 call evaluate_logical_value
\r
119 mov ebx,[condition_stack]
\r
121 jnz continue_evaluation
\r
123 mov byte [ebx],COND_DETERMINED + COND_TRUE
\r
124 jmp get_logical_value
\r
125 close_logical_subexpression:
\r
126 and [current_constituent],0
\r
127 mov ebx,[condition_stack]
\r
128 cmp ebx,[condition_stack_base]
\r
129 je excess_parenthesis
\r
132 mov [condition_stack],ebx
\r
133 test al,COND_DETERMINED
\r
134 jnz subexpression_determined
\r
135 cmp al,COND_EVALUATE + COND_NEGATED
\r
136 jne get_logical_operator
\r
137 test byte [ebx],COND_EVALUATE
\r
138 jz get_logical_operator
\r
139 xor byte [ebx],COND_NEGATED
\r
140 jmp get_logical_operator
\r
141 subexpression_determined:
\r
143 jnz subexpression_determined_true
\r
144 mov [comparator],evaluated_false
\r
145 jmp get_logical_operator
\r
146 subexpression_determined_true:
\r
147 mov [comparator],evaluated_true
\r
148 jmp get_logical_operator
\r
149 end_of_logical_expression:
\r
150 mov ebx,[condition_stack]
\r
151 cmp ebx,[condition_stack_base]
\r
152 jne missing_parenthesis
\r
154 test al,COND_DETERMINED
\r
155 jnz condition_determined
\r
156 test al,COND_NEGATED
\r
157 jz evaluate_logical_value
\r
158 call evaluate_logical_value
\r
162 condition_determined:
\r
165 excess_parenthesis:
\r
166 mov edx,_excess_closing_parenthesis
\r
167 call register_error
\r
168 jmp unknown_condition
\r
169 missing_parenthesis:
\r
170 mov edx,_missing_closing_parenthesis
\r
171 call register_error
\r
176 parse_logical_value:
\r
178 ; esi = pointer into preprocessed line or the last embedded line
\r
180 ; [comparator] - evaluating routine
\r
181 ; [expression_workspace.memory_start] - parsed argument sequences
\r
182 ; [expression_end] - end of the parsed argument sequences
\r
183 ; esi = pointer advanced past the parsed value
\r
184 ; al = special character that follows parsed value, zero if no more symbols in line
\r
185 ; ecx = number of parentheses opened before the value that did not get closed
\r
186 ; cf set if value was empty
\r
187 mov edi,[expression_workspace.memory_start]
\r
189 mov [comparator],eax
\r
190 or [leave_opening_parentheses],1
\r
191 call parse_expression
\r
192 mov [initial_parentheses],ecx
\r
193 mov [expression_end],edi
\r
194 call peek_at_constituent_value
\r
197 je end_of_logical_value
\r
199 je end_of_logical_value
\r
201 je end_of_logical_value
\r
203 je end_of_logical_value
\r
205 je identify_comparator
\r
212 jmp end_of_logical_value
\r
213 identify_comparator:
\r
215 jz end_of_logical_value
\r
216 cmp [edx+ValueDefinition.type],VALTYPE_NATIVE_COMPARATOR
\r
217 jne end_of_logical_value
\r
218 and [current_constituent],0
\r
219 mov eax,[edx+ValueDefinition.value]
\r
222 and [current_constituent],0
\r
223 call warp_to_next_symbol
\r
226 jnz parse_less_than
\r
227 call peek_at_constituent_value
\r
230 je parse_less_or_equal
\r
234 mov eax,check_if_less
\r
236 parse_less_or_equal:
\r
237 and [current_constituent],0
\r
238 mov eax,check_if_not_greater
\r
241 and [current_constituent],0
\r
242 mov eax,check_if_not_equal
\r
245 and [current_constituent],0
\r
246 call warp_to_next_symbol
\r
247 jc parse_greater_than
\r
249 jnz parse_greater_than
\r
250 call peek_at_constituent_value
\r
251 jc parse_greater_than
\r
253 je parse_greater_or_equal
\r
254 parse_greater_than:
\r
255 mov eax,check_if_greater
\r
257 parse_greater_or_equal:
\r
258 and [current_constituent],0
\r
259 mov eax,check_if_not_less
\r
262 and [current_constituent],0
\r
263 mov eax,check_if_equal
\r
265 mov edi,[expression_end]
\r
266 mov [comparator],eax
\r
267 and [leave_opening_parentheses],0
\r
268 call parse_expression
\r
269 mov [expression_end],edi
\r
270 call peek_at_constituent_value
\r
271 jnc end_of_logical_value
\r
274 end_of_logical_value:
\r
275 mov ecx,[initial_parentheses]
\r
277 jnz logical_value_not_empty
\r
278 mov [comparator],check_if_not_zero
\r
279 mov ebx,[expression_workspace.memory_start]
\r
281 jne logical_value_not_empty
\r
284 logical_value_not_empty:
\r
288 evaluate_logical_value:
\r
290 ; [comparator] - evaluating routine
\r
291 ; [expression_workspace.memory_start] - parsed argument sequences
\r
292 ; out: al = logical value
\r
293 ; note: evaluates value prepared by previous call to parse_logical_value
\r
296 mov esi,[expression_workspace.memory_start]
\r
307 evaluate_stored_logical_value:
\r
308 ; in: esi - pointer to evaluating routine followed by parsed argument sequences
\r
309 ; out: al = logical value
\r
315 invalid_logical_value:
\r
316 mov edx,_invalid_expression
\r
317 call register_error
\r
318 jmp evaluated_false
\r
321 call get_difference_signum
\r
324 jmp evaluated_false
\r
325 check_if_not_equal:
\r
326 call get_difference_signum
\r
329 jmp evaluated_false
\r
331 call get_difference_signum
\r
334 jmp evaluated_false
\r
336 call get_difference_signum
\r
339 jmp evaluated_false
\r
341 call get_difference_signum
\r
344 jmp evaluated_false
\r
345 check_if_not_greater:
\r
346 call get_difference_signum
\r
349 jmp evaluated_false
\r
350 get_difference_signum:
\r
351 mov edi,[calculation_workspace.memory_start]
\r
352 call calculate_parsed_expression
\r
354 call calculate_parsed_expression
\r
356 mov esi,subtraction_operator
\r
357 call calculate_parsed_expression
\r
360 jnc check_difference_for_variable_terms
\r
364 check_difference_for_variable_terms:
\r
365 add eax,sizeof.ExpressionTerm
\r
366 cmp [eax+ExpressionTerm.attributes],0
\r
367 je difference_terms_ok
\r
368 cmp [eax+ExpressionTerm.metadata],0
\r
369 je check_difference_for_variable_terms
\r
370 mov edx,_values_not_comparable
\r
371 call register_error
\r
372 difference_terms_ok:
\r
373 cmp byte [edi+ExpressionTerm.attributes],EXPR_FLOAT
\r
374 je get_float_signum
\r
375 call get_numeric_term_value
\r
382 jne signum_positive
\r
385 call get_term_value
\r
387 call get_float_exponent
\r
389 test [esi+FloatData.attributes],FLOAT_NEGATIVE
\r
390 jnz signum_negative
\r
402 mov edi,[calculation_workspace.memory_start]
\r
403 call calculate_parsed_expression
\r
407 cmp byte [edi+ExpressionTerm.attributes],EXPR_FLOAT
\r
408 je check_if_not_zero_float
\r
409 call get_numeric_term_value
\r
416 check_if_has_variable_terms:
\r
417 add edi,sizeof.ExpressionTerm
\r
418 cmp [edi+ExpressionTerm.attributes],0
\r
420 cmp [edi+ExpressionTerm.metadata],0
\r
421 je check_if_has_variable_terms
\r
423 check_if_not_zero_float:
\r
424 call get_term_value
\r
426 call get_float_exponent
\r
427 jz check_if_has_variable_terms
\r
431 mov edi,[calculation_workspace.memory_start]
\r
432 call calculate_parsed_expression
\r
434 call calculate_parsed_expression
\r
442 cmp [edx+sizeof.ExpressionTerm+ExpressionTerm.attributes],0
\r
443 je check_difference_terms
\r
445 cmp [edx+sizeof.ExpressionTerm+ExpressionTerm.attributes],0
\r
446 je check_difference_terms
\r
447 mov esi,subtraction_operator
\r
449 call calculate_parsed_expression
\r
452 check_difference_terms:
\r
453 add edi,sizeof.ExpressionTerm
\r
454 cmp [edi+ExpressionTerm.attributes],0
\r
456 cmp [edi+ExpressionTerm.metadata],0
\r
457 je check_difference_terms
\r
458 jmp evaluated_false
\r
459 undefined_condition:
\r
460 mov edx,_invalid_value
\r
461 call register_error
\r
462 jmp evaluated_false
\r
464 check_if_type_equal:
\r
465 mov edi,[calculation_workspace.memory_start]
\r
466 call calculate_parsed_expression
\r
470 mov eax,[edi+ExpressionTerm.attributes]
\r
471 mov [result_type],al
\r
472 call calculate_parsed_expression
\r
476 mov eax,[edi+ExpressionTerm.attributes]
\r
477 cmp al,[result_type]
\r
479 jmp evaluated_false
\r
481 check_if_value_equal:
\r
482 mov edi,[calculation_workspace.memory_start]
\r
483 call calculate_parsed_expression
\r
488 mov eax,[edi+ExpressionTerm.attributes]
\r
489 mov [result_type],al
\r
491 call calculate_parsed_expression
\r
496 mov eax,[edi+ExpressionTerm.attributes]
\r
497 cmp al,[result_type]
\r
498 jne evaluated_false
\r
500 jne compare_values_numerically
\r
501 call get_term_value
\r
504 call get_term_value
\r
506 jne evaluated_false
\r
507 compare_values_numerically:
\r
508 mov esi,subtraction_operator
\r
510 call calculate_parsed_expression
\r
514 check_if_terms_equal:
\r
515 add eax,sizeof.ExpressionTerm
\r
516 cmp [eax+ExpressionTerm.attributes],0
\r
517 je check_if_constant_term_equal
\r
518 cmp [eax+ExpressionTerm.metadata],0
\r
519 je check_if_terms_equal
\r
520 jmp evaluated_false
\r
521 check_if_constant_term_equal:
\r
522 cmp byte [edi+ExpressionTerm.attributes],EXPR_FLOAT
\r
523 je check_if_float_equal
\r
524 call get_numeric_term_value
\r
530 check_if_float_equal:
\r
531 call get_term_value
\r
533 call get_float_exponent
\r
534 jnz evaluated_false
\r
539 jmp check_if_expression_defined
\r
540 check_if_defined_earlier:
\r
541 mov ecx,[current_pass]
\r
542 check_if_expression_defined:
\r
543 and [outer_expression],0
\r
544 and [defined_element],0
\r
547 jnz checked_expression_invalid
\r
548 check_expression_element:
\r
551 jz check_expression_end
\r
553 je check_if_subexpression_defined
\r
554 cmp al,EXPR_SYMBOL_VALUE
\r
555 je check_if_symbol_defined
\r
556 or [defined_element],1
\r
559 je check_expression_element
\r
561 je check_expression_element
\r
563 je check_expression_element
\r
564 cmp al,EXPR_OPERATOR
\r
565 je check_expression_element
\r
566 checked_expression_invalid:
\r
567 jmp invalid_logical_value
\r
568 check_expression_end:
\r
570 xchg esi,[outer_expression]
\r
572 jnz check_expression_element
\r
573 jecxz checked_expression_defined
\r
574 cmp [defined_element],0
\r
575 je checked_expression_invalid
\r
576 checked_expression_defined:
\r
578 check_if_symbol_defined:
\r
585 check_symbol_value:
\r
586 or [defined_element],1
\r
587 jecxz check_expression_element
\r
588 test [eax+ValueDefinition.flags],VAL_INTERNAL
\r
589 jnz check_expression_element
\r
590 cmp [eax+ValueDefinition.pass],ecx
\r
591 jne evaluated_false
\r
592 jmp check_expression_element
\r
593 check_if_subexpression_defined:
\r
598 call get_available_value
\r
602 cmp [eax+ValueDefinition.type],VALTYPE_SYMBOLIC
\r
603 jne check_symbol_value
\r
604 mov [outer_expression],esi
\r
606 call get_subexpression
\r
608 jnc invalid_logical_value
\r
609 jmp check_expression_element
\r
611 call clear_line_embeddings
\r
614 call embed_symbolic_value
\r
615 mov edi,[expression_workspace.memory_start]
\r
616 and [leave_opening_parentheses],0
\r
617 call parse_expression
\r
618 call get_constituent_value
\r
619 mov esi,[expression_workspace.memory_start]
\r
625 jnz invalid_logical_value
\r
626 check_if_expression_is_used_symbol:
\r
629 je check_for_indirect_symbol
\r
630 cmp al,EXPR_SYMBOL_VALUE
\r
631 jne invalid_logical_value
\r
635 check_if_used_symbol:
\r
638 jnz invalid_logical_value
\r
641 mov ecx,[ebx+SymbolTree_Leaf.last_use_pass]
\r
642 jecxz symbol_predicted_unused
\r
643 mov eax,[current_pass]
\r
647 ja symbol_predicted_unused
\r
648 symbol_predicted_used:
\r
649 or [ebx+SymbolTree_Leaf.flags],SYM_USAGE_PREDICTED + SYM_PREDICTED_USED
\r
651 symbol_predicted_unused:
\r
652 mov al,[ebx+SymbolTree_Leaf.flags]
\r
653 or al,SYM_USAGE_PREDICTED
\r
654 and al,not SYM_PREDICTED_USED
\r
655 mov [ebx+SymbolTree_Leaf.flags],al
\r
656 jmp evaluated_false
\r
657 check_for_indirect_symbol:
\r
660 call get_available_value
\r
662 jz check_if_used_symbol
\r
663 cmp [edx+ValueDefinition.type],VALTYPE_SYMBOLIC
\r
664 jne check_if_used_symbol
\r
665 call get_subexpression
\r
666 jnc invalid_logical_value
\r
667 jmp check_if_expression_is_used_symbol
\r