@@ -488,7 +488,7 @@ Mode is \"r\" for read, \"w\" for write, and \"a\" for append."
488488 ((= 0 (strcmp mode "r")) (set! flags 0)) ; O_RDONLY
489489 ((= 0 (strcmp mode "w")) (set! flags 577)) ; O_WRONLY|O_CREAT|O_TRUNC
490490 (t (do (println "unknown mode for fopen:" mode ) (exit 1))))
491- (set! handle (syscall SYS_open str flags 420)) ; 420 == mode, 644 in octal
491+ (set! handle (syscall SYS_open str flags (octal "0o644")))
492492 (if (> handle 0)
493493 handle
494494 nil)))
@@ -544,10 +544,7 @@ It is assumed the filehandle came from fopen, but nil is also accepted."
544544 "Make the given directory.
545545
546546Note that this does not create parents, use (mkdirs) for that."
547- (syscall SYS_mkdir
548- path
549- 493 ; octal 0755 in decimal
550- ))
547+ (syscall SYS_mkdir path (octal "0o755")))
551548
552549(defun mkdirs (path)
553550 "Make the given directory, creating parent directories as necessary"
@@ -797,27 +794,107 @@ and run BODY for side-effects. Returns nil."
797794
798795
799796(defun binary (text)
800- "Parse the given text as a binary number, complet with 0b prefix."
797+ "Parse the given text as a binary number, complete with an 0b prefix.
798+
799+ See-also dec2binary."
801800 (parse-integer text "b" 2))
802801
803802(defun binary? (text)
804803 (integer-base? text "b" 2))
805804
806805(defun hex (text)
807- "Parse the given text as a hex number, complet with 0x prefix."
806+ "Parse the given text as a hex number, complete with an 0x prefix.
807+
808+ See-also dec2hex."
808809 (parse-integer text "x" 16))
809810
810811(defun hex? (text)
811812 (integer-base? text "x" 16))
812813
813814(defun octal (text)
814- "Parse the given text as a binary number, complet with 0o prefix."
815+ "Parse the given text as a binary number, complete with an 0o prefix.
816+
817+ See-also dec2octal"
815818 (parse-integer text "o" 8))
816819
817820(defun octal? (text)
818821 (integer-base? text "o" 8))
819822
820823
824+ ;;; 5.1.1 base conversions from decimal
825+
826+ (defun base-digit (value)
827+ "Return the character representation of a digit value 0-15."
828+ (cond
829+ ((= value 0) "0")
830+ ((= value 1) "1")
831+ ((= value 2) "2")
832+ ((= value 3) "3")
833+ ((= value 4) "4")
834+ ((= value 5) "5")
835+ ((= value 6) "6")
836+ ((= value 7) "7")
837+ ((= value 8) "8")
838+ ((= value 9) "9")
839+ ((= value 10) "A")
840+ ((= value 11) "B")
841+ ((= value 12) "C")
842+ ((= value 13) "D")
843+ ((= value 14) "E")
844+ ((= value 15) "F")
845+ (t nil)))
846+
847+ (defun decimal-base (value prefix base)
848+ "Convert a decimal integer to a number in the specified base."
849+ (let ((result "")
850+ (remainder 0)
851+ (digit "")
852+ (negative nil))
853+
854+ ;; Remember if our value was negative
855+ (if (< value 0)
856+ (do
857+ (set! negative t)
858+ (set! value (- 0 value))))
859+
860+ ;; Zero is a special case because the loop below would not run.
861+ (if (= value 0)
862+ (set! result "0")
863+
864+ (while (> value 0)
865+ (set! remainder (% value base))
866+ (set! digit (base-digit remainder))
867+ (set! result (strcat digit result))
868+ (set! value (/ value base))))
869+
870+ ;; Restore sign if we need to.
871+ (if negative (set! result (strcat "-" result)))
872+
873+ ;; Minimum width is two digits; mostly for hex digits.
874+ (if (= (strlen result) 1)
875+ (set! result (strcat "0" result)))
876+
877+ (strcat prefix result)))
878+
879+ (defun dec2binary (value)
880+ "Convert a decimal integer to binary, with a 0b prefix.
881+
882+ See also binary, and binary?"
883+ (decimal-base value "0b" 2))
884+
885+ (defun dec2hex (value)
886+ "Convert a decimal integer to hexadecimal, with a 0x prefix.
887+
888+ See also hex, and hex?"
889+ (decimal-base value "0x" 16))
890+
891+ (defun dec2octal (value)
892+ "Convert a decimal integer to octal, with a 0o prefix.
893+
894+ See also octal, and octal?"
895+ (decimal-base value "0o" 8))
896+
897+
821898
822899;;; 5.2 maths functions
823900
0 commit comments