179 lines
2.5 KiB
NASM
179 lines
2.5 KiB
NASM
SYS_EXIT equ 0x1
|
|
SYS_READ equ 0x3
|
|
SYS_WRITE equ 0x4
|
|
|
|
STDIN equ 0x0
|
|
STDOUT equ 0x1
|
|
STDERR equ 0x2
|
|
|
|
; R15 is reserved for action
|
|
ACTION_LOOP equ 0x0
|
|
ACTION_CHAR equ 0x1
|
|
ACTION_BACK_TO_OPENING equ 0x2
|
|
ACTION_BACK_TO_COMMA equ 0x3
|
|
ACTION_BACK_TO_COLON equ 0x4
|
|
|
|
section .data
|
|
space db " "
|
|
endl db 10
|
|
backslash db "\\"
|
|
quote db 0x22 ; "
|
|
opening_curly db "{"
|
|
opening_bracket db "["
|
|
closing_curly db "}"
|
|
closing_bracket db "]"
|
|
comma db ","
|
|
colon db ":"
|
|
indent dq 2 ; dq (64 bits) because we are working with 64 bit registers
|
|
|
|
section .bss
|
|
char resb 1
|
|
exitCode resb 1
|
|
scope resq 1
|
|
in_string resb 1
|
|
escape_next resb 1
|
|
|
|
section .text
|
|
global _start
|
|
|
|
_start:
|
|
mov byte[exitCode], 0
|
|
mov byte[scope], 0
|
|
|
|
loop:
|
|
mov rax, SYS_READ
|
|
mov rbx, STDIN
|
|
mov rcx, char
|
|
mov rdx, 1
|
|
int 0x80
|
|
|
|
; is at EOF?
|
|
cmp rax, 0
|
|
jle end
|
|
|
|
mov r15, ACTION_LOOP
|
|
|
|
mov al, [char]
|
|
cmp al, [quote]
|
|
je case_quote
|
|
cmp al, [backslash]
|
|
je case_backslash
|
|
cmp al, [opening_curly]
|
|
je case_opening
|
|
cmp al, [opening_bracket]
|
|
je case_opening
|
|
cmp al, [closing_curly]
|
|
je case_closing
|
|
cmp al, [closing_bracket]
|
|
je case_closing
|
|
cmp al, [comma]
|
|
je case_comma
|
|
cmp al, [colon]
|
|
je case_colon
|
|
|
|
jmp print_char
|
|
|
|
case_quote:
|
|
mov al, [escape_next]
|
|
cmp al, 1
|
|
je print_char
|
|
|
|
xor byte[in_string], 1
|
|
jmp print_char
|
|
|
|
case_backslash:
|
|
mov byte[escape_next], 1
|
|
jmp print_char
|
|
|
|
case_opening:
|
|
mov r15, ACTION_BACK_TO_OPENING
|
|
jmp print_char
|
|
case_opening_back:
|
|
inc byte[scope]
|
|
jmp ln_start
|
|
|
|
case_closing:
|
|
dec byte[scope]
|
|
mov r15, ACTION_CHAR
|
|
jmp ln_start
|
|
|
|
case_comma:
|
|
mov r15, ACTION_BACK_TO_COMMA
|
|
jmp print_char
|
|
case_comma_back:
|
|
mov al, [in_string]
|
|
cmp al, 0
|
|
je ln_start
|
|
jmp loop
|
|
|
|
case_colon:
|
|
mov r15, ACTION_BACK_TO_COLON
|
|
jmp print_char
|
|
case_colon_back:
|
|
mov al, [in_string]
|
|
cmp al, 1
|
|
je loop
|
|
|
|
mov r15, ACTION_LOOP
|
|
mov al, [space]
|
|
mov byte[char], al
|
|
jmp print_char
|
|
|
|
print_char:
|
|
mov rax, SYS_WRITE
|
|
mov rbx, STDOUT
|
|
mov rcx, char
|
|
mov rdx, 1
|
|
int 0x80
|
|
|
|
cmp r15, ACTION_BACK_TO_OPENING
|
|
je case_opening_back
|
|
cmp r15, ACTION_BACK_TO_COMMA
|
|
je case_comma_back
|
|
cmp r15, ACTION_BACK_TO_COLON
|
|
je case_colon_back
|
|
|
|
jmp loop
|
|
|
|
ln_start:
|
|
xor r8, r8
|
|
xor r9, r9
|
|
xor rax, rax
|
|
|
|
mov rax, [indent]
|
|
mov rbx, [scope]
|
|
imul rax, rbx
|
|
mov r9, rax
|
|
|
|
mov rax, SYS_WRITE
|
|
mov rbx, STDOUT
|
|
mov rcx, endl
|
|
mov rdx, 1
|
|
int 0x80
|
|
|
|
cmp qword[scope], 0
|
|
jne ln_loop
|
|
|
|
ln_end:
|
|
cmp r15, ACTION_CHAR
|
|
je print_char
|
|
jmp loop
|
|
|
|
ln_loop:
|
|
mov rax, SYS_WRITE
|
|
mov rbx, STDOUT
|
|
mov rcx, space
|
|
mov rdx, 1
|
|
int 0x80
|
|
|
|
inc r8
|
|
cmp r8, r9
|
|
jne ln_loop
|
|
|
|
jmp ln_end
|
|
|
|
end:
|
|
mov rax, SYS_EXIT
|
|
mov rbx, [exitCode]
|
|
int 0x80
|