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
|
|
|
|
|
|
|
|
;; ------------------------------------------
|
|
|
|
;; Fixed strings for printing
|
2018-01-04 19:05:03 +03:00
|
|
|
|
2018-01-04 02:50:34 +03:00
|
|
|
static prompt_string, db 10,"user> " ; The string to print at the prompt
|
2017-10-10 02:22:10 +03:00
|
|
|
|
2018-01-04 02:50:34 +03:00
|
|
|
section .text
|
|
|
|
|
|
|
|
;; Takes a string as input and processes it into a form
|
|
|
|
read:
|
|
|
|
jmp read_str ; In reader.asm
|
2018-01-04 19:05:03 +03:00
|
|
|
|
|
|
|
;; ----------------------------------------------
|
|
|
|
;; Evaluates a form
|
|
|
|
;;
|
|
|
|
;; Inputs: RSI Form to evaluate
|
|
|
|
;;
|
2017-10-10 02:22:10 +03:00
|
|
|
eval:
|
|
|
|
mov rax, rsi ; Return the input
|
|
|
|
ret
|
|
|
|
|
|
|
|
;; Prints the result
|
|
|
|
print:
|
2018-01-04 02:50:34 +03:00
|
|
|
mov rdi, 1 ; print readably
|
|
|
|
jmp pr_str
|
2017-10-10 02:22:10 +03:00
|
|
|
|
|
|
|
;; Read-Eval-Print in sequence
|
|
|
|
rep_seq:
|
2018-01-04 19:05:03 +03:00
|
|
|
; -------------
|
|
|
|
; Read
|
2018-01-04 02:50:34 +03:00
|
|
|
call read
|
|
|
|
push rax ; Save form
|
2018-01-04 19:05:03 +03:00
|
|
|
|
|
|
|
; -------------
|
|
|
|
; Eval
|
2017-10-10 02:22:10 +03:00
|
|
|
mov rsi, rax ; Output of read into input of eval
|
|
|
|
call eval
|
2018-01-04 19:05:03 +03:00
|
|
|
|
|
|
|
; -------------
|
|
|
|
; Print
|
2018-01-04 02:50:34 +03:00
|
|
|
|
2018-01-04 19:05:03 +03:00
|
|
|
mov rsi, rax ; Output of eval into input of print
|
2018-01-04 02:50:34 +03:00
|
|
|
call print ; String in RAX
|
|
|
|
|
|
|
|
mov r8, rax ; Save output
|
|
|
|
pop rsi ; Form returned by read
|
|
|
|
call release_object
|
|
|
|
mov rax, r8
|
|
|
|
|
2017-10-10 02:22:10 +03:00
|
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
_start:
|
|
|
|
|
|
|
|
; -----------------------------
|
|
|
|
; Main loop
|
|
|
|
|
|
|
|
.mainLoop:
|
|
|
|
; print the prompt
|
2018-01-04 19:05:03 +03:00
|
|
|
print_str_mac prompt_string
|
2017-10-10 02:22:10 +03:00
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
mov rsi, rax
|
2018-01-04 02:50:34 +03:00
|
|
|
call rep_seq ; Read-Eval-Print
|
|
|
|
|
|
|
|
push rax ; Save returned string
|
2017-10-10 02:22:10 +03:00
|
|
|
|
|
|
|
mov rsi, rax ; Put into input of print_string
|
|
|
|
call print_string
|
|
|
|
|
2018-01-04 02:50:34 +03:00
|
|
|
; Release string from rep_seq
|
2017-10-15 02:26:09 +03:00
|
|
|
pop rsi
|
|
|
|
call release_array
|
|
|
|
|
2018-01-04 02:50:34 +03:00
|
|
|
; Release the input string
|
2017-10-10 02:22:10 +03:00
|
|
|
pop rsi
|
|
|
|
call release_array
|
|
|
|
|
|
|
|
jmp .mainLoop
|
|
|
|
.mainLoopEnd:
|
|
|
|
|
|
|
|
jmp quit
|
|
|
|
|