struct CompiledMacroHeader shared_namespace dd ? literals_offset dd ? label_argument_leaf dd ? label_argument_contextless db ? reserved db ? reserved2 dw ? ends struct CompiledMacroArgument symbol_leaf dd ? contextless db ? reserved db ? reserved2 dw ? default_value_length dd ? default_value_offset dd ? ends struct UnresolvedJump offset dd ? entry_length dd ? ; source_context SourceContext ends struct MatchedExcerpt data_start dd ? data_end dd ? recognition_context dd ? symbol_leaf dd ? ends BOOL_NEG = -1 BOOL_AND = -2 BOOL_OR = -3 define_calm_instruction: mov dl,DBLOCK_CALMINSTRUCTION mov ecx,sizeof.MacroData call add_directive_block mov edx,[ebx+SymbolTree_Leaf.branch] call get_symbol_namespace mov [alm_namespace],ebx or [assembly_mode],AMODE_CALM_DEFINITION mov [calm_definition_active],0 test [assembly_mode],AMODE_SKIP jnz assembly_line test [assembly_mode],AMODE_DEFINITION jnz add_line_to_macro mov eax,[calm_code_buffer.memory_start] mov [calm_code_cursor],eax mov eax,[calm_literals_buffer.memory_start] mov [calm_literals_cursor],eax mov eax,[calm_auxiliary_buffer.memory_start] mov [calm_auxiliary_cursor],eax call move_to_next_symbol jc missing_argument cmp al,'(' je calm_labeled_instruction and [argument_start],0 mov dl,SYMCLASS_INSTRUCTION get_calm_instruction_identifier: call get_macro_definition_symbol jc invalid_identifier push esi mov eax,ebx mov ecx,[alm_namespace] call get_local_anchor call get_symbol_namespace or [ebx+SymbolTree_Root.flags],NAMESPACE_CALM mov [new_local_namespace],ebx pop esi mov edi,[calm_code_buffer.memory_start] mov [edi+CompiledMacroHeader.shared_namespace],ebx or [symbol_definition],1 mov ebx,[argument_start] test ebx,ebx jz calm_instruction_label_argument_ok push esi edi mov esi,ebx cmp byte [esi],'&' sete al mov [edi+CompiledMacroHeader.label_argument_contextless],al jne calm_instruction_label_prefix_ok inc esi calm_instruction_label_prefix_ok: mov dl,SYMCLASS_EXPRESSION mov ebx,[new_local_namespace] call identify_symbol_in_namespace mov eax,esi pop edi esi jc invalid_argument test ebx,ebx jz invalid_argument cmp byte [eax],')' jne invalid_argument call update_value_definition push esi edi mov [value_type],VALTYPE_RESERVED xor ecx,ecx call assign_value pop edi esi calm_instruction_label_argument_ok: mov [edi+CompiledMacroHeader.label_argument_leaf],ebx add edi,sizeof.CompiledMacroHeader calm_instruction_argument_declaration: call move_to_next_symbol jc calm_instruction_arguments_declared cmp al,'&' sete al mov [contextless_processing],al jne calm_instruction_argument_name inc esi calm_instruction_argument_name: mov dl,SYMCLASS_EXPRESSION push edi mov ebx,[new_local_namespace] call identify_symbol_in_namespace pop edi jc invalid_argument test ebx,ebx jz invalid_argument mov edx,calm_code_buffer mov ecx,sizeof.CompiledMacroArgument+4 call reserve_workspace mov [edi+CompiledMacroArgument.symbol_leaf],ebx mov al,[contextless_processing] mov [edi+CompiledMacroArgument.contextless],al call update_value_definition test edx,edx jz calm_instruction_argument_prepared push esi edi mov [value_type],VALTYPE_RESERVED xor ecx,ecx call assign_value pop edi esi xor edx,edx calm_instruction_argument_prepared: call move_to_next_symbol jc calm_instruction_argument_ready cmp al,':' je calm_instruction_argument_default_value cmp al,'=' je calm_instruction_argument_default_value cmp al,'*' jne calm_instruction_argument_ready dec edx inc esi calm_instruction_argument_ready: mov [edi+CompiledMacroArgument.default_value_length],edx add edi,sizeof.CompiledMacroArgument call move_to_next_symbol jc calm_instruction_arguments_declared inc esi cmp al,'&' je calm_instruction_greedy_argument cmp al,',' jne invalid_argument call move_to_next_symbol jc invalid_argument jmp calm_instruction_argument_declaration calm_instruction_argument_default_value: inc esi mov [calm_code_cursor],edi mov edx,calm_literals_buffer mov edi,[calm_literals_cursor] mov ecx,[line_end] sub ecx,esi add ecx,1+sizeof.RecognitionContext call reserve_workspace mov [calm_literals_cursor],edi call move_to_next_symbol jc calm_plain_default_value cmp al,'<' je calm_enclosed_default_value calm_plain_default_value: mov dl,',' xor dh,dh mov [breakpoint_token],'&' call extract_piece_of_line jmp calm_default_value_ready calm_enclosed_default_value: inc esi mov dl,'>' mov dh,'<' mov [breakpoint_token],0 call extract_piece_of_line cmp al,'>' jne invalid_argument inc esi calm_default_value_ready: mov edx,edi xchg edi,[calm_literals_cursor] mov eax,edi sub edx,edi sub eax,[calm_literals_buffer.memory_start] mov edi,[calm_code_cursor] mov [edi+CompiledMacroArgument.default_value_offset],eax jmp calm_instruction_argument_ready calm_instruction_greedy_argument: assert CompiledMacroArgument.symbol_leaf = 0 or eax,-1 stosd jmp call_instruction_begin_code calm_labeled_instruction: inc esi call move_to_next_symbol jc missing_argument mov [argument_start],esi mov edi,[expression_workspace.memory_start] mov dl,')' xor dh,dh mov [breakpoint_token],dh call cut_piece_of_line cmp al,')' jne invalid_argument inc esi mov dl,SYMCLASS_STRUCTURE jmp get_calm_instruction_identifier calm_instruction_arguments_declared: assert CompiledMacroArgument.symbol_leaf = 0 xor eax,eax stosd call_instruction_begin_code: mov [calm_code_cursor],edi mov eax,[new_local_namespace] mov [current_context.base_namespace],eax and [calm_line_number],0 mov [calm_definition_active],1 jmp instruction_assembled assemble_alm_instruction: or [alm_statement],1 mov ebx,[source_context] mov eax,[ebx+SourceContext.number_of_entries] dec eax imul eax,sizeof.SourceEntry test [ebx+sizeof.SourceContext+eax+SourceEntry.flags],SRCF_ALM_STATEMENT jnz identify_alm_instruction inc [calm_line_number] identify_alm_instruction: call move_to_next_symbol jc empty_line call get_alm_identifier jc unrecognized_alm_instruction mov dl,SYMCLASS_INSTRUCTION call identify_alm_symbol jc alm_label call get_available_value jc alm_label test [edx+ValueDefinition.flags],VAL_UNCONDITIONAL jnz execute_alm_instruction test [assembly_mode],AMODE_SKIP jnz assembly_line test [assembly_mode],AMODE_DEFINITION jnz add_line_to_macro execute_alm_instruction: cmp [edx+ValueDefinition.type],VALTYPE_CALM je launch_calm cmp [edx+ValueDefinition.type],VALTYPE_SYMBOLIC je use_macro cmp [edx+ValueDefinition.type],VALTYPE_NATIVE_COMMAND jne unrecognized_alm_instruction jmp [edx+ValueDefinition.value] alm_label: call move_to_next_symbol jc unrecognized_alm_instruction cmp al,':' jne unrecognized_alm_instruction inc esi test [assembly_mode],AMODE_SKIP jnz identify_alm_instruction test [assembly_mode],AMODE_DEFINITION jnz add_label_to_macro call identify_calm_location jc unrecognized_alm_instruction call create_constant_value_definition test edx,edx jz assembly_line mov [edx+ValueDefinition.type],VALTYPE_PLAIN mov eax,[calm_code_cursor] sub eax,[calm_code_buffer.memory_start] mov [edx+ValueDefinition.value],eax mov eax,[current_pass] mov [edx+ValueDefinition.pass],eax jmp identify_alm_instruction unrecognized_alm_instruction: test [assembly_mode],AMODE_SKIP jnz assembly_line test [assembly_mode],AMODE_DEFINITION jnz add_line_to_macro mov edx,_unexpected_instruction call register_error jmp assembly_line get_alm_identifier: xor ecx,ecx call move_to_next_symbol jc malformed_alm_identifier cmp al,1Ah je alm_plain_name cmp al,30h je alm_numeric_name cmp al,'#' jne malformed_alm_identifier call check_concatenation jnc get_alm_identifier malformed_alm_identifier: stc retn alm_plain_name: inc esi lodsd mov ebx,eax mov ecx,[ebx] mov eax,[ebx+4+ecx] mov [case_sensitive_hash],eax mov eax,[ebx+4+ecx+4] mov [case_insensitive_hash],eax alm_check_for_concatenation: xor ecx,ecx call move_to_next_symbol jc alm_identifier_ok cmp al,'#' jne alm_identifier_ok call check_concatenation jc alm_identifier_ok call move_to_next_symbol jc alm_identifier_ok cmp al,1Ah je alm_concatenation cmp al,30h je alm_concatenation alm_identifier_ok: mov [symbol_data],ebx cmp ebx,[assembly_workspace.memory_start] je alm_identifier_volatile mov [name_volatile],0 clc retn alm_identifier_volatile: sub edi,ebx sub edi,4 mov [ebx],edi mov [name_volatile],1 clc retn alm_concatenation: mov edx,assembly_workspace cmp ebx,[edx+Workspace.memory_start] je alm_name_segment mov edi,[edx+Workspace.memory_start] add edi,4 mov ecx,[ebx] call reserve_workspace xchg ebx,esi lodsd mov ecx,eax rep movsb mov esi,ebx mov ebx,[edx+Workspace.memory_start] alm_name_segment: lodsb cmp al,30h je alm_attach_numeric_segment lodsd push ebx esi alm_append_name: mov esi,eax mov ecx,[esi] mov edx,assembly_workspace call reserve_workspace lodsd lea ebx,[esi+eax] mov ecx,[case_sensitive_hash] mov edx,[case_insensitive_hash] xor eax,eax alm_name_hash: lodsb xor cl,al xor dl,[characters+eax] imul ecx,FNV_PRIME imul edx,FNV_PRIME stosb cmp esi,ebx jne alm_name_hash mov [case_sensitive_hash],ecx mov [case_insensitive_hash],edx pop esi ebx jmp alm_check_for_concatenation alm_numeric_name: inc esi mov ebx,[assembly_workspace.memory_start] lea edi,[ebx+4] mov eax,FNV_OFFSET mov [case_sensitive_hash],eax mov [case_insensitive_hash],eax alm_attach_numeric_segment: mov edx,esi mov ecx,[edx] lea esi,[esi+4+ecx] push ebx esi push edi call convert_number_back pop edi mov eax,edx jmp alm_append_name identify_alm_symbol: mov [symbol_class],dl push esi mov esi,[symbol_data] lodsd mov ecx,eax mov edx,[case_insensitive_hash] mov ebx,[alm_namespace] mov [name_kind],NAME_CASEINSENSITIVE and [name_token],0 and [symbol_required],0 and [symbol_expected],0 call scan_namespace pop esi retn identify_calm_location: mov [symbol_class],SYMCLASS_CALM_LOCATION push esi mov esi,[symbol_data] lodsd mov ecx,eax mov edx,[case_sensitive_hash] mov ebx,[current_context.base_namespace] and [name_kind],0 and [name_token],0 or [symbol_required],1 or [symbol_expected],1 call scan_namespace pop esi retn alm_jyes: mov [value],calm_jyes jmp assemble_alm_jump alm_jno: mov [value],calm_jno jmp assemble_alm_jump alm_jump: mov [value],calm_jump assemble_alm_jump: test [assembly_mode],AMODE_CALM_DEFINITION jz unexpected_instruction call move_to_next_symbol jc missing_argument call get_alm_identifier jc invalid_argument call identify_calm_location jc invalid_argument mov edx,[ebx+SymbolTree_Leaf.definition] test edx,edx jz alm_unresolved_jump mov eax,[edx+ValueDefinition.pass] cmp eax,[current_pass] jne alm_unresolved_jump mov ebx,[edx+ValueDefinition.value] emit_calm_jump: mov edi,[calm_code_cursor] mov edx,calm_code_buffer mov ecx,8+4 call reserve_workspace mov eax,[calm_line_number] stosd mov eax,[value] stosd mov eax,ebx stosd mov [calm_code_cursor],edi jmp instruction_assembled alm_unresolved_jump: push esi mov edx,calm_auxiliary_buffer mov edi,[calm_auxiliary_cursor] mov esi,[source_context] mov ecx,[esi+SourceContext.number_of_entries] imul ecx,sizeof.SourceEntry add ecx,sizeof.SourceContext add ecx,sizeof.UnresolvedJump call reserve_workspace mov [calm_auxiliary_cursor],edi mov eax,[calm_code_cursor] add eax,8 sub eax,[calm_code_buffer.memory_start] mov [edi+UnresolvedJump.offset],eax add edi,sizeof.UnresolvedJump call clone_source_context mov ecx,edi xchg edi,[calm_auxiliary_cursor] sub ecx,edi mov [edi+UnresolvedJump.entry_length],ecx pop esi jmp emit_calm_jump alm_end: test [assembly_mode],AMODE_CALM_DEFINITION jz unexpected_unconditional_alm_instruction call move_to_next_symbol jc finish_calm_definition call get_alm_identifier jc invalid_argument mov dl,SYMCLASS_STRUCTURE call identify_alm_symbol jc invalid_argument mov edx,[ebx+SymbolTree_Leaf.definition] cmp [edx+ValueDefinition.type],VALTYPE_NATIVE_COMMAND jne invalid_argument cmp [edx+ValueDefinition.value],alm_end jne invalid_argument finish_calm_definition: mov dl,DBLOCK_CALMINSTRUCTION call find_directive_block jc unexpected_unconditional_alm_instruction call close_directive_block and [assembly_mode],not AMODE_CALM_DEFINITION test [assembly_mode],AMODE_DEFINITION jnz add_line_to_macro cmp [calm_definition_active],0 je instruction_assembled push esi mov esi,[calm_auxiliary_buffer.memory_start] resolve_calm_jumps: cmp esi,[calm_auxiliary_cursor] je calm_jumps_resolved mov eax,[esi+UnresolvedJump.offset] add eax,[calm_code_buffer.memory_start] mov ebx,[eax] mov edx,[ebx+SymbolTree_Leaf.definition] test edx,edx jz unresolvable_calm_jump mov ecx,[edx+ValueDefinition.pass] cmp ecx,[current_pass] jne unresolvable_calm_jump mov ebx,[edx+ValueDefinition.value] mov [eax],ebx resolve_next_calm_jump: add esi,[esi+UnresolvedJump.entry_length] jmp resolve_calm_jumps unresolvable_calm_jump: mov edx,[calm_code_cursor] sub edx,[calm_code_buffer.memory_start] mov [eax],edx add esi,sizeof.UnresolvedJump mov edx,_undefined_jump_target call register_delayed_error sub esi,sizeof.UnresolvedJump jmp resolve_next_calm_jump calm_jumps_resolved: mov ebx,[current_context.base_namespace] mov edx,[ebx+SymbolTree_Root.parent_branch] mov eax,[edx+SymbolTree_Foliage.root] mov [current_context.base_namespace],eax mov edi,[calm_code_cursor] mov edx,calm_code_buffer mov ecx,[calm_literals_cursor] mov esi,[calm_literals_buffer.memory_start] sub ecx,esi add ecx,8 call reserve_workspace mov eax,[calm_line_number] stosd mov eax,calm_end stosd mov ebx,[calm_code_buffer.memory_start] mov eax,edi sub eax,ebx mov [ebx+CompiledMacroHeader.literals_offset],eax mov ecx,[calm_literals_cursor] sub ecx,esi rep movsb mov ebx,[macro_leaf] test ebx,ebx jz calm_definition_done call create_value_definition test edx,edx jz calm_definition_done mov esi,[calm_code_buffer.memory_start] mov ecx,edi sub ecx,esi mov [value_type],VALTYPE_CALM call assign_value mov al,[macro_flags] or [edx+ValueDefinition.flags],al calm_definition_done: pop esi jmp instruction_assembled unexpected_unconditional_alm_instruction: test [assembly_mode],AMODE_SKIP jnz assembly_line test [assembly_mode],AMODE_DEFINITION jnz add_line_to_macro jmp unexpected_instruction alm_local: test [assembly_mode],AMODE_CALM_DEFINITION jz unexpected_instruction call move_to_next_symbol jc missing_argument or [symbol_definition],1 mov dl,SYMCLASS_EXPRESSION mov ebx,[current_context.base_namespace] call identify_symbol_in_namespace jc invalid_argument test ebx,ebx jz invalid_argument call update_value_definition test edx,edx jz alm_next_local push esi mov [value_type],VALTYPE_RESERVED xor ecx,ecx call assign_value pop esi alm_next_local: call move_to_next_symbol jc instruction_assembled cmp al,',' jne invalid_argument inc esi jmp alm_local alm_assemble: mov [value],calm_assemble jmp assemble_alm_operation_on_variable alm_stringify: mov [value],calm_stringify assemble_alm_operation_on_variable: test [assembly_mode],AMODE_CALM_DEFINITION jz unexpected_instruction and [symbol_definition],0 mov dl,SYMCLASS_EXPRESSION call identify_symbol jc invalid_identifier test ebx,ebx jz invalid_identifier mov edi,[calm_code_cursor] mov edx,calm_code_buffer mov ecx,8+4 call reserve_workspace mov eax,[calm_line_number] stosd mov eax,[value] stosd mov eax,ebx stosd mov [calm_code_cursor],edi jmp instruction_assembled alm_arrange: test [assembly_mode],AMODE_CALM_DEFINITION jz unexpected_instruction and [symbol_definition],0 mov dl,SYMCLASS_EXPRESSION call identify_symbol jc invalid_identifier test ebx,ebx jz invalid_identifier call move_to_next_symbol jc missing_argument cmp al,',' jne instruction_assembled inc esi call move_to_next_symbol mov edi,[calm_code_cursor] mov edx,calm_code_buffer mov ecx,8+12 call reserve_workspace mov eax,[calm_line_number] stosd mov eax,calm_arrange stosd mov eax,ebx stosd mov edx,calm_literals_buffer mov ebx,[calm_literals_cursor] mov eax,ebx sub eax,[edx+Workspace.memory_start] stosd mov [calm_code_cursor],edi mov edi,ebx mov ecx,[line_end] sub ecx,esi shl ecx,1 call reserve_workspace mov [breakpoint_token],0 call parse_pattern mov [calm_literals_cursor],edi mov eax,edi mov edi,[calm_code_cursor] sub eax,[calm_literals_buffer.memory_start] stosd mov [calm_code_cursor],edi jmp instruction_assembled parse_pattern: ; in: ; esi - first token of the pattern in the preprocessed line ; edi - buffer with enough space to hold twice the length of the preprocessed text left in line ; [breakpoint_token] = initial byte of symbol that should end the pattern ; out: ; esi - after the processed portion of line (might be at [line_end]) ; edi - in the buffer after the stored pattern cmp esi,[line_end] je pattern_parsed lodsb token_available: cmp al,[breakpoint_token] je pattern_breakpoint token_in_pattern: cmp al,'=' je parse_pattern_literal cmp al,1Ah je parse_reference_in_pattern cmp al,40h je ignore_context_in_pattern cmp al,20h je whitespace_in_pattern stosb literal_token_in_pattern: cmp al,22h je copy_pattern_data cmp al,27h je copy_pattern_data cmp al,30h jne parse_pattern lodsd mov ecx,eax stosd rep movsb jmp parse_pattern whitespace_in_pattern: cmp esi,[line_end] je pattern_parsed lodsb cmp al,20h je whitespace_in_pattern cmp al,[breakpoint_token] je pattern_breakpoint cmp al,40h jne store_whitespace_in_pattern call pass_context jmp whitespace_in_pattern store_whitespace_in_pattern: mov byte [edi],20h inc edi jmp token_in_pattern pattern_breakpoint: dec esi pattern_parsed: retn pass_context: mov eax,esi add esi,sizeof.RecognitionContext cmp dword [eax],0 je zero_context mov [embedded_context],eax retn zero_context: and [embedded_context],0 retn copy_pattern_data: movsd jmp parse_pattern ignore_context_in_pattern: call pass_context jmp parse_pattern ignore_context_in_pattern_literal: call pass_context parse_pattern_literal: cmp esi,[line_end] je error_in_parsed_pattern lodsb cmp al,40h je ignore_context_in_pattern_literal cmp al,20h je parse_hard_space_in_pattern stosb cmp al,1Ah jne literal_token_in_pattern movsd jmp parsed_name_in_pattern parse_hard_space_in_pattern: mov al,0A0h stosb jmp parse_pattern parse_reference_in_pattern: dec esi call detect_numeric_symbol jc numeric_name_in_pattern inc esi mov [name_token],esi lodsd mov dx,SYMCLASS_EXPRESSION mov [name_volatile],0 push esi edi mov esi,eax lodsd mov ecx,eax xor ebx,ebx mov eax,[embedded_context] test eax,eax jz use_current_namespace_in_pattern mov eax,[eax+RecognitionContext.base_namespace] jmp namespace_in_pattern_ok use_current_namespace_in_pattern: mov eax,[current_context.base_namespace] namespace_in_pattern_ok: mov [recognition_context.base_namespace],eax call recognize_symbol pop edi esi mov al,1Bh stosb mov eax,[name_token] mov eax,[eax] stosd mov eax,ebx stosd parsed_name_in_pattern: cmp esi,[line_end] je pattern_parsed lodsb cmp al,40h je ignore_context_after_name_in_pattern cmp al,'?' jne token_available mov al,0BFh stosb jmp parse_pattern ignore_context_after_name_in_pattern: call pass_context jmp parsed_name_in_pattern numeric_name_in_pattern: movsb movsd jmp parsed_name_in_pattern error_in_parsed_pattern: mov edx,_invalid_argument call register_error jmp parse_pattern alm_match: test [assembly_mode],AMODE_CALM_DEFINITION jz unexpected_instruction call move_to_next_symbol jc missing_argument mov edx,calm_literals_buffer mov edi,[calm_literals_cursor] mov ecx,[line_end] sub ecx,esi shl ecx,1 call reserve_workspace mov [calm_literals_cursor],edi mov [breakpoint_token],',' call parse_pattern xchg edi,[calm_literals_cursor] mov [pattern_start],edi cmp esi,[line_end] je missing_argument lodsb cmp al,',' jne invalid_argument and [symbol_definition],0 mov dl,SYMCLASS_EXPRESSION call identify_symbol jc invalid_identifier test ebx,ebx jz invalid_identifier and [brackets],0 call move_to_next_symbol jc no_brackets cmp al,',' jne no_brackets inc esi call move_to_next_symbol jc invalid_argument mov dl,al lea edi,[esi+1] call skip_token cmp esi,edi jne invalid_argument call move_to_next_symbol jc invalid_argument mov dh,al lea edi,[esi+1] call skip_token cmp esi,edi jne invalid_argument mov word [brackets],dx no_brackets: mov edi,[calm_code_cursor] mov edx,calm_code_buffer mov ecx,8+16 call reserve_workspace mov eax,[calm_line_number] stosd mov eax,calm_match stosd mov eax,ebx stosd mov ebx,[calm_literals_buffer.memory_start] mov eax,[pattern_start] sub eax,ebx stosd mov eax,[calm_literals_cursor] sub eax,ebx stosd mov eax,[brackets] stosd mov [calm_code_cursor],edi jmp instruction_assembled alm_compute: test [assembly_mode],AMODE_CALM_DEFINITION jz unexpected_instruction and [symbol_definition],0 mov dl,SYMCLASS_EXPRESSION call identify_symbol jc invalid_identifier test ebx,ebx jz invalid_identifier call move_to_next_symbol jc missing_argument cmp al,',' jne instruction_assembled inc esi call move_to_next_symbol mov edi,[calm_code_cursor] mov edx,calm_code_buffer mov ecx,8+8 call reserve_workspace mov eax,[calm_line_number] stosd mov eax,calm_compute stosd mov eax,ebx stosd call compile_expression jnc instruction_assembled sub [calm_code_cursor],8+8 jmp instruction_assembled compile_expression: xor eax,eax stosd mov [calm_code_cursor],edi mov edi,[expression_workspace.memory_start] and [leave_opening_parentheses],0 or [use_raw_values],1 call parse_expression and [use_raw_values],0 push esi mov esi,[expression_workspace.memory_start] mov ecx,edi sub ecx,esi add ecx,4 mov edi,[calm_code_cursor] mov edx,calm_code_buffer call reserve_workspace mov [calm_code_cursor],edi call convert_parsed_expression pop esi jc no_computable_expression mov ecx,edi xchg edi,[calm_code_cursor] sub ecx,edi mov [edi-4],ecx ; clc retn no_computable_expression: retn convert_parsed_expression: xor ebx,ebx xor ecx,ecx xor dl,dl mov [subexpression_end],esi scan_reducible_subexpression: mov eax,[esi+ebx] test eax,eax jz end_subexpression cmp al,EXPR_OPERATOR je scan_operator cmp al,EXPR_SYMBOL_VALUE je scan_parsed_symbol cmp al,EXPR_NUMBER je scan_parsed_value cmp al,EXPR_STRING je scan_parsed_value cmp al,EXPR_FLOAT je scan_parsed_value jmp end_subexpression scan_parsed_value: add ebx,8 inc ecx jmp scan_reducible_subexpression scan_parsed_symbol: mov eax,[esi+ebx+4] test eax,eax jz end_subexpression test [eax+SymbolTree_Leaf.flags],SYM_CONSTANT jz end_subexpression mov eax,[esi+ebx+8] test eax,eax jz end_subexpression cmp [eax+ValueDefinition.type],VALTYPE_SYMBOLIC je end_subexpression add ebx,12 inc ecx jmp scan_reducible_subexpression scan_operator: test eax,EXPRF_OPERATOR_UNARY setz al movzx eax,al cmp ecx,eax jbe end_subexpression sub ecx,eax add ebx,8 or dl,1 jmp scan_reducible_subexpression end_subexpression: add ebx,esi mov [subexpression_end],ebx test dl,dl jz convert_irreducible_expression cmp ecx,1 jne convert_irreducible_expression push edi xor eax,eax xchg eax,[ebx] push eax mov edi,[calculation_workspace.memory_start] call calculate_parsed_expression mov esi,[subexpression_end] pop dword [esi] call pop_terms mov ebx,edi pop edi jc convert_irreducible_expression cmp [ebx+sizeof.ExpressionTerm+ExpressionTerm.attributes],0 jne embed_numeric_value mov eax,[ebx+ExpressionTerm.attributes] mov ebx,[ebx+ExpressionTerm.value] jmp copy_expression_literal embed_numeric_value: push edi mov edi,ebx call convert_terms_to_numeric_value pop edi mov ebx,esi mov esi,[subexpression_end] mov eax,EXPR_POLYNOMIAL + EXPRF_CALM_LITERAL jmp parsed_value_length_ok convert_irreducible_expression: lodsd test eax,eax jz parsed_expression_converted cmp al,EXPR_SYMBOL_VALUE je copy_parsed_symbol cmp al,EXPR_OPERATOR je copy_parsed_operator cmp al,EXPR_NUMBER je copy_parsed_value cmp al,EXPR_STRING je copy_parsed_value cmp al,EXPR_FLOAT je copy_parsed_value cmp al,EXPR_MISSING_PARENTHESIS je expression_missing_parenthesis jmp invalid_expression copy_parsed_value: mov ebx,[esi] add esi,4 copy_expression_literal: or eax,EXPRF_CALM_LITERAL test eax,EXPRF_VALUE_IN_WORKSPACE jnz parsed_value_in_workspace test ebx,ebx jnz parsed_value_pointer_ok jmp invalid_expression parsed_value_in_workspace: add ebx,[value_workspace.memory_start] and eax,not EXPRF_VALUE_IN_WORKSPACE parsed_value_pointer_ok: cmp al,EXPR_FLOAT je parsed_float_to_copy mov ecx,[ebx] add ecx,4 jmp parsed_value_length_ok parsed_float_to_copy: mov ecx,sizeof.FloatData parsed_value_length_ok: stosd mov edx,[calm_literals_cursor] mov eax,edx sub eax,[calm_literals_buffer.memory_start] stosd push edi push ecx mov edi,edx mov edx,calm_literals_buffer call reserve_workspace pop ecx xchg esi,ebx rep movsb mov [calm_literals_cursor],edi mov esi,ebx pop edi parsed_item_converted: cmp esi,[subexpression_end] jbe convert_irreducible_expression jmp convert_parsed_expression copy_parsed_symbol: mov al,EXPR_SYMBOL stosd lodsd test eax,eax jz invalid_expression stosd add esi,4 jmp parsed_item_converted copy_parsed_operator: stosd movsd jmp parsed_item_converted parsed_expression_converted: stosd clc retn alm_check: test [assembly_mode],AMODE_CALM_DEFINITION jz unexpected_instruction mov edi,[calm_code_cursor] mov edx,calm_code_buffer mov eax,edi sub eax,[edx+Workspace.memory_start] mov [calm_rollback_offset],eax mov ecx,8 call reserve_workspace mov eax,[calm_line_number] stosd mov eax,calm_check stosd mov [calm_code_cursor],edi or [use_raw_values],1 mov ebx,[condition_stack_base] and dword [ebx],0 add ebx,4 mov [condition_stack],ebx parse_alm_condition: call peek_at_constituent_value jc calm_condition_parsed cmp al,'~' jne parse_alm_logical_value and [current_constituent],0 mov ecx,BOOL_NEG call push_to_condition_stack jmp parse_alm_condition alm_logical_value_empty: test ecx,ecx jz calm_condition_parsed call push_to_condition_stack jmp parse_alm_condition parse_alm_logical_value: call parse_logical_value jc alm_logical_value_empty jecxz convert_logical_value call push_to_condition_stack convert_logical_value: mov [calm_source_pointer],esi mov esi,[expression_workspace.memory_start] mov ecx,edi sub ecx,esi add ecx,8 add ecx,[condition_stack] sub ecx,[condition_stack_base] mov edi,[calm_code_cursor] mov edx,calm_code_buffer call reserve_workspace xor eax,eax stosd mov [calm_code_cursor],edi mov eax,[comparator] stosd mov eax,[expression_end] convert_argument_sequences: push eax call convert_parsed_expression pop eax jc condition_malformed cmp esi,eax jb convert_argument_sequences mov ecx,edi xchg edi,[calm_code_cursor] sub ecx,edi mov [edi-4],ecx mov esi,[calm_source_pointer] parse_alm_logical_operator: call get_constituent_value jc calm_condition_parsed cmp al,')' je close_subconditions cmp al,'|' je parse_or cmp al,'&' jne condition_malformed parse_and: mov ecx,BOOL_AND jmp prepare_stack_for_logical_operator parse_or: mov ecx,BOOL_OR prepare_stack_for_logical_operator: mov ebx,[condition_stack] sub ebx,4 cmp dword [ebx],0 jge push_logical_operator mov [condition_stack],ebx mov edi,[calm_code_cursor] mov eax,[ebx] stosd mov [calm_code_cursor],edi jmp prepare_stack_for_logical_operator push_logical_operator: call push_to_condition_stack jmp parse_alm_condition close_subconditions: mov ebx,[condition_stack] sub ebx,4 cmp dword [ebx],0 jl store_logical_operator je condition_malformed dec dword [ebx] jnz parse_alm_logical_operator mov [condition_stack],ebx jmp parse_alm_logical_operator store_logical_operator: mov edi,[calm_code_cursor] mov eax,[ebx] mov [condition_stack],ebx stosd mov [calm_code_cursor],edi jmp close_subconditions push_to_condition_stack: mov ebx,[condition_stack] mov [ebx],ecx add ebx,4 cmp [condition_stack_end],ebx je grow_condition_stack mov [condition_stack],ebx retn grow_condition_stack: mov eax,[condition_stack_base] sub ebx,eax lea ecx,[ebx+4] call grow_stack mov [condition_stack_base],eax add ebx,eax mov [condition_stack],ebx add ecx,eax mov [condition_stack_end],ecx retn calm_condition_parsed: mov edi,[calm_code_cursor] mov ebx,[condition_stack] mov ecx,ebx sub ecx,[condition_stack_base] mov edx,calm_code_buffer call reserve_workspace finish_calm_condition: sub ebx,4 mov eax,[ebx] cmp eax,0 jg condition_malformed stosd jne finish_calm_condition mov [calm_code_cursor],edi and [use_raw_values],0 jmp instruction_assembled condition_malformed: and [use_raw_values],0 mov edx,_invalid_expression alm_abort: call register_error mov eax,[calm_rollback_offset] add eax,[calm_code_buffer.memory_start] mov [calm_code_cursor],eax jmp assembly_line alm_publish: test [assembly_mode],AMODE_CALM_DEFINITION jz unexpected_instruction mov [value],calm_publish_variable call move_to_next_symbol jc missing_argument cmp al,':' jne get_identifier_variable inc esi mov [value],calm_publish_stack get_identifier_variable: and [symbol_definition],0 mov dl,SYMCLASS_EXPRESSION call identify_symbol jc invalid_identifier test ebx,ebx jz invalid_identifier mov [label_leaf],ebx call move_to_next_symbol jc missing_argument cmp al,':' jne get_value_variable mov eax,calm_publish_constant xchg [value],eax cmp eax,calm_publish_variable jne invalid_argument inc esi call move_to_next_symbol jc missing_argument get_value_variable: cmp al,',' jne missing_argument inc esi mov dl,SYMCLASS_EXPRESSION call identify_symbol jc invalid_identifier test ebx,ebx jz invalid_identifier mov edi,[calm_code_cursor] mov edx,calm_code_buffer mov ecx,8+8 call reserve_workspace mov eax,[calm_line_number] stosd mov eax,[value] stosd mov eax,[label_leaf] stosd mov eax,ebx stosd mov [calm_code_cursor],edi jmp instruction_assembled alm_transform: test [assembly_mode],AMODE_CALM_DEFINITION jz unexpected_instruction call move_to_next_symbol jc missing_argument and [symbol_definition],0 mov dl,SYMCLASS_EXPRESSION call identify_symbol jc invalid_identifier test ebx,ebx jz invalid_identifier mov [label_leaf],ebx xor ebx,ebx call move_to_next_symbol jc alm_transform_arguments_ready cmp al,',' jne alm_transform_arguments_ready inc esi mov dl,SYMCLASS_EXPRESSION call identify_symbol jc invalid_identifier test edx,edx jz invalid_identifier call get_symbol_namespace alm_transform_arguments_ready: mov edi,[calm_code_cursor] mov edx,calm_code_buffer mov ecx,8+8 call reserve_workspace mov eax,[calm_line_number] stosd mov eax,calm_transform stosd mov eax,[label_leaf] stosd mov eax,ebx stosd mov [calm_code_cursor],edi jmp instruction_assembled alm_take: test [assembly_mode],AMODE_CALM_DEFINITION jz unexpected_instruction call move_to_next_symbol jc missing_argument xor ebx,ebx and [symbol_definition],0 cmp al,',' je alm_take_destination_ready mov dl,SYMCLASS_EXPRESSION call identify_symbol jc invalid_identifier test ebx,ebx jz invalid_identifier call move_to_next_symbol jc missing_argument cmp al,',' jne missing_argument alm_take_destination_ready: mov [label_leaf],ebx inc esi mov dl,SYMCLASS_EXPRESSION call identify_symbol jc invalid_identifier test ebx,ebx jz invalid_identifier mov edi,[calm_code_cursor] mov edx,calm_code_buffer mov ecx,8+8 call reserve_workspace mov eax,[calm_line_number] stosd mov eax,calm_take stosd mov eax,[label_leaf] stosd mov eax,ebx stosd mov [calm_code_cursor],edi jmp instruction_assembled alm_err: mov [value],calm_err jmp assemble_alm_operation_on_expression alm_display: mov [value],calm_display assemble_alm_operation_on_expression: test [assembly_mode],AMODE_CALM_DEFINITION jz unexpected_instruction mov edi,[calm_code_cursor] mov edx,calm_code_buffer mov ecx,8+4 call reserve_workspace mov eax,[calm_line_number] stosd mov eax,[value] stosd call compile_expression jmp instruction_assembled alm_emit: test [assembly_mode],AMODE_CALM_DEFINITION jz unexpected_instruction mov edi,[calm_code_cursor] mov edx,calm_code_buffer mov ecx,8+4 call reserve_workspace mov eax,[calm_line_number] stosd mov eax,calm_emit stosd call compile_expression mov edi,[calm_code_cursor] call peek_at_constituent_value jc alm_call_arguments_ready cmp al,',' jne alm_call_arguments_ready and [current_constituent],0 call compile_expression jmp instruction_assembled alm_load: test [assembly_mode],AMODE_CALM_DEFINITION jz unexpected_instruction and [symbol_definition],0 mov dl,SYMCLASS_EXPRESSION call identify_symbol jc invalid_identifier test ebx,ebx jz invalid_identifier mov edi,[calm_code_cursor] mov edx,calm_code_buffer mov eax,edi sub eax,[edx+Workspace.memory_start] mov [calm_rollback_offset],eax mov ecx,12+4 call reserve_workspace mov eax,[calm_line_number] stosd mov eax,calm_load stosd mov eax,ebx stosd call move_to_next_symbol jc alm_missing_argument cmp al,',' jne alm_malformed_argument inc esi call move_to_next_symbol call compile_expression push ecx call get_constituent_value pop ecx jc alm_missing_argument cmp al,':' je alm_load_offset cmp al,',' jne alm_malformed_argument mov edi,[calm_rollback_offset] add edi,[calm_code_buffer.memory_start] mov dword [edi+4],calm_load_from_output jmp alm_load_length alm_load_offset: mov edi,[calm_code_cursor] call compile_expression call get_constituent_value jc alm_missing_argument cmp al,',' jne alm_malformed_argument alm_load_length: mov edi,[calm_code_cursor] call compile_expression jmp instruction_assembled alm_missing_argument: mov edx,_missing_argument jmp alm_abort alm_malformed_argument: mov edx,_invalid_argument jmp alm_abort alm_store: test [assembly_mode],AMODE_CALM_DEFINITION jz unexpected_instruction mov edi,[calm_code_cursor] mov edx,calm_code_buffer mov eax,edi sub eax,[edx+Workspace.memory_start] mov [calm_rollback_offset],eax mov ecx,8+4 call reserve_workspace mov eax,[calm_line_number] stosd mov eax,calm_store stosd call compile_expression call get_constituent_value jc alm_missing_argument cmp al,':' je alm_store_offset cmp al,',' jne alm_malformed_argument mov edi,[calm_rollback_offset] add edi,[calm_code_buffer.memory_start] mov dword [edi+4],calm_store_in_output jmp alm_store_length alm_store_offset: mov edi,[calm_code_cursor] call compile_expression call get_constituent_value jc alm_missing_argument cmp al,',' jne alm_malformed_argument alm_store_length: mov edi,[calm_code_cursor] call compile_expression call get_constituent_value jc alm_missing_argument cmp al,',' jne alm_malformed_argument mov edi,[calm_code_cursor] call compile_expression jmp instruction_assembled alm_call: test [assembly_mode],AMODE_CALM_DEFINITION jz unexpected_instruction and [symbol_definition],0 mov edx,[embedded_context] mov [line_context],edx test edx,edx jnz alm_call_context_adjust mov edx,current_context alm_call_context_adjust: mov ebx,[edx+RecognitionContext.base_namespace] test [ebx+SymbolTree_Root.flags],NAMESPACE_CALM jz alm_call_context_ready mov eax,[ebx+SymbolTree_Root.parent_branch] test eax,eax jz alm_call_context_ready mov ebx,[eax+SymbolTree_Foliage.root] mov eax,alm_adjusted_context mov [eax+RecognitionContext.base_namespace],ebx mov ecx,[edx+RecognitionContext.base_label] mov [eax+RecognitionContext.base_label],ecx mov [embedded_context],eax alm_call_context_ready: mov dl,SYMCLASS_INSTRUCTION call identify_symbol jc invalid_identifier test ebx,ebx jz invalid_identifier cmp [ebx+SymbolTree_Leaf.class],SYMCLASS_INSTRUCTION je alm_call_instruction_ok mov ebx,edx mov [symbol_class],SYMCLASS_INSTRUCTION or [symbol_required],1 or [symbol_expected],1 call scan_symbol_branch jc invalid_identifier mov edi,ebx mark_instruction_fallbacks: mov edx,[edi+SymbolTree_Leaf.fallback_neighbour] test edx,edx jz instruction_fallback_neighbour_ok or [edx+SymbolTree_Leaf.extra_flags],SYMX_INSTRUCTION_PREDICTED instruction_fallback_neighbour_ok: mov edi,[edi+SymbolTree_Leaf.fallback_parent] test edi,edi jz alm_call_instruction_ok or [edi+SymbolTree_Leaf.extra_flags],SYMX_INSTRUCTION_PREDICTED jmp mark_instruction_fallbacks alm_call_instruction_ok: mov edi,[calm_code_cursor] mov edx,calm_code_buffer mov ecx,8+8 call reserve_workspace mov eax,[calm_line_number] stosd mov eax,calm_call stosd mov eax,ebx stosd mov eax,alm_adjusted_context cmp [embedded_context],eax jne alm_call_argument mov eax,[line_context] mov [embedded_context],eax alm_call_argument: call move_to_next_symbol jc alm_call_arguments_ready cmp al,',' jne alm_call_invalid_argument inc esi mov edx,calm_code_buffer mov ecx,8 call reserve_workspace call move_to_next_symbol jc alm_call_empty_argument cmp al,',' je alm_call_empty_argument push edi mov dl,SYMCLASS_EXPRESSION call identify_symbol pop edi jc alm_call_invalid_argument test ebx,ebx jz alm_call_invalid_argument mov eax,ebx stosd jmp alm_call_argument alm_call_empty_argument: or eax,-1 stosd jmp alm_call_argument alm_call_invalid_argument: mov edx,_invalid_argument call register_error alm_call_arguments_ready: xor eax,eax stosd mov [calm_code_cursor],edi jmp instruction_assembled alm_exit: test [assembly_mode],AMODE_CALM_DEFINITION jz unexpected_instruction mov edi,[calm_code_cursor] mov edx,calm_code_buffer mov ecx,8 call reserve_workspace mov eax,[calm_line_number] stosd mov eax,calm_end stosd mov [calm_code_cursor],edi jmp instruction_assembled launch_calm: mov eax,[current_pass] mov [ebx+SymbolTree_Leaf.last_use_pass],eax mov eax,[ebx+SymbolTree_Leaf.branch] mov [instruction_branch],eax mov [calm_value],edx mov [calm_source_pointer],esi mov esi,[edx+ValueDefinition.value] mov eax,[esi+CompiledMacroHeader.literals_offset] add eax,esi mov [calm_literals],eax mov [breakpoint_token],0 mov ebx,[esi+CompiledMacroHeader.label_argument_leaf] test ebx,ebx jz calm_label_argument_ok test [assembly_mode],AMODE_DEFINITION setnz al or al,[esi+CompiledMacroHeader.label_argument_contextless] mov [contextless_processing],al call update_value_definition test edx,edx jz calm_label_argument_ok push esi push edx push [line_end] push [embedded_context] mov eax,[line_context] mov [embedded_context],eax mov esi,[line_start] mov ecx,[label_instruction_start] mov [line_end],ecx sub ecx,esi add ecx,1+sizeof.RecognitionContext mov edx,assembly_workspace mov edi,[edx+Workspace.memory_start] call reserve_workspace xor edx,edx mov [breakpoint_token],dl call extract_piece_of_line pop [embedded_context] pop [line_end] pop edx mov [value_type],VALTYPE_SYMBOLIC mov esi,[assembly_workspace.memory_start] mov ecx,edi sub ecx,esi call assign_value pop esi calm_label_argument_ok: add esi,sizeof.CompiledMacroHeader mov eax,[esi] inc eax cmp eax,1 jbe calm_arguments_defined get_calm_argument: mov edx,assembly_workspace mov edi,[edx+Workspace.memory_start] mov ecx,[line_end] sub ecx,[calm_source_pointer] add ecx,1+sizeof.RecognitionContext call reserve_workspace test [assembly_mode],AMODE_DEFINITION setnz al or al,[esi+CompiledMacroArgument.contextless] mov [contextless_processing],al mov eax,[esi+sizeof.CompiledMacroArgument] xchg esi,[calm_source_pointer] inc eax jz get_calm_greedy_argument call extract_argument_value jmp calm_argument_value_cut get_calm_greedy_argument: xor edx,edx call extract_piece_of_line calm_argument_value_cut: xchg esi,[calm_source_pointer] mov ebx,[esi+CompiledMacroArgument.symbol_leaf] call update_value_definition test edx,edx jz calm_argument_ok mov ecx,edi sub ecx,[assembly_workspace.memory_start] test ecx,ecx jnz calm_argument_value_ready or ecx,[esi+CompiledMacroArgument.default_value_length] jz calm_argument_value_ready cmp ecx,-1 je missing_argument push esi mov esi,[esi+CompiledMacroArgument.default_value_offset] add esi,[calm_literals] jmp calm_assign_argument_value calm_argument_value_ready: push esi mov esi,[assembly_workspace.memory_start] calm_assign_argument_value: mov [value_type],VALTYPE_SYMBOLIC call assign_value pop esi calm_argument_ok: add esi,sizeof.CompiledMacroArgument mov eax,[esi] inc eax cmp eax,1 jbe calm_arguments_defined xchg esi,[calm_source_pointer] call move_to_next_symbol jc calm_next_argument cmp al,',' jne invalid_argument inc esi calm_next_argument: xchg esi,[calm_source_pointer] jmp get_calm_argument calm_arguments_defined: add esi,4 and [calm_instruction_number],0 call create_source_entry jc calm_exceeded_stack_limit mov edx,[calm_value] mov [ebx+SourceEntry.type],SOURCE_CALM mov [ebx+SourceEntry.text],edx sub esi,[edx+ValueDefinition.value] mov [ebx+SourceEntry.offset],esi or [edx+ValueDefinition.flags],VAL_IN_USE inc [edx+ValueDefinition.reference_count] mov eax,[parameter_namespace] mov [ebx+SourceEntry.local_namespace],eax mov esi,[calm_source_pointer] mov ecx,[instruction_branch] test ecx,ecx jz instruction_assembled mov [ebx+SourceEntry.name],ecx or [ebx+SourceEntry.name_length],-1 jmp instruction_assembled calm_exceeded_stack_limit: mov edx,_stack_limit_exceeded call register_error jmp assembly_line calm_virtual_machine: mov al,[ebx+SourceEntry.saved_result] mov [calm_result],al mov edx,[ebx+SourceEntry.text] mov [calm_value],edx mov esi,[edx+ValueDefinition.value] mov eax,[esi+CompiledMacroHeader.literals_offset] add eax,esi mov [calm_literals],eax add esi,[ebx+SourceEntry.offset] calm_execution_unit: lodsd mov [calm_instruction_number],eax lodsd jmp eax calm_end: mov ebx,[source_context] mov ecx,[ebx+SourceContext.number_of_entries] dec ecx ; jz internal_error mov [ebx+SourceContext.number_of_entries],ecx imul ecx,sizeof.SourceEntry mov edx,[ebx+sizeof.SourceContext+ecx+SourceEntry.text] and [edx+ValueDefinition.flags],not VAL_IN_USE dec [edx+ValueDefinition.reference_count] jmp assembly_line calm_arrange: lodsd mov [label_leaf],eax lodsd mov ecx,eax lodsd push esi mov esi,[calm_literals] add eax,esi add esi,ecx mov [pattern_end],eax mov edi,[assembly_workspace.memory_start] arrange_by_pattern: mov edx,assembly_workspace mov ecx,[pattern_end] sub ecx,esi call reserve_workspace arrange_token: cmp esi,[pattern_end] je assign_arranged_value lodsb cmp al,1Bh je arrange_by_reference cmp al,0A0h je downgrade_hard_space cmp al,0BFh je restore_question_mark stosb cmp al,1Ah je copy_arranged_token_data cmp al,22h je copy_arranged_token_data cmp al,27h je copy_arranged_token_data cmp al,30h jne arrange_token lodsd stosd mov ecx,eax rep movsb jmp arrange_token copy_arranged_token_data: movsd jmp arrange_token downgrade_hard_space: mov al,20h stosb jmp arrange_token restore_question_mark: mov al,'?' stosb jmp arrange_token arrange_by_reference: mov ebx,[esi+4] call use_available_value jc arrange_missing_value mov al,[edx+ValueDefinition.type] cmp al,VALTYPE_NUMERIC je arrange_numeric_value cmp al,VALTYPE_PLAIN je arrange_plain_value cmp al,VALTYPE_SYMBOLIC jne arrange_unsupported_value mov ecx,[edx+ValueDefinition.value_length] jecxz arrange_empty_value add ecx,1+sizeof.RecognitionContext mov ebx,edx mov edx,assembly_workspace call reserve_workspace mov edx,ebx mov ebx,esi mov esi,[edx+ValueDefinition.value] mov ecx,[edx+ValueDefinition.value_length] rep movsb lea esi,[ebx+8] cmp esi,[pattern_end] je assign_arranged_value mov al,40h stosb xor eax,eax assert sizeof.RecognitionContext and 11b = 0 mov ecx,sizeof.RecognitionContext shr 2 rep stosd jmp arrange_by_pattern arrange_numeric_value: mov eax,[edx+ValueDefinition.value] mov ecx,[eax] cmp dword [eax+4+ecx],0 jne arrange_unsupported_value test byte [eax+4+ecx-1],80h jnz arrange_unsupported_value mov ebx,esi mov esi,eax mov edx,assembly_workspace add ecx,1+4 call reserve_workspace mov al,30h stosb lodsd stosd mov ecx,eax rep movsb lea esi,[ebx+8] jmp arrange_by_pattern arrange_empty_value: add esi,8 jmp arrange_token arrange_plain_value: mov edx,[edx+ValueDefinition.value] mov al,30h stosb mov ebx,edi xor eax,eax stosd mov eax,edx store_plain_bytes: inc dword [ebx] stosb shr eax,8 jnz store_plain_bytes test byte [edi-1],80h jnz store_plain_bytes add esi,8 jmp arrange_by_pattern arrange_unsupported_value: mov edx,_invalid_symbol_value jmp arrange_failed_reference arrange_missing_value: mov edx,_undefined_symbol arrange_failed_reference: call register_error mov al,1Ah stosb movsd lodsd mov eax,[eax+SymbolTree_Leaf.branch] cmp [eax+SymbolTree_Foliage.name_kind],NAME_CASEINSENSITIVE jne arrange_token mov al,'?' stosb jmp arrange_token assign_arranged_value: mov ebx,[label_leaf] call update_value_definition test edx,edx jz arranged_value_assigned mov [value_type],VALTYPE_SYMBOLIC mov ecx,edi mov esi,[assembly_workspace.memory_start] sub ecx,esi call assign_value arranged_value_assigned: pop esi jmp calm_execution_unit calm_match: and [calm_result],0 lodsd mov ebx,eax lodsd mov ecx,eax lodsd mov edi,[calm_literals] add eax,edi add edi,ecx mov [pattern_end],eax lodsd mov [brackets],eax call use_available_value jc calm_undefined_symbol mov al,[edx+ValueDefinition.type] cmp al,VALTYPE_RESERVED je calm_undefined_symbol cmp al,VALTYPE_SYMBOLIC jne calm_invalid_value push esi mov [value],edx inc [edx+ValueDefinition.reference_count] mov esi,[edx+ValueDefinition.value] mov ecx,[edx+ValueDefinition.value_length] add ecx,esi mov [line_end],ecx mov ebx,[expression_workspace.memory_start] and [matched_context],0 and [stored_position],0 calm_match_with_pattern: cmp edi,[pattern_end] je calm_end_of_pattern mov ah,[edi] cmp ah,1Bh jne calm_exact_match calm_wildcard_match: and [stored_position],0 add edi,1+8 cmp edi,[pattern_end] je calm_required_wildcard_match cmp byte [edi],0BFh je calm_optional_wildcard_match calm_required_wildcard_match: cmp esi,[line_end] je calm_match_done call calm_consume_whitespace jz calm_match_done xchg edi,ebx mov edx,expression_workspace mov ecx,sizeof.MatchedExcerpt call reserve_workspace xchg edi,ebx mov eax,[edi-4] mov ecx,[matched_context] mov [ebx+MatchedExcerpt.symbol_leaf],eax mov [ebx+MatchedExcerpt.recognition_context],ecx mov [ebx+MatchedExcerpt.data_start],esi mov al,[esi] call calm_consume_token jc calm_match_done mov [ebx+MatchedExcerpt.data_end],esi add ebx,sizeof.MatchedExcerpt jmp calm_match_with_pattern calm_optional_wildcard_match: xchg edi,ebx mov edx,expression_workspace mov ecx,sizeof.MatchedExcerpt call reserve_workspace xchg edi,ebx mov eax,[edi-4] inc edi mov ecx,[matched_context] mov [ebx+MatchedExcerpt.symbol_leaf],eax mov [ebx+MatchedExcerpt.recognition_context],ecx mov [ebx+MatchedExcerpt.data_start],esi mov [ebx+MatchedExcerpt.data_end],esi add ebx,sizeof.MatchedExcerpt jmp calm_match_with_pattern calm_exact_match: cmp esi,[line_end] je calm_end_of_text mov al,[esi] cmp al,40h jne found_token_to_match inc esi mov [matched_context],esi add esi,sizeof.RecognitionContext jmp calm_exact_match found_token_to_match: cmp [stored_position],0 jne calm_match_position_stored mov [stored_position],esi mov ecx,[matched_context] mov [stored_context],ecx mov [stored_pattern],edi calm_match_position_stored: cmp al,20h je calm_match_whitespace cmp ah,20h je calm_skip_pattern_whitespace cmpsb jne calm_token_mismatch cmp ah,1Ah je calm_match_name_tokens cmp ah,22h je calm_match_string_tokens cmp ah,27h je calm_match_string_tokens cmp ah,30h jne calm_match_with_pattern mov ecx,esi mov edx,edi lodsd add esi,eax mov eax,[edi] lea edi,[edi+4+eax] cmp byte [edi],0BFh jne calm_compare_token_contents inc edi jmp calm_compare_token_contents calm_match_string_tokens: lodsd mov ecx,eax mov edx,[edi] add edi,4 calm_compare_token_contents: cmp ecx,edx je calm_match_with_pattern push esi edi mov esi,ecx mov edi,edx mov ecx,[esi] add ecx,4 repe cmpsb pop edi esi jne calm_retract_match jmp calm_match_with_pattern calm_match_name_tokens: lodsd mov ecx,eax mov edx,[edi] add edi,4 cmp byte [edi],0BFh je calm_case_insensitive_match cmp ecx,edx je calm_match_with_pattern push esi edi mov esi,ecx mov edi,edx lodsd scasd jne calm_name_mismatch mov ecx,eax mov eax,[esi+ecx] cmp eax,[edi+ecx] jne calm_name_mismatch repe cmpsb jne calm_name_mismatch pop edi esi jmp calm_match_with_pattern calm_name_mismatch: pop edi esi jmp calm_retract_match calm_case_insensitive_match: inc edi cmp ecx,edx je calm_match_with_pattern push esi edi mov esi,ecx mov edi,edx lodsd scasd jne calm_name_mismatch mov ecx,eax mov eax,[esi+ecx+4] cmp eax,[edi+ecx+4] jne calm_name_mismatch xor eax,eax calm_compare_case_insensitively: lodsb mov dl,[characters+eax] mov al,[edi] inc edi cmp dl,[characters+eax] jne name_mismatch loop calm_compare_case_insensitively pop edi esi jmp calm_match_with_pattern calm_match_converted_number: call convert_number_to_match jmp calm_compare_token_contents calm_match_with_converted_number: xchg esi,edi call convert_number_to_match xchg esi,edi jmp calm_compare_token_contents calm_match_whitespace: cmp ah,20h je calm_optional_whitespace cmp ah,0A0h je calm_required_whitespace cmp [stored_pattern],edi jne calm_retract_match call calm_consume_whitespace jz calm_match_done and [stored_position],0 jmp calm_match_with_pattern calm_optional_whitespace: inc edi cmp edi,[pattern_end] je calm_whitespace_matched cmp byte [edi],0A0h jne calm_whitespace_matched calm_required_whitespace: inc edi cmp edi,[pattern_end] je calm_whitespace_matched cmp byte [edi],20h jne calm_whitespace_matched inc edi calm_whitespace_matched: call calm_consume_whitespace jz calm_end_of_text jmp calm_match_with_pattern calm_skip_pattern_whitespace: inc edi jmp calm_match_with_pattern calm_token_mismatch: cmp ax,1A30h je calm_match_converted_number cmp ax,301Ah je calm_match_with_converted_number calm_retract_match: xor esi,esi xchg esi,[stored_position] mov ecx,[stored_context] mov [matched_context],ecx mov edi,[stored_pattern] call calm_consume_whitespace jz calm_match_done calm_expand_wildcard_match: cmp ebx,[expression_workspace.memory_start] je calm_match_done call calm_consume_token jc calm_match_done mov [ebx-sizeof.MatchedExcerpt+MatchedExcerpt.data_end],esi jmp calm_match_with_pattern calm_consume_whitespace: mov al,[esi] cmp al,40h je calm_consume_context_token cmp al,20h jne calm_whitespace_consumed inc esi cmp esi,[line_end] jne calm_consume_whitespace calm_whitespace_consumed: retn calm_consume_context_token: inc esi mov [matched_context],esi add esi,sizeof.RecognitionContext cmp esi,[line_end] jne calm_consume_whitespace retn calm_consume_token: xor ecx,ecx mov edx,[brackets] inc esi consume_token_content: cmp al,dh je consume_closing cmp al,dl je consume_opening cmp al,1Ah je consume_token_with_data cmp al,22h je consume_token_with_data cmp al,27h je consume_token_with_data cmp al,30h je consume_internal_token cmp al,40h je consume_context_token test ecx,ecx jnz consume_more retn consume_token_with_data: add esi,4 test ecx,ecx jnz consume_more retn consume_internal_token: lodsd add esi,eax test ecx,ecx jnz consume_more retn consume_context_token: add esi,sizeof.RecognitionContext test ecx,ecx jnz consume_more retn consume_closing: sub ecx,1 jg consume_more retn consume_opening: inc ecx consume_more: cmp esi,[line_end] je consume_unsatisfied lodsb jmp consume_token_content consume_unsatisfied: stc retn calm_end_of_pattern: cmp esi,[line_end] je calm_match_found lodsb cmp al,20h je calm_end_of_pattern cmp al,40h jne calm_another_token_to_match add esi,sizeof.RecognitionContext jmp calm_end_of_pattern calm_another_token_to_match: dec esi cmp [stored_position],0 je calm_expand_wildcard_match jmp calm_retract_match calm_end_of_text: cmp edi,[pattern_end] je calm_match_found mov ah,[edi] cmp ah,1Bh je calm_wildcard_match cmp ah,20h jne calm_match_done inc edi jmp calm_end_of_text calm_match_found: or [calm_result],1 mov esi,ebx mov [value_type],VALTYPE_SYMBOLIC calm_assign_matched_values: cmp esi,[expression_workspace.memory_start] je calm_match_done sub esi,sizeof.MatchedExcerpt mov ebx,[esi+MatchedExcerpt.symbol_leaf] call update_value_definition test edx,edx jz calm_assign_matched_values push esi mov eax,[esi+MatchedExcerpt.recognition_context] mov ecx,[esi+MatchedExcerpt.data_end] mov esi,[esi+MatchedExcerpt.data_start] sub ecx,esi jz calm_matched_value_ready test eax,eax jz calm_matched_value_ready cmp dword [eax],0 je calm_matched_value_ready push esi ecx edx mov esi,eax mov edx,assembly_workspace mov edi,[edx+Workspace.memory_start] add ecx,1+sizeof.RecognitionContext call reserve_workspace mov al,40h stosb assert sizeof.RecognitionContext and 11b = 0 mov ecx,sizeof.RecognitionContext shr 2 rep movsd pop edx ecx esi rep movsb mov ecx,edi mov esi,[assembly_workspace.memory_start] sub ecx,esi calm_matched_value_ready: call assign_value pop esi jmp calm_assign_matched_values calm_match_done: mov edx,[value] dec [edx+ValueDefinition.reference_count] pop esi jmp calm_execution_unit calm_compute: lodsd mov [label_leaf],eax lodsd add eax,esi push eax mov edi,[calculation_workspace.memory_start] and [value_position],0 call calculate_parsed_expression call pop_terms jc calm_compute_done mov al,byte [edi+ExpressionTerm.attributes] cmp al,EXPR_STRING je calm_computed_string cmp al,EXPR_FLOAT je calm_computed_float call convert_terms_to_numeric_value mov [value_type],VALTYPE_NUMERIC calm_computed_value_ready: mov edi,ecx mov ebx,[label_leaf] call update_value_definition test edx,edx jz calm_compute_done mov ecx,edi call assign_value calm_compute_done: pop esi jmp calm_execution_unit calm_computed_string: call get_term_value mov esi,edx mov ecx,[esi] add ecx,4 mov [value_type],VALTYPE_STRING jmp calm_computed_value_ready calm_computed_float: call get_term_value mov esi,edx mov ecx,sizeof.FloatData mov [value_type],VALTYPE_FLOAT jmp calm_computed_value_ready calm_check: lodsd test eax,eax jz calm_execution_unit js calm_check calm_evaluate_logical_value: call evaluate_stored_logical_value mov [calm_result],al add esi,[esi-4] find_next_logical_value: lodsd test eax,eax jz calm_execution_unit jns next_logical_value_found cmp eax,BOOL_NEG jne find_next_logical_value xor [calm_result],1 jmp find_next_logical_value next_logical_value_found: mov ebx,esi xor ecx,ecx skip_next_logical_value: inc ecx add esi,eax skip_logical_operator: lodsd assert BOOL_NEG = -1 cmp eax,BOOL_NEG jg skip_next_logical_value je skip_logical_operator dec ecx jnz skip_logical_operator cmp eax,BOOL_AND je calm_and calm_or: cmp [calm_result],0 jne find_next_logical_value mov esi,ebx jmp calm_evaluate_logical_value calm_and: cmp [calm_result],0 je find_next_logical_value mov esi,ebx jmp calm_evaluate_logical_value calm_jyes: cmp [calm_result],0 jne calm_jump add esi,4 jmp calm_execution_unit calm_jno: cmp [calm_result],0 je calm_jump add esi,4 jmp calm_execution_unit calm_jump: lodsd mov edx,[calm_value] add eax,[edx+ValueDefinition.value] mov esi,eax jmp calm_execution_unit calm_assemble: lodsd mov ebx,eax mov eax,[current_pass] mov [ebx+SymbolTree_Leaf.last_use_pass],eax mov eax,[ebx+SymbolTree_Leaf.branch] mov [instruction_branch],eax call use_available_value jc calm_undefined_symbol mov al,[edx+ValueDefinition.type] cmp al,VALTYPE_SYMBOLIC jne calm_invalid_value call create_source_entry jc calm_assemble_exceeded_stack_limit mov [ebx+SourceEntry.type],SOURCE_MACRO or [ebx+SourceEntry.flags],SRCF_PREPROCESSED mov [ebx+SourceEntry.text],edx or [edx+ValueDefinition.flags],VAL_IN_USE inc [edx+ValueDefinition.reference_count] mov eax,[calm_instruction_number] mov [ebx-sizeof.SourceEntry+SourceEntry.line_number],eax mov edx,[ebx-sizeof.SourceEntry+SourceEntry.text] mov ecx,[edx+ValueDefinition.value] sub esi,ecx mov [ebx-sizeof.SourceEntry+SourceEntry.offset],esi mov eax,[ebx-sizeof.SourceEntry+SourceEntry.local_namespace] mov [ebx+SourceEntry.local_namespace],eax mov al,[calm_result] mov [ebx-sizeof.SourceEntry+SourceEntry.saved_result],al mov ecx,[instruction_branch] test ecx,ecx jz assembly_line mov [ebx+SourceEntry.name],ecx or [ebx+SourceEntry.name_length],-1 jmp assembly_line calm_undefined_symbol: mov edx,_undefined_symbol jmp calm_execution_error calm_invalid_value: mov edx,_invalid_symbol_value jmp calm_execution_error calm_assemble_exceeded_stack_limit: mov edx,_stack_limit_exceeded calm_execution_error: call register_error jmp calm_execution_unit calm_transform: mov [calm_result],0 lodsd mov [label_leaf],eax mov ebx,eax lodsd mov [transforming_namespace],eax call get_available_value jc calm_undefined_symbol cmp [edx+ValueDefinition.type],VALTYPE_SYMBOLIC jne calm_invalid_value push esi call clear_line_embeddings mov esi,[edx+ValueDefinition.value] mov [line_start],esi xor eax,eax mov [embedded_context],eax mov [line_context],eax mov ecx,[edx+ValueDefinition.value_length] add ecx,esi mov [line_end],ecx mov edi,[assembly_workspace.memory_start] mov [hidden_context],0 transform_symbolic_value: and [symbol_definition],0 mov dl,SYMCLASS_EXPRESSION push edi mov eax,[embedded_context] mov [line_context],eax mov ebx,[transforming_namespace] test ebx,ebx jz transform_identify call identify_symbol_in_namespace jmp transform_identification_done transform_identify: call identify_symbol transform_identification_done: jc symbolic_value_transformed test edi,edi jnz ready_to_transform call skip_literal xor ebx,ebx ready_to_transform: pop edi test ebx,ebx jz untransformed_literal mov [further_whitespace],ecx call get_available_value jc untransformed_literal cmp [edx+ValueDefinition.type],VALTYPE_SYMBOLIC jne untransformed_literal mov eax,[current_pass] mov [ebx+SymbolTree_Leaf.last_use_pass],eax mov [calm_result],1 mov [line_start],esi mov esi,[edx+ValueDefinition.value] mov ecx,[edx+ValueDefinition.value_length] mov ebx,ecx add ecx,[further_whitespace] add ecx,1+sizeof.RecognitionContext mov edx,assembly_workspace call reserve_workspace test ebx,ebx jz symbol_transformed mov al,1 xchg al,[hidden_context] test al,al jnz reset_hidden_context cmp [line_context],0 je copy_transformed_value reset_hidden_context: xor edx,edx call reset_transformed_context copy_transformed_value: mov ecx,ebx rep movsb symbol_transformed: mov ecx,[further_whitespace] mov al,20h rep stosb mov esi,[line_start] jmp transform_symbolic_value untransformed_literal: mov ecx,esi xchg esi,[line_start] sub ecx,esi mov ebx,ecx add ecx,1+sizeof.RecognitionContext mov edx,assembly_workspace call reserve_workspace xor al,al xchg al,[hidden_context] test al,al jz copy_untransformed_literal mov edx,[line_context] call reset_transformed_context copy_untransformed_literal: mov ecx,ebx rep movsb jmp transform_symbolic_value reset_transformed_context: mov al,40h cmp [esi],al je transformed_context_ok stosb assert sizeof.RecognitionContext and 11b = 0 mov ecx,sizeof.RecognitionContext shr 2 test edx,edx jz clear_transformed_context xchg esi,edx rep movsd mov esi,edx transformed_context_ok: retn clear_transformed_context: xor eax,eax rep stosd retn symbolic_value_transformed: pop edi cmp [calm_result],0 je calm_transform_done mov ebx,[label_leaf] call update_value_definition test edx,edx jz calm_transform_done mov esi,[assembly_workspace.memory_start] mov ecx,edi sub ecx,esi mov [value_type],VALTYPE_SYMBOLIC call assign_value calm_transform_done: pop esi jmp calm_execution_unit calm_stringify: lodsd mov [label_leaf],eax mov ebx,eax call get_available_value jc calm_undefined_symbol mov al,[edx+ValueDefinition.type] cmp al,VALTYPE_SYMBOLIC jne calm_invalid_value mov eax,[edx+ValueDefinition.value] mov [symbol_value_start],eax mov ecx,[edx+ValueDefinition.value_length] add ecx,eax mov [symbol_value_end],ecx push esi call convert_symbolic_value_to_string mov edi,ecx mov ebx,[label_leaf] call update_value_definition test edx,edx jz calm_stringify_done mov ecx,edi mov [value_type],VALTYPE_STRING call assign_value calm_stringify_done: pop esi jmp calm_execution_unit calm_publish_constant: mov edi,create_constant_value_definition jmp calm_publish calm_publish_stack: mov edi,create_value_definition jmp calm_publish calm_publish_variable: mov edi,update_value_definition calm_publish: lodsd mov ebx,eax lodsd mov [label_leaf],eax call use_available_value jc calm_undefined_symbol mov al,[edx+ValueDefinition.type] cmp al,VALTYPE_SYMBOLIC jne calm_invalid_value push esi edi call clear_line_embeddings mov esi,[edx+ValueDefinition.value] mov [line_start],esi mov ecx,[edx+ValueDefinition.value_length] add ecx,esi mov [line_end],ecx and [symbol_definition],0 mov dl,SYMCLASS_EXPRESSION call identify_symbol mov eax,esi pop edi esi jc calm_invalid_identifier test ebx,ebx jz calm_invalid_identifier cmp eax,[line_end] jne calm_invalid_identifier xchg ebx,[label_leaf] call use_available_value jc calm_undefined_symbol mov al,[edx+ValueDefinition.type] cmp al,VALTYPE_SYMBOLIC jb calm_invalid_value cmp al,VALTYPE_PLAIN je calm_value_type_ok cmp al,VALTYPE_AREA ja calm_invalid_value calm_value_type_ok: mov [value_type],al mov [value],edx mov ebx,[label_leaf] call edi test edx,edx jz calm_execution_unit push esi mov eax,[value] mov esi,[eax+ValueDefinition.value] mov ecx,[eax+ValueDefinition.value_length] call assign_value pop esi jmp calm_execution_unit calm_invalid_identifier: mov edx,_invalid_identifier call register_error jmp calm_execution_unit calm_take: lodsd mov edi,eax lodsd mov ebx,eax xor edx,edx call remove_value_definition setnc [calm_result] jmp calm_execution_unit calm_display: call compute_calm_constant jc calm_execution_unit cmp al,EXPR_STRING je calm_display_string cmp al,EXPR_NUMBER je calm_display_character calm_invalid_argument: mov edx,_invalid_argument call register_error jmp calm_execution_unit calm_display_string: call display_string_data jmp calm_execution_unit calm_display_character: call display_single_byte_data jmp calm_execution_unit calm_err: call compute_calm_constant jc calm_execution_unit cmp al,EXPR_STRING jne calm_invalid_argument call register_volatile_error test edx,edx jz calm_execution_unit or [edx+Error.flags],ERR_CUSTOM jmp calm_execution_unit calm_emit: call compute_calm_constant jc calm_invalid_data_unit cmp al,EXPR_NUMBER jne calm_invalid_data_unit mov edi,data_unit_length mov ecx,4 call fit_value jc calm_invalid_data_unit jns calm_emit_data calm_invalid_data_unit: mov edx,_invalid_argument call register_error mov [data_unit_length],1 calm_emit_data: lodsd test eax,eax jz calm_reserve_data add eax,esi push eax mov edi,[calculation_workspace.memory_start] and [value_position],0 call calculate_parsed_expression pop esi call pop_terms jc calm_execution_unit push edi mov ecx,[data_unit_length] call initialize_output xchg edi,[esp] call get_calculated_constant_value pop edi cmp al,EXPR_FLOAT je calm_emit_float cmp al,EXPR_STRING je calm_emit_string cmp al,EXPR_NUMBER jne calm_invalid_argument mov ecx,[data_unit_length] call fit_value jnc calm_execution_unit calm_emit_out_of_range: mov edx,_value_out_of_range call register_error jmp calm_execution_unit calm_emit_string: mov eax,[data_unit_length] mov ecx,[edx] sub eax,ecx jc calm_emit_out_of_range xchg esi,edx add esi,4 rep movsb mov ecx,eax xor al,al rep stosb mov esi,edx jmp calm_execution_unit calm_emit_float: push esi mov esi,edx mov ecx,[data_unit_length] call fit_float pop esi jmp calm_execution_unit calm_reserve_data: mov ecx,[data_unit_length] call uninitialized_output jmp calm_execution_unit compute_calm_constant: lodsd test eax,eax jz calm_constant_invalid add eax,esi push eax mov edi,[calculation_workspace.memory_start] and [value_position],0 call calculate_parsed_expression pop esi call pop_terms jc calm_constant_invalid call get_calculated_constant_value clc retn calm_constant_invalid: stc retn calm_load: lodsd mov [label_leaf],eax lodsd add eax,esi push eax mov edi,esi and [value_position],0 call get_area_value pop esi jc calm_load_area_invalid mov [data_area_symbol],ebx mov [data_area],edx call compute_calm_constant jc calm_load_offset_invalid cmp al,EXPR_NUMBER jne calm_load_offset_invalid mov edi,data_offset mov ecx,4 call fit_value jc calm_load_offset_invalid js calm_load_offset_invalid call compute_calm_constant jc calm_load_length_invalid cmp al,EXPR_NUMBER jne calm_load_length_invalid mov edi,value_length mov ecx,4 call fit_value jc calm_load_length_invalid js calm_load_length_invalid mov ebx,[label_leaf] call update_value_definition test edx,edx jz calm_execution_unit mov ecx,[value_length] add ecx,4 mov [value_type],VALTYPE_STRING push edx esi xor esi,esi call assign_value mov edi,[edx+ValueDefinition.value] mov eax,[value_length] mov ecx,eax stosd mov edx,[data_area] call load_from_area pop esi edx jnc calm_execution_unit mov [edx+ValueDefinition.value_length],4 mov edi,[edx+ValueDefinition.value] and dword [edi],0 jmp calm_execution_unit calm_load_area_invalid: lodsd add esi,eax calm_load_offset_invalid: lodsd add esi,eax calm_load_length_invalid: jmp calm_invalid_argument calm_load_from_output: lodsd mov [label_leaf],eax call compute_calm_constant jc calm_load_offset_invalid cmp al,EXPR_NUMBER jne calm_load_offset_invalid mov edi,file_offset mov ecx,8 call fit_value jc calm_load_offset_invalid js calm_load_offset_invalid call compute_calm_constant jc calm_load_length_invalid cmp al,EXPR_NUMBER jne calm_load_length_invalid mov edi,value_length mov ecx,4 call fit_value jc calm_load_length_invalid js calm_load_length_invalid mov ebx,[label_leaf] call update_value_definition test edx,edx jz calm_execution_unit mov ecx,[value_length] add ecx,4 mov [value_type],VALTYPE_STRING push esi xor esi,esi call assign_value mov edi,[edx+ValueDefinition.value] mov eax,[value_length] mov ecx,eax stosd push edx call read_from_output pop edx esi mov ecx,[value_length] test ecx,ecx jz calm_execution_unit sub [edx+ValueDefinition.value_length],ecx mov edi,[edx+ValueDefinition.value] sub [edi],ecx calm_address_out_of_range: mov edx,_address_out_of_range call register_error jmp calm_execution_unit calm_store: lodsd add eax,esi push eax mov edi,esi and [value_position],0 call get_area_value pop esi jc calm_store_area_invalid mov [data_area_symbol],ebx mov [data_area],edx call compute_calm_constant jc calm_store_offset_invalid cmp al,EXPR_NUMBER jne calm_store_offset_invalid mov edi,data_offset mov ecx,4 call fit_value jc calm_store_offset_invalid js calm_store_offset_invalid call compute_calm_constant jc calm_store_length_invalid cmp al,EXPR_NUMBER jne calm_store_length_invalid mov edi,value_length mov ecx,4 call fit_value jc calm_store_length_invalid js calm_store_length_invalid call prepare_area_to_write jc calm_store_not_possible push edi call compute_calm_constant pop edi jc calm_store_value_invalid mov ecx,[value_length] cmp al,EXPR_STRING je calm_store_string cmp al,EXPR_NUMBER jne calm_store_value_invalid call fit_value jc calm_emit_out_of_range jmp calm_execution_unit calm_store_string: mov eax,ecx mov ecx,[edx] sub eax,ecx jc calm_emit_out_of_range push esi lea esi,[edx+4] rep movsb xchg ecx,eax rep stosb pop esi jmp calm_execution_unit calm_store_area_invalid: lodsd add esi,eax calm_store_offset_invalid: lodsd add esi,eax calm_store_length_invalid: lodsd add esi,eax calm_store_value_invalid: jmp calm_invalid_argument calm_store_not_possible: lodsd add esi,eax jmp calm_execution_unit calm_store_in_output: call compute_calm_constant jc calm_store_offset_invalid cmp al,EXPR_NUMBER jne calm_store_offset_invalid mov edi,file_offset mov ecx,8 call fit_value jc calm_store_offset_invalid js calm_store_offset_invalid call compute_calm_constant jc calm_store_length_invalid cmp al,EXPR_NUMBER jne calm_store_length_invalid mov edi,value_length mov ecx,4 call fit_value jc calm_store_length_invalid js calm_store_length_invalid call compute_calm_constant mov ecx,[value_length] cmp al,EXPR_STRING je try_exact_store cmp al,EXPR_NUMBER jne calm_store_value_invalid try_exact_store: cmp ecx,[edx] jne indirect_store push esi lea esi,[edx+4] jmp calm_rewrite_output indirect_store: push eax ecx edx mov edx,assembly_workspace mov edi,[edx+Workspace.memory_start] call reserve_workspace pop edx ecx eax cmp al,EXPR_STRING je calm_store_string_in_output call fit_value jc calm_emit_out_of_range push esi calm_store_finish: mov esi,[assembly_workspace.memory_start] calm_rewrite_output: call rewrite_output pop esi cmp [value_length],0 jne calm_address_out_of_range jmp calm_execution_unit calm_store_string_in_output: mov eax,ecx mov ecx,[edx] sub eax,ecx jc calm_emit_out_of_range push esi lea esi,[edx+4] rep movsb xchg ecx,eax rep stosb jmp calm_store_finish calm_call: lodsd mov ebx,eax mov eax,[current_pass] mov [ebx+SymbolTree_Leaf.last_use_pass],eax mov eax,[ebx+SymbolTree_Leaf.branch] mov [instruction_branch],eax call use_available_value jc calm_call_undefined mov al,[edx+ValueDefinition.type] cmp al,VALTYPE_CALM jne calm_call_invalid call create_source_entry jc calm_call_exceeded_stack_limit xor eax,eax xchg eax,[calm_instruction_number] mov [ebx-sizeof.SourceEntry+SourceEntry.line_number],eax mov eax,[parameter_namespace] mov [ebx+SourceEntry.local_namespace],eax mov ecx,[instruction_branch] test ecx,ecx jz called_name_ok mov [ebx+SourceEntry.name],ecx or [ebx+SourceEntry.name_length],-1 called_name_ok: mov [ebx+SourceEntry.type],SOURCE_CALM mov [ebx+SourceEntry.text],edx or [edx+ValueDefinition.flags],VAL_IN_USE inc [edx+ValueDefinition.reference_count] mov edi,esi mov esi,[edx+ValueDefinition.value] mov eax,[esi+CompiledMacroHeader.literals_offset] add eax,esi mov [calm_value],edx mov [calm_literals],eax add esi,sizeof.CompiledMacroHeader push ebx process_call_arguments: mov eax,[esi] inc eax cmp eax,1 jbe call_arguments_ready mov ebx,[edi] test ebx,ebx jz omitted_call_argument add edi,4 cmp ebx,-1 je omitted_call_argument call use_available_value jc missing_argument_value cmp [edx+ValueDefinition.type],VALTYPE_NATIVE_COMMAND jae unassignable_value push edx mov ebx,[esi+CompiledMacroArgument.symbol_leaf] call update_value_definition pop eax push esi edi mov esi,[eax+ValueDefinition.value] mov ecx,[eax+ValueDefinition.value_length] mov al,[eax+ValueDefinition.type] cmp al,VALTYPE_ELEMENT je assign_element cmp al,VALTYPE_AREA je assign_element assign_call_argument: test edx,edx jz call_argument_assigned mov [value_type],al call assign_value call_argument_assigned: pop edi esi next_call_argument: add esi,sizeof.CompiledMacroArgument jmp process_call_arguments missing_argument_value: mov edx,_undefined_symbol call register_error jmp next_call_argument unassignable_value: mov edx,_invalid_symbol_value call register_error jmp next_call_argument omitted_call_argument: mov ebx,[esi+CompiledMacroArgument.symbol_leaf] call update_value_definition push esi edi mov ecx,[esi+CompiledMacroArgument.default_value_length] mov esi,[esi+CompiledMacroArgument.default_value_offset] add esi,[calm_literals] mov al,VALTYPE_SYMBOLIC cmp ecx,-1 jne assign_call_argument inc ecx push edx mov edx,_invalid_argument call register_error pop edx jmp assign_call_argument assign_element: mov ecx,[edi-4] mov edi,[assembly_workspace.memory_start] mov esi,edi xor eax,eax stosd mov eax,ecx stosd xor eax,eax inc eax stosd stosb dec eax stosd mov ecx,17 mov al,VALTYPE_NUMERIC jmp assign_call_argument call_arguments_ready: add esi,4 mov eax,[edi] add edi,4 test eax,eax jz call_arguments_ok mov edx,_invalid_argument call register_error skip_excess_arguments: mov eax,[edi] add edi,4 test eax,eax jnz skip_excess_arguments call_arguments_ok: pop ebx mov eax,[ebx-sizeof.SourceEntry+SourceEntry.text] mov ecx,[eax+ValueDefinition.value] sub edi,ecx mov [ebx-sizeof.SourceEntry+SourceEntry.offset],edi mov al,[calm_result] mov [ebx-sizeof.SourceEntry+SourceEntry.saved_result],al jmp calm_execution_unit calm_call_undefined: mov edx,_undefined_symbol jmp calm_call_error calm_call_invalid: mov edx,_invalid_symbol_value jmp calm_call_error calm_call_exceeded_stack_limit: mov edx,_stack_limit_exceeded calm_call_error: call register_error skip_call_arguments: lodsd test eax,eax jnz skip_call_arguments jmp calm_execution_unit