2017-10-10 02:22:10 +03:00
|
|
|
;;
|
|
|
|
;; nasm -felf64 step1_read_print.asm && ld step1_read_print.o && ./a.out
|
|
|
|
|
|
|
|
;; Calling convention: Address of input is in RSI
|
|
|
|
;; Address of return value is in RAX
|
|
|
|
;;
|
|
|
|
|
2017-10-22 02:24:53 +03:00
|
|
|
global _start
|
2017-10-12 01:29:29 +03:00
|
|
|
|
2017-10-22 02:24:53 +03:00
|
|
|
%include "types.asm" ; Data types, memory
|
|
|
|
%include "system.asm" ; System calls
|
|
|
|
%include "reader.asm" ; String -> Data structures
|
|
|
|
%include "printer.asm" ; Data structures -> String
|
2017-12-27 20:32:01 +03:00
|
|
|
%include "exceptions.asm" ; Error handling
|
|
|
|
|
2017-10-10 02:22:10 +03:00
|
|
|
section .data
|
|
|
|
|
2017-10-15 02:26:09 +03:00
|
|
|
test_string1: db 10, "test1", 10
|
|
|
|
.len: equ $ - test_string1
|
|
|
|
|
|
|
|
test_string2: db 10, "test2", 10
|
|
|
|
.len: equ $ - test_string2
|
|
|
|
|
2017-10-10 02:22:10 +03:00
|
|
|
;str: ISTRUC Array
|
2017-10-12 01:29:29 +03:00
|
|
|
;AT Array.type, db maltype_string
|
2017-10-10 02:22:10 +03:00
|
|
|
;AT Array.length, dd 6
|
|
|
|
;AT Array.data, db 'hello',10
|
|
|
|
;IEND
|
2017-10-20 01:01:33 +03:00
|
|
|
|
|
|
|
test_cons: ISTRUC Cons
|
|
|
|
AT Cons.typecar, db ( maltype_integer + 2 )
|
|
|
|
AT Cons.typecdr, db 0
|
|
|
|
AT Cons.car, dq 123
|
|
|
|
IEND
|
|
|
|
|
|
|
|
test_cons2: ISTRUC Cons
|
|
|
|
AT Cons.typecar, db ( maltype_integer + 2 )
|
|
|
|
AT Cons.typecdr, db content_pointer
|
|
|
|
AT Cons.car, dq 456
|
|
|
|
AT Cons.cdr, dq test_cons
|
|
|
|
IEND
|
2017-10-12 01:29:29 +03:00
|
|
|
|
2017-10-10 02:22:10 +03:00
|
|
|
;; ------------------------------------------
|
|
|
|
;; Fixed strings for printing
|
|
|
|
|
|
|
|
prompt_string: db 10,"user> " ; The string to print at the prompt
|
|
|
|
.len: equ $ - prompt_string
|
2017-10-22 02:24:53 +03:00
|
|
|
|
|
|
|
section .text
|
2017-10-10 02:22:10 +03:00
|
|
|
|
|
|
|
;; Evaluates a form
|
|
|
|
eval:
|
|
|
|
mov rax, rsi ; Return the input
|
|
|
|
ret
|
|
|
|
|
|
|
|
;; Prints the result
|
|
|
|
print:
|
|
|
|
mov rax, rsi ; Return the input
|
|
|
|
ret
|
|
|
|
|
|
|
|
;; Read-Eval-Print in sequence
|
|
|
|
rep_seq:
|
2017-10-15 02:26:09 +03:00
|
|
|
call read_str
|
2017-10-10 02:22:10 +03:00
|
|
|
mov rsi, rax ; Output of read into input of eval
|
|
|
|
call eval
|
|
|
|
mov rsi, rax ; Output of eval into input of print
|
|
|
|
call print
|
|
|
|
mov rsi, rax ; Return value
|
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
_start:
|
|
|
|
|
|
|
|
; -----------------------------
|
|
|
|
; Main loop
|
|
|
|
|
|
|
|
.mainLoop:
|
|
|
|
; print the prompt
|
|
|
|
mov rdx, prompt_string.len ; number of bytes
|
|
|
|
mov rsi, prompt_string ; address of raw string to output
|
|
|
|
call print_rawstring
|
|
|
|
|
|
|
|
call read_line
|
|
|
|
|
|
|
|
; Check if we have a zero-length string
|
|
|
|
cmp DWORD [rax+Array.length], 0
|
|
|
|
je .mainLoopEnd
|
|
|
|
|
|
|
|
push rax ; Save address of the string
|
2017-10-15 02:26:09 +03:00
|
|
|
|
|
|
|
; Put into read_str
|
|
|
|
mov rsi, rax
|
|
|
|
call read_str
|
|
|
|
push rax
|
|
|
|
|
|
|
|
; Put into pr_str
|
|
|
|
mov rsi, rax
|
2017-12-27 20:32:01 +03:00
|
|
|
mov rdi, 1 ; print readably
|
2017-10-15 02:26:09 +03:00
|
|
|
call pr_str
|
|
|
|
push rax
|
2017-10-10 02:22:10 +03:00
|
|
|
|
|
|
|
mov rsi, rax ; Put into input of print_string
|
|
|
|
call print_string
|
|
|
|
|
2017-10-15 02:26:09 +03:00
|
|
|
; Release string from pr_str
|
|
|
|
pop rsi
|
|
|
|
call release_array
|
|
|
|
|
2017-10-21 10:21:56 +03:00
|
|
|
; Release the object from read_str
|
2017-10-15 02:26:09 +03:00
|
|
|
pop rsi
|
2017-10-21 10:21:56 +03:00
|
|
|
call release_object ; Could be Cons or Array
|
2017-10-15 02:26:09 +03:00
|
|
|
|
2017-10-10 02:22:10 +03:00
|
|
|
; Release the string
|
|
|
|
pop rsi
|
|
|
|
call release_array
|
|
|
|
|
|
|
|
jmp .mainLoop
|
|
|
|
.mainLoopEnd:
|
|
|
|
|
|
|
|
jmp quit
|
|
|
|
|