initial commit: a mess of assembly code
[fmap.git] / x86_64_sse2_x87 / fasm / source / conditions.inc
blob0c46786c3dc31b1a5574c9326c9f1963dcc62fd1
1 \r
2 COND_NEGATED = 1                        ; only with COND_EVALUATE\r
3 COND_TRUE = 1                           ; only with COND_DETERMINED\r
4 COND_EVALUATE = 2\r
5 COND_DETERMINED = 4\r
6 \r
7 get_condition_value:\r
8 ; in:\r
9 ;  esi = pointer into preprocessed line or the last embedded line\r
10 ; out:\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
16     get_logical_value:\r
17         call    peek_at_constituent_value\r
18         cmp     al,'~'\r
19         jne     negation_registered\r
20         and     [current_constituent],0\r
21         mov     ebx,[condition_stack]\r
22         mov     al,[ebx]\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
29         setnc   dh\r
30         mov     dl,al\r
31         jecxz   get_logical_operator\r
32         mov     ebx,[condition_stack]\r
33         lea     eax,[ebx+ecx+1]\r
34         cmp     eax,[condition_stack_end]\r
35         jbe     condition_stack_ready\r
36         push    ecx edx\r
37         mov     ecx,eax\r
38         mov     eax,[condition_stack_base]\r
39         sub     ecx,eax\r
40         sub     ebx,eax\r
41         call    grow_stack\r
42         mov     [condition_stack_base],eax\r
43         add     ebx,eax\r
44         mov     [condition_stack],ebx\r
45         add     eax,ecx\r
46         mov     [condition_stack_end],eax\r
47         pop     edx ecx\r
48     condition_stack_ready:\r
49         xor     al,al\r
50         test    byte [ebx],COND_EVALUATE\r
51         jz      store_opening_parentheses\r
52         or      al,COND_EVALUATE\r
53     store_opening_parentheses:\r
54         inc     ebx\r
55         mov     [ebx],al\r
56         loop    store_opening_parentheses\r
57         mov     [condition_stack],ebx\r
58         cmp     dx,'~'\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
63         cmp     al,')'\r
64         je      close_logical_subexpression\r
65         cmp     al,'|'\r
66         je      logical_or\r
67         cmp     al,'&'\r
68         jne     end_of_logical_expression\r
69     logical_and:\r
70         and     [current_constituent],0\r
71         mov     ebx,[condition_stack]\r
72         mov     al,[ebx]\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
77         test    al,COND_TRUE\r
78         jz      determined_false\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
85         test    al,al\r
86         jnz     continue_evaluation\r
87     determined_false:\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
93         test    al,al\r
94         jnz     determined_false\r
95     continue_evaluation:\r
96         mov     byte [ebx],COND_EVALUATE\r
97         jmp     get_logical_value\r
98     logical_or:\r
99         and     [current_constituent],0\r
100         mov     ebx,[condition_stack]\r
101         mov     al,[ebx]\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
106         test    al,COND_TRUE\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
114         test    al,al\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
120         test    al,al\r
121         jnz     continue_evaluation\r
122     determined_true:\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
130         mov     al,[ebx]\r
131         dec     ebx\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
142         test    al,COND_TRUE\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
153         mov     al,[ebx]\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
159         test    al,al\r
160         setz    al\r
161         retn\r
162     condition_determined:\r
163         and     al,COND_TRUE\r
164         retn\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
172     unknown_condition:\r
173         xor     al,al\r
174         retn\r
176 parse_logical_value:\r
177 ; in:\r
178 ;  esi = pointer into preprocessed line or the last embedded line\r
179 ; out:\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
188         xor     eax,eax\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
195         jc      end_of_line\r
196         cmp     al,'&'\r
197         je      end_of_logical_value\r
198         cmp     al,'|'\r
199         je      end_of_logical_value\r
200         cmp     al,'~'\r
201         je      end_of_logical_value\r
202         cmp     al,')'\r
203         je      end_of_logical_value\r
204         cmp     al,1Ah\r
205         je      identify_comparator\r
206         cmp     al,'='\r
207         je      parse_equal\r
208         cmp     al,'<'\r
209         je      parse_less\r
210         cmp     al,'>'\r
211         je      parse_greater\r
212         jmp     end_of_logical_value\r
213     identify_comparator:\r
214         test    edx,edx\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
220         jmp     set_comparator\r
221     parse_less:\r
222         and     [current_constituent],0\r
223         call    warp_to_next_symbol\r
224         jc      parse_less_than\r
225         test    ecx,ecx\r
226         jnz     parse_less_than\r
227         call    peek_at_constituent_value\r
228         jc      parse_less_than\r
229         cmp     al,'='\r
230         je      parse_less_or_equal\r
231         cmp     al,'>'\r
232         je      parse_not_equal\r
233     parse_less_than:\r
234         mov     eax,check_if_less\r
235         jmp     set_comparator\r
236     parse_less_or_equal:\r
237         and     [current_constituent],0\r
238         mov     eax,check_if_not_greater\r
239         jmp     set_comparator\r
240     parse_not_equal:\r
241         and     [current_constituent],0\r
242         mov     eax,check_if_not_equal\r
243         jmp     set_comparator\r
244     parse_greater:\r
245         and     [current_constituent],0\r
246         call    warp_to_next_symbol\r
247         jc      parse_greater_than\r
248         test    ecx,ecx\r
249         jnz     parse_greater_than\r
250         call    peek_at_constituent_value\r
251         jc      parse_greater_than\r
252         cmp     al,'='\r
253         je      parse_greater_or_equal\r
254     parse_greater_than:\r
255         mov     eax,check_if_greater\r
256         jmp     set_comparator\r
257     parse_greater_or_equal:\r
258         and     [current_constituent],0\r
259         mov     eax,check_if_not_less\r
260         jmp     set_comparator\r
261     parse_equal:\r
262         and     [current_constituent],0\r
263         mov     eax,check_if_equal\r
264     set_comparator:\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
272     end_of_line:\r
273         xor     al,al\r
274     end_of_logical_value:\r
275         mov     ecx,[initial_parentheses]\r
276         cmp     [comparator],0\r
277         jnz     logical_value_not_empty\r
278         mov     [comparator],check_if_not_zero\r
279         mov     ebx,[expression_workspace.memory_start]\r
280         cmp     dword [ebx],0\r
281         jne     logical_value_not_empty\r
282         stc\r
283         retn\r
284     logical_value_not_empty:\r
285         clc\r
286         retn\r
288 evaluate_logical_value:\r
289 ; in:\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
294 ; preserves: esi\r
295         push    esi\r
296         mov     esi,[expression_workspace.memory_start]\r
297         jmp     [comparator]\r
298     evaluated_false:\r
299         pop     esi\r
300         xor     al,al\r
301         retn\r
302     evaluated_true:\r
303         pop     esi\r
304         mov     al,1\r
305         retn\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
310 ; preserves: esi\r
311         push    esi\r
312         lodsd\r
313         jmp     eax\r
315 invalid_logical_value:\r
316         mov     edx,_invalid_expression\r
317         call    register_error\r
318         jmp     evaluated_false\r
320 check_if_equal:\r
321         call    get_difference_signum\r
322         test    al,al\r
323         jz      evaluated_true\r
324         jmp     evaluated_false\r
325 check_if_not_equal:\r
326         call    get_difference_signum\r
327         test    al,al\r
328         jnz     evaluated_true\r
329         jmp     evaluated_false\r
330 check_if_less:\r
331         call    get_difference_signum\r
332         cmp     al,0\r
333         jl      evaluated_true\r
334         jmp     evaluated_false\r
335 check_if_not_less:\r
336         call    get_difference_signum\r
337         cmp     al,0\r
338         jnl     evaluated_true\r
339         jmp     evaluated_false\r
340 check_if_greater:\r
341         call    get_difference_signum\r
342         cmp     al,0\r
343         jg      evaluated_true\r
344         jmp     evaluated_false\r
345 check_if_not_greater:\r
346         call    get_difference_signum\r
347         cmp     al,0\r
348         jng     evaluated_true\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
353         jc      signum_error\r
354         call    calculate_parsed_expression\r
355         jc      signum_error\r
356         mov     esi,subtraction_operator\r
357         call    calculate_parsed_expression\r
358         call    pop_terms\r
359         mov     eax,edi\r
360         jnc     check_difference_for_variable_terms\r
361       signum_error:\r
362         xor     al,al\r
363         retn\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
376         mov     ecx,1\r
377         call    fit_value\r
378         js      signum_negative\r
379         jc      signum_positive\r
380         xor     al,al\r
381         cmp     [edi],al\r
382         jne     signum_positive\r
383         retn\r
384       get_float_signum:\r
385         call    get_term_value\r
386         mov     esi,edx\r
387         call    get_float_exponent\r
388         jz      signum_zero\r
389         test    [esi+FloatData.attributes],FLOAT_NEGATIVE\r
390         jnz     signum_negative\r
391       signum_positive:\r
392         mov     al,1\r
393         retn\r
394       signum_negative:\r
395         or      al,-1\r
396         retn\r
397       signum_zero:\r
398         xor     al,al\r
399         retn\r
401 check_if_not_zero:\r
402         mov     edi,[calculation_workspace.memory_start]\r
403         call    calculate_parsed_expression\r
404         jc      evaluated_false\r
405         call    pop_terms\r
406         jc      evaluated_false\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
410         mov     ecx,1\r
411         call    fit_value\r
412         js      evaluated_true\r
413         jc      evaluated_true\r
414         cmp     byte [edi],0\r
415         jne     evaluated_true\r
416     check_if_has_variable_terms:\r
417         add     edi,sizeof.ExpressionTerm\r
418         cmp     [edi+ExpressionTerm.attributes],0\r
419         je      evaluated_false\r
420         cmp     [edi+ExpressionTerm.metadata],0\r
421         je      check_if_has_variable_terms\r
422         jmp     evaluated_true\r
423     check_if_not_zero_float:\r
424         call    get_term_value\r
425         mov     esi,edx\r
426         call    get_float_exponent\r
427         jz      check_if_has_variable_terms\r
428         jmp     evaluated_true\r
430 check_if_relative:\r
431         mov     edi,[calculation_workspace.memory_start]\r
432         call    calculate_parsed_expression\r
433         jc      evaluated_false\r
434         call    calculate_parsed_expression\r
435         jc      evaluated_false\r
436         mov     ebx,edi\r
437         call    pop_terms\r
438         jc      evaluated_false\r
439         mov     edx,edi\r
440         call    pop_terms\r
441         jc      evaluated_false\r
442         cmp     [edx+sizeof.ExpressionTerm+ExpressionTerm.attributes],0\r
443         je      check_difference_terms\r
444         xchg    edi,edx\r
445         cmp     [edx+sizeof.ExpressionTerm+ExpressionTerm.attributes],0\r
446         je      check_difference_terms\r
447         mov     esi,subtraction_operator\r
448         mov     edi,ebx\r
449         call    calculate_parsed_expression\r
450         call    pop_terms\r
451         jc      evaluated_false\r
452     check_difference_terms:\r
453         add     edi,sizeof.ExpressionTerm\r
454         cmp     [edi+ExpressionTerm.attributes],0\r
455         je      evaluated_true\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
467         jc      evaluated_false\r
468         call    pop_terms\r
469         jc      evaluated_false\r
470         mov     eax,[edi+ExpressionTerm.attributes]\r
471         mov     [result_type],al\r
472         call    calculate_parsed_expression\r
473         jc      evaluated_false\r
474         call    pop_terms\r
475         jc      evaluated_false\r
476         mov     eax,[edi+ExpressionTerm.attributes]\r
477         cmp     al,[result_type]\r
478         je      evaluated_true\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
484         jc      evaluated_false\r
485         mov     ebx,edi\r
486         call    pop_terms\r
487         jc      evaluated_false\r
488         mov     eax,[edi+ExpressionTerm.attributes]\r
489         mov     [result_type],al\r
490         mov     edi,ebx\r
491         call    calculate_parsed_expression\r
492         jc      evaluated_false\r
493         mov     ebx,edi\r
494         call    pop_terms\r
495         jc      evaluated_false\r
496         mov     eax,[edi+ExpressionTerm.attributes]\r
497         cmp     al,[result_type]\r
498         jne     evaluated_false\r
499         cmp     al,EXPR_STRING\r
500         jne     compare_values_numerically\r
501         call    get_term_value\r
502         mov     ecx,[edx]\r
503         call    pop_terms\r
504         call    get_term_value\r
505         cmp     ecx,[edx]\r
506         jne     evaluated_false\r
507       compare_values_numerically:\r
508         mov     esi,subtraction_operator\r
509         mov     edi,ebx\r
510         call    calculate_parsed_expression\r
511         call    pop_terms\r
512         jc      evaluated_false\r
513         mov     eax,edi\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
525         xor     ecx,ecx\r
526         xor     edi,edi\r
527         call    fit_value\r
528         jc      evaluated_false\r
529         jmp     evaluated_true\r
530       check_if_float_equal:\r
531         call    get_term_value\r
532         mov     esi,edx\r
533         call    get_float_exponent\r
534         jnz     evaluated_false\r
535         jmp     evaluated_true\r
537 check_if_defined:\r
538         xor     ecx,ecx\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
545         lodsd\r
546         test    eax,eax\r
547         jnz     checked_expression_invalid\r
548     check_expression_element:\r
549         lodsd\r
550         test    eax,eax\r
551         jz      check_expression_end\r
552         cmp     al,EXPR_SYMBOL\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
557         add     esi,4\r
558         cmp     al,EXPR_NUMBER\r
559         je      check_expression_element\r
560         cmp     al,EXPR_STRING\r
561         je      check_expression_element\r
562         cmp     al,EXPR_FLOAT\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
569         xor     esi,esi\r
570         xchg    esi,[outer_expression]\r
571         test    esi,esi\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
577         jmp     evaluated_true\r
578     check_if_symbol_defined:\r
579         lodsd\r
580         test    eax,eax\r
581         jz      evaluated_false\r
582         lodsd\r
583         test    eax,eax\r
584         jz      evaluated_false\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
594         mov     ebx,[esi]\r
595         test    ebx,ebx\r
596         jz      evaluated_false\r
597         add     esi,4\r
598         call    get_available_value\r
599         mov     eax,edx\r
600         test    eax,eax\r
601         jz      evaluated_false\r
602         cmp     [eax+ValueDefinition.type],VALTYPE_SYMBOLIC\r
603         jne     check_symbol_value\r
604         mov     [outer_expression],esi\r
605         push    ecx\r
606         call    get_subexpression\r
607         pop     ecx\r
608         jnc     invalid_logical_value\r
609         jmp     check_expression_element\r
610     get_subexpression:\r
611         call    clear_line_embeddings\r
612         xor     esi,esi\r
613         xor     ecx,ecx\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
620         retn\r
622 check_if_used:\r
623         lodsd\r
624         test    eax,eax\r
625         jnz     invalid_logical_value\r
626    check_if_expression_is_used_symbol:\r
627         lodsd\r
628         cmp     al,EXPR_SYMBOL\r
629         je      check_for_indirect_symbol\r
630         cmp     al,EXPR_SYMBOL_VALUE\r
631         jne     invalid_logical_value\r
632         lodsd\r
633         mov     ebx,eax\r
634         lodsd\r
635    check_if_used_symbol:\r
636         lodsd\r
637         test    eax,eax\r
638         jnz     invalid_logical_value\r
639         test    ebx,ebx\r
640         jz      evaluated_false\r
641         mov     ecx,[ebx+SymbolTree_Leaf.last_use_pass]\r
642         jecxz   symbol_predicted_unused\r
643         mov     eax,[current_pass]\r
644         sub     eax,ecx\r
645         jz      evaluated_true\r
646         cmp     eax,1\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
650         jmp     evaluated_true\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
658         lodsd\r
659         mov     ebx,eax\r
660         call    get_available_value\r
661         test    edx,edx\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