display_string_data: ; in: ; edx - 32-bit length followed by string data ; preserves: esi test [trace_mode],TRACE_DISPLAY jnz bypass_display_buffer cmp [next_pass_needed],0 jne display_ok mov ecx,[edx] call reserve_display_buffer mov ebx,esi mov esi,edx lodsd mov ecx,eax rep movsb string_displayed: mov esi,ebx display_ok: retn bypass_display_buffer: mov ebx,esi mov esi,edx lodsd mov ecx,eax jecxz string_displayed call display_string jmp string_displayed reserve_display_buffer: mov edi,[display_data_length] add ecx,edi add edi,[display_buffer] mov [display_data_length],ecx cmp ecx,[display_buffer_length] jbe display_buffer_reserve_ok mov eax,[display_buffer] sub edi,eax push edx call grow_stack pop edx add edi,eax mov [display_buffer],eax mov [display_buffer_length],ecx display_buffer_reserve_ok: retn display_single_byte_data: ; in: ; edx - 32-bit length followed by numeric data ; preserves: esi test [trace_mode],TRACE_DISPLAY jnz byte_bypassing_display_buffer cmp [next_pass_needed],0 jne display_ok mov ecx,1 call reserve_display_buffer mov ecx,1 call fit_value jc byte_out_of_range retn byte_bypassing_display_buffer: mov edi,displayed_byte mov ecx,1 call fit_value jc byte_out_of_range mov ebx,esi mov esi,edi mov ecx,1 call display_string jmp string_displayed byte_out_of_range: mov edx,_value_out_of_range call register_error retn show_display_data: test [trace_mode],TRACE_DISPLAY jnz display_line_feed mov ecx,[display_data_length] jecxz display_data_shown mov esi,[display_buffer] call display_string display_line_feed: mov esi,_new_line xor ecx,ecx call display_string display_data_shown: retn show_errors: mov esi,[first_error] display_error: test esi,esi jz display_data_shown push esi mov eax,[esi+sizeof.Error+SourceContext.number_of_entries] test eax,eax jz display_error_message lea ebx,[esi+sizeof.Error+sizeof.SourceContext] dec eax imul eax,sizeof.SourceEntry lea eax,[ebx+eax] mov [last_source_entry],eax test [trace_mode],TRACE_ERROR_STACK jnz show_source_context and [last_file_source_entry],0 find_last_file_entry: cmp [eax+SourceEntry.type],SOURCE_FILE je last_file_entry_found cmp eax,ebx je show_source_context sub eax,sizeof.SourceEntry jmp find_last_file_entry last_file_entry_found: mov [last_file_source_entry],eax show_source_context: push ebx cmp [ebx+SourceEntry.type],SOURCE_MEMORY je display_memory_source cmp [ebx+SourceEntry.type],SOURCE_MACRO jne display_source_name mov esi,_macro_source test [ebx+SourceEntry.flags],SRCF_PREPROCESSED jz display_source_type mov esi,_preprocessed_source display_source_type: xor ecx,ecx call display_error_string display_source_name: mov esi,[ebx+SourceEntry.name] test esi,esi jz unnamed_source mov ecx,[ebx+SourceEntry.name_length] cmp ecx,-1 je display_source_symbol call display_error_string jmp display_line_number display_source_symbol: xchg ebx,esi call show_symbol_name mov ebx,esi jmp display_line_number unnamed_source: mov esi,_unnamed_source xor ecx,ecx call display_error_string jmp display_line_number display_memory_source: mov esi,_memory_source xor ecx,ecx call display_error_string display_line_number: mov esi,_line_number_prefix xor ecx,ecx call display_error_string mov eax,[ebx+SourceEntry.line_number] xor edx,edx call itoa call display_error_string mov esi,_line_number_suffix xor ecx,ecx call display_error_string pop ebx mov esi,[esp] push ebx cmp [ebx+SourceEntry.line_number],0 je skip_line_content test [trace_mode],TRACE_ERROR_STACK jnz show_source_line cmp ebx,[last_source_entry] je last_source_entry_line_content cmp ebx,[last_file_source_entry] je show_source_line skip_line_content: mov esi,_space next_source_entry: pop ebx find_next_source_entry: cmp ebx,[last_source_entry] je source_context_shown add ebx,sizeof.SourceEntry test [trace_mode],TRACE_ERROR_STACK jnz show_source_entry test [ebx+SourceEntry.flags],SRCF_PREPROCESSED jnz find_next_source_entry show_source_entry: xor ecx,ecx call display_error_string jmp show_source_context last_source_entry_line_content: test [esi+Error.flags],ERR_CUSTOM jnz skip_line_content show_source_line: cmp [ebx+SourceEntry.type],SOURCE_CALM je show_calm_source mov esi,_line_content_prefix xor ecx,ecx call display_error_string call show_line_content mov esi,_new_line jmp next_source_entry show_calm_source: mov esi,_calm_source xor ecx,ecx call display_error_string mov esi,_new_line jmp next_source_entry source_context_shown: mov esi,_new_line xor ecx,ecx call display_error_string mov ebx,[esp] test [ebx+Error.flags],ERR_CUSTOM jnz display_error_message cmp [ebx+Error.preprocessed_length],0 je display_error_message mov esi,_preprocessed_text_prefix xor ecx,ecx call display_error_string mov esi,[ebx+Error.preprocessed_data] mov ecx,[ebx+Error.preprocessed_length] call show_preprocessed_line mov esi,_new_line xor ecx,ecx call display_error_string display_error_message: pop ebx call show_error_message mov esi,ebx next_error: mov esi,[esi+Error.next] jmp display_error show_error_message: ; in: ; ebx - Error ; preserves: ebx mov esi,_error_prefix test [ebx+Error.flags],ERR_CUSTOM jz display_error_prefix mov esi,_custom_error_prefix display_error_prefix: xor ecx,ecx call display_error_string mov esi,[ebx+Error.message] test [ebx+Error.flags],ERR_CUSTOM jz format_error_message xor ecx,ecx call display_error_string finish_error_message: mov esi,_message_suffix xor ecx,ecx call display_error_string retn format_error_message: mov edx,esi cut_error_message: lodsb test al,al jz show_error_message_segment cmp al,'%' jne cut_error_message show_error_message_segment: dec esi push esi xchg ecx,esi sub ecx,edx mov esi,edx call display_error_string pop esi lodsb test al,al jz finish_error_message lodsb cmp al,'s' je insert_string_into_error_message cmp al,'i' jne format_error_message push ebx mov ebx,[ebx+Error.symbol] mov ebx,[ebx+SymbolTree_Leaf.branch] call show_symbol_name pop ebx jmp format_error_message insert_string_into_error_message: push esi mov esi,[ebx+Error.symbol] xor ecx,ecx call display_error_string pop esi jmp format_error_message show_symbol_name: ; in: ; ebx - SymbolTree_Foliage, may be null ; preserves: esi test ebx,ebx jz symbol_name_shown mov edi,[identifier_workspace.memory_start] cmp [ebx+SymbolTree_Foliage.name_kind],NAME_NUMERIC je next_name_segment compose_symbol_name: mov ecx,[ebx+SymbolTree_Foliage.name_length] mov edx,identifier_workspace mov al,[ebx+SymbolTree_Foliage.name_kind] cmp al,NAME_CASESENSITIVE je name_segment_to_copy cmp al,NAME_ABSTRACT je name_segment_copied cmp al,NAME_NUMERIC je dot_label_name mov al,'?' stosb name_segment_to_copy: push ecx add ecx,2 call reserve_workspace pop ecx mov edx,[ebx+SymbolTree_Foliage.name_data] copy_name_segment: jecxz name_segment_copied dec ecx mov al,[edx+ecx] stosb jmp copy_name_segment dot_label_name: push esi mov esi,[ebx+SymbolTree_Foliage.name_data] xor eax,eax read_dot_count: jecxz dot_count_read dec ecx shl eax,8 mov al,[esi+ecx] jmp read_dot_count dot_count_read: pop esi push eax lea ecx,[eax+2] call reserve_workspace pop ecx mov al,'.' rep stosb name_segment_copied: mov edx,[ebx+SymbolTree_Foliage.root] mov ebx,[edx+SymbolTree_Root.parent_branch] test [edx+SymbolTree_Root.flags],NAMESPACE_LOCAL or NAMESPACE_CALM jnz mark_local_symbol_name test ebx,ebx jz symbol_name_ready next_name_segment: mov al,'.' stosb jmp compose_symbol_name mark_local_symbol_name: mov al,':' stosb test [edx+SymbolTree_Root.flags],NAMESPACE_CALM jz symbol_name_ready mov eax,[ebx+SymbolTree_Foliage.name_data] mov ebx,[eax+SymbolTree_Leaf.branch] test ebx,ebx jnz compose_symbol_name symbol_name_ready: mov ebx,[identifier_workspace.memory_start] mov ecx,edi sub ecx,ebx jz symbol_name_shown push esi mov esi,ebx reverse_composed_name: dec edi cmp ebx,edi jae show_composed_name mov al,[ebx] xchg al,[edi] mov [ebx],al inc ebx jmp reverse_composed_name show_composed_name: call display_error_string pop esi symbol_name_shown: retn show_line_content: ; in: ; ebx - SourceEntry cmp [ebx+SourceEntry.type],SOURCE_MACRO je show_line_from_macro mov esi,[ebx+SourceEntry.text] add esi,[ebx+SourceEntry.line_offset] mov ecx,[ebx+SourceEntry.number_of_attached_lines] inc ecx mov [number_of_lines],ecx show_token: mov al,[esi] test al,al jz line_content_shown cmp al,0Ah je line_content_shown cmp al,1Ah je show_name_token cmp al,22h je show_string_token cmp al,27h je show_string_token cmp al,'\' jne show_basic_token cmp byte [esi+1],0Ah jne show_basic_token dec [number_of_lines] jnz show_attached_line show_basic_token: mov ecx,1 call display_error_string inc esi jmp show_token show_name_token: add esi,1+4 mov ecx,[esi-4] call display_error_string add esi,[esi-4] add esi,12 jmp show_token show_string_token: mov ebx,esi inc esi call show_string_token_content lea esi,[ebx+1] lodsd add esi,eax jmp show_token show_string_token_content: lea edi,[esi+4] mov ecx,[esi] show_string_segment: push ecx edi mov esi,_single_quote mov ecx,1 call display_error_string pop edi ecx jecxz show_end_quote mov edx,ecx mov al,27h repne scasb sub edx,ecx mov esi,edi sub esi,edx push ecx edi mov ecx,edx call display_error_string pop edi ecx test ecx,ecx jnz show_string_segment show_end_quote: cmp byte [ebx],27h je string_token_shown mov esi,_single_quote mov ecx,1 call display_error_string string_token_shown: retn show_attached_line: mov ecx,1 call display_error_string lea ebx,[esi+2] mov esi,_line_segment_prefix xor ecx,ecx call display_error_string mov esi,ebx jmp show_token show_line_from_macro: mov edx,[ebx+SourceEntry.text] mov esi,[edx+ValueDefinition.value] mov ecx,[edx+ValueDefinition.value_length] mov eax,[ebx+SourceEntry.line_offset] add esi,eax sub ecx,eax jbe line_content_shown call show_preprocessed_line line_content_shown: retn show_preprocessed_line: ; in: ; esi - preprocessed tokens ; ecx = total length of preprocessed tokens lea eax,[esi+ecx] mov [preprocessed_text_end],eax show_preprocessed_token: cmp esi,[preprocessed_text_end] jae preprocessed_line_shown mov al,[esi] test al,al jz preprocessed_line_shown cmp al,1Ah je show_preprocessed_name_token cmp al,22h je show_preprocessed_string_token cmp al,27h je show_preprocessed_string_token cmp al,30h je show_internal_number cmp al,40h je show_context_token mov ecx,1 call display_error_string inc esi jmp show_preprocessed_token show_preprocessed_name_token: inc esi lodsd mov ebx,esi mov esi,eax lodsd mov ecx,eax call display_error_string mov esi,ebx jmp show_preprocessed_token show_preprocessed_string_token: mov ebx,esi mov esi,[esi+1] call show_string_token_content lea esi,[ebx+1+4] jmp show_preprocessed_token show_internal_number: inc esi mov edx,esi push esi call convert_number_back lea esi,[edx+4] mov ecx,[edx] call display_error_string pop esi add esi,[esi] add esi,4 jmp show_preprocessed_token show_context_token: add esi,1+sizeof.RecognitionContext jmp show_preprocessed_token preprocessed_line_shown: retn itoa: ; in: ; edx:eax = unsigned number ; out: ; esi - temporary buffer containing decimal digits ; ecx = length of string (number of digits) mov edi,temporary_value+4 stosd mov eax,edx stosd mov edx,temporary_value mov dword [edx],8 call convert_number_back lea esi,[edx+4] mov ecx,[edx] retn