3293 lines
73 KiB
PHP
3293 lines
73 KiB
PHP
|
|
||
|
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
|