Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions PRIMITIVES.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,6 @@ added to them too.
* Terminate execution.
* `explode`
* Convert the supplied string to a list of characters.
* `fclose`
* Close the given file-handle, and always return nil.
* To simplify usage `fclose` will accept a nil-filehandle.
* `fopen`
* Open the given filename, for read/write, and return a handle.
* `fread`
* Read ALL available data from the given handle.
* To simplify usage `fread` will accept a nil-filehandle, and return nil.
Expand Down Expand Up @@ -242,6 +237,11 @@ The implementation of these primitives can be found in the file [stdlib.slisp](s
* Return the offset of matching items inside the given list.
* `flatten`
* Flatten the given list of lists into a single list
* `fclose`
* Close the given file-handle, and always return nil.
* To simplify usage `fclose` will accept a nil-filehandle.
* `fopen`
* Open the given filename, for read/write, and return a handle.
* `getc`
* Read a single character from STDIN, return NIL on failure.
* `getenv`
Expand Down
78 changes: 0 additions & 78 deletions compiler/template.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -1578,84 +1578,6 @@ FUNC fn_sys_explode



;; Close a file handle
;;
;; As a special case closing a nil-filehandle is valid.
;;
FUNC fn_sys_fclose
mov rbx, rdi ; type-check arg1 (path)
GET_TAG_BITS rbx
cmp rbx, TAG_ID_NIL
je .fclose_return_nil
cmp rbx, TAG_ID_INTEGER
jne type_error

UNTAG_REG rdi
mov rax, SYS_close
syscall
xor rax, rax ; return nil
.fclose_return_nil:
STORE_NIL_REG rax
ret




;; Open a file handle, modes are "r", "w", or "a"
FUNC fn_sys_fopen
mov rbx, rdi ; type-check arg1 (path)
GET_TAG_BITS rbx
cmp rbx, TAG_ID_STRING
jne type_error

mov rbx, rsi ; type-check arg2 (mode)
GET_TAG_BITS rbx
cmp rbx, TAG_ID_STRING
jne type_error

UNTAG_REG rdi
UNTAG_REG rsi

mov al, [rsi] ; We only look at the first character..
cmp al, 'a'
je .fopen_append
cmp al, 'r'
je .fopen_read
cmp al, 'w'
je .fopen_write

; fall through to bad mode
STORE_NIL_REG rax
ret

.fopen_append:
mov rax, SYS_open
mov rsi, 1089 ; O_WRONLY|O_CREAT|O_APPEND
mov rdx, 0o644
syscall
jmp .fopen_done
.fopen_read:
mov rax, SYS_open
mov rsi, 0 ; O_RDONLY
xor rdx, rdx
syscall
jmp .fopen_done
.fopen_write:
mov rax, SYS_open
mov rsi, 577 ; O_WRONLY|O_CREAT|O_TRUNC
mov rdx, 0o644
syscall
.fopen_done:
test rax, rax
js .fopen_syscall_fail
TAG_INTEGER_REG rax
ret
.fopen_syscall_fail:
STORE_NIL_REG rax
ret



;; Read ALL data from the given file handle.
;;
;; As a special case reading from a nil-filehandle
Expand Down
2 changes: 0 additions & 2 deletions inception.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -309,8 +309,6 @@
(register-builtin "sys_environment" (lambda (args) (sys_environment)))
(register-builtin "sys_exit" (lambda (args) (sys_exit (car args))))
(register-builtin "sys_explode" (lambda (args) (sys_explode (car args))))
(register-builtin "sys_fclose" (lambda (args) (sys_fclose (car args))))
(register-builtin "sys_fopen" (lambda (args) (sys_fopen (car args) (cadr args))))
(register-builtin "sys_fread" (lambda (args) (sys_fread (car args))))
(register-builtin "sys_fwrite" (lambda (args) (sys_fwrite (car args) (cadr args) (caddr args))))
(register-builtin "sys_implode" (lambda (args) (sys_implode (car args))))
Expand Down
46 changes: 34 additions & 12 deletions stdlib.slisp
Original file line number Diff line number Diff line change
Expand Up @@ -98,18 +98,6 @@
"Convert a string to a list of characters."
(sys_explode str))

(defun fclose (n)
"Close the given file-handle.

It is assumed the filehandle came from fopen, but nil is also accepted."
(sys_fclose n))

(defun fopen (str mode)
"Open a file with the given mode.

Mode is \"r\" for read, \"w\" for write, and \"a\" for append."
(sys_fopen str mode))

(defun fread (handle)
"Read all available data from the given file-handle.

Expand Down Expand Up @@ -409,6 +397,40 @@ do the right thing for each entry in the given list."
"Does the named path exist?"
(cons? (stat path)))

(defconst SYS_close 3)

(defun fclose (handle)
"Close the given handle.

As a special case closing a NIL file-handle is valid"
(cond
((nil? handle) nil)
((int? handle)
(let ((res 0))
(set! res (syscall SYS_close handle))
(if (> res 0)
res
nil)))
(t (do (println "Calling fclose with an invalid handle-type") (exit 1)))))

(defconst SYS_open 2)

(defun fopen (str mode)
"Open a file with the given mode.

Mode is \"r\" for read, \"w\" for write, and \"a\" for append."
(let ((flags 0)
(handle 0))
(cond
((= 0 (strcmp mode "a")) (set! flags 1089)) ; O_WRONLY|O_CREAT|O_APPEND
((= 0 (strcmp mode "r")) (set! flags 0)) ; O_RDONLY
((= 0 (strcmp mode "w")) (set! flags 577)) ; O_WRONLY|O_CREAT|O_TRUNC
(t (do (println "unknown mode for fopen:" mode ) (exit 1))))
(set! handle (syscall SYS_open str flags 420)) ; 420 == mode, 644 in octal
(if (> handle 0)
handle
nil)))

(defun file? (path)
"Is the given path a file?"
(let ((res (stat path)))
Expand Down
Loading