1;; Copyright (c) 2015-2016 Robert Virding 2;; 3;; Licensed under the Apache License, Version 2.0 (the "License"); 4;; you may not use this file except in compliance with the License. 5;; You may obtain a copy of the License at 6;; 7;; http://www.apache.org/licenses/LICENSE-2.0 8;; 9;; Unless required by applicable law or agreed to in writing, software 10;; distributed under the License is distributed on an "AS IS" BASIS, 11;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12;; See the License for the specific language governing permissions and 13;; limitations under the License. 14 15;; File : cl.lfe 16;; Author : Robert Virding, Duncan McGreggor 17;; Purpose : LFE Common Lisp interface library. 18 19(defmodule cl 20 "LFE Common Lisp interface library." 21 (export 22 ;; Boolean conversion functions. 23 (make-lfe-bool 1) (make-cl-bool 1) 24 ;; Control structure. 25 (mapcar 2) (maplist 2) (mapc 2) (mapl 2) 26 ;; Symbol functions. 27 (symbol-plist 1) (symbol-name 1) 28 (get 2) (get 3) (getl 2) (putprop 3) (remprop 2) 29 ;; Property list functions. 30 (getf 2) (getf 3) (putf 3) (remf 2) (get-properties 2) 31 ;; Sequences. 32 (elt 2) (length 1) (reverse 1) (some 2) (every 2) (notany 2) (notevery 2) 33 (reduce 2) (reduce 4) (reduce 6) 34 (remove 2) (remove-if 2) (remove-if-not 2) (remove-duplicates 1) 35 (substitute 3) (substitute-if 3) (substitute-if-not 3) 36 (find 2) (find-if 2) (find-if-not 2) 37 (position 2) (position-if 2) (position-if-not 2) 38 (count 2) (count-if 2) (count-if-not 2) 39 ;; Lists. 40 (car 1) (cdr 1) (first 1) (rest 1) (nth 2) 41 (nthcdr 2) (last 1) (butlast 1) 42 ;; Substitution of expressions. 43 (subst 3) (subst-if 3) (subst-if-not 3) (sublis 2) 44 ;; Lists as sets. 45 (member 2) (member-if 2) (member-if-not 2) (adjoin 2) (union 2) 46 (intersection 2) (set-difference 2) (set-exclusive-or 2) (subsetp 2) 47 ;; Association list functions. 48 (acons 3) (pairlis 2) (pairlis 3) (assoc 2) (assoc-if 2) (assoc-if-not 2) 49 (rassoc 2) (rassoc-if 2) (rassoc-if-not 2) 50 ;; Types. 51 (type-of 1) (coerce 2)) 52 (export-macro 53 ;; Export control structure macros. 54 do 55 ;; Export CL-style if and cond, which we don't use internally. 56 if cond)) 57 58;;; Boolean conversion functions. 59 60(defun make-lfe-bool ;Make an LFE bool from a CL value 61 "cl-boolean 62 Make an LFE bool from a CL value." 63 ([()] 'false) 64 ([_] 'true)) ;Everything else is true 65 66(defun make-cl-bool ;Make a CL bool from an LFE value 67 "lfe-boolean 68 Make a CL bool from an LFE value." 69 (['false] ()) 70 (['true] 'true)) 71 72;; Control structure. 73 74(defmacro do args 75 "vars (end-test result) body" 76 (let* ((`(,pars (,test ,ret) . ,body) args) 77 ((tuple vs is cs) 78 (lists:foldr (match-lambda 79 ([(list v i c) (tuple vs is cs)] 80 (tuple (cons v vs) (cons i is) (cons c cs)))) 81 (tuple () () ()) pars))) 82 `(letrec-function ((|\|-do-func-\|| 83 (lambda ,vs 84 (if ,test ,ret 85 (let ((do-state (progn . ,body))) 86 (|\|-do-func-\|| . ,cs)))))) 87 (|\|-do-func-\|| . ,is)))) 88 89(defun mapcar (func list) 90 "function list" 91 (lists:map func list)) 92 93(defun maplist 94 "function list" 95 ([func (= (cons _ rest) list)] 96 (cons (funcall func list) (maplist func rest))) 97 ([func ()] ())) 98 99(defun mapc (func list) 100 "function list" 101 (lists:foreach func list) 102 list) 103 104(defun mapl (func list) 105 "function list" 106 (fletrec ((mapl-loop 107 ([(= (cons _ rest) list)] 108 (funcall func list) 109 (mapl-loop rest)) 110 ([()] ()))) 111 (mapl-loop list) 112 list)) 113 114;; Symbol function functions. 115;; get, getl, putprop and remprop should really only work on a 116;; symbols plist not just a plist. This is coming. Hence including 117;; getf, putf and remf. 118 119(defun ensure-plist-table () 120 (case (ets:info 'lfe-symbol-plist 'type) 121 ('undefined 122 (let ((init-pid (erlang:whereis 'init))) 123 (ets:new 'lfe-symbol-plist 124 (list 'set 'public 'named_table (tuple 'heir init-pid ()))))) 125 (_ 'ok))) 126 127(defun symbol-plist (symbol) 128 "symbol 129 Get the property list for symbol." 130 (ensure-plist-table) 131 (case (ets:lookup 'lfe-symbol-plist symbol) 132 (`(#(,_ ,plist)) plist) 133 (() ()))) 134 135(defun symbol-name (symb) 136 "symbol 137 Get the name of symbol as a list." 138 (atom_to_list symb)) 139 140(defun get (symbol pname) 141 "symbol pname 142 Get the property pname of symbol." 143 (get symbol pname ())) 144 145;;(defun get (plist pname def) (getf plist pname def)) 146 147(defun get (symbol pname def) 148 "symbol pname default" 149 (ensure-plist-table) 150 (let ((plist (symbol-plist symbol))) 151 (getf plist pname def))) 152 153(defun getl (symbol pnames) 154 "symbol pnames" 155 (ensure-plist-table) 156 (let ((plist (symbol-plist symbol))) 157 (fletrec ((getl-loop 158 ([(= (list* p v plist-rest) plist) pnames] 159 (if (member p pnames) 160 plist 161 (getl-loop plist-rest pnames))) 162 ([() pnames] ()))) 163 (getl-loop plist pnames)))) 164 165;; (defun putprop (plist val pname) (putf plist val pname)) 166 167(defun putprop (symbol val pname) 168 "symbol value pname" 169 (ensure-plist-table) 170 (let* ((plist (symbol-plist symbol)) 171 (plist (putf plist val pname))) 172 (ets:insert 'lfe-symbol-plist (tuple symbol plist)))) 173 174;; (defun getprop (plist pname) (remf plist pname)) 175 176(defun remprop (symbol pname) 177 "symbol pname" 178 (ensure-plist-table) 179 (let* ((plist (symbol-plist symbol)) 180 (plist (remf plist pname))) 181 ;; Delete element if plist empty 182 (if (=:= plist ()) 183 (ets:delete 'lfe-symbol-plist symbol) 184 (ets:insert 'lfe-symbol-plist (tuple symbol plist))))) 185 186;; Property list functions. 187 188(defun getf (plist pname) 189 "plist pname" 190 (getf plist pname ())) 191 192(defun getf 193 "plist pname default" 194 ([(list* p v plist) p def] v) 195 ([(list* _ _ plist) pname def] (getf plist pname def)) 196 ([() _m def] def)) 197 198(defun putf ;This doesn't exist in CL 199 "plist value pname" 200 ([(list* p _ plist) val p] 201 (list* p val plist)) 202 ([(list* p v plist) val pname] 203 (list* p v (putf plist val pname))) 204 ([() val pname] (list pname val))) 205 206(defun remf 207 "plist pname" 208 ([(list* p _ plist) p] plist) 209 ([(list* p v plist) pname] 210 (list* p v (remf plist pname))) 211 ([() pname] ())) 212 213(defun get-properties 214 "plist pnames" 215 ([(= (list* p v plist-rest) plist) pnames] 216 (if (member p pnames) 217 (tuple p v plist) 218 (get-properties plist-rest pnames))) 219 ([() pnames] (tuple () () ()))) 220 221;; Arrays. 222 223;; (defun aref (array i j) 224;; (elt j (elt i array))) 225 226;; Sequences. 227;; Simple sequence functions. 228 229(defun elt 230 ((n seq) (when (is_list seq)) 231 (nth n seq)) 232 ((n seq) (when (is_tuple seq)) 233 (tref seq (+ n 1)))) 234 235(defun length 236 ([seq] (when (is_list seq)) 237 (length seq)) 238 ([seq] (when (is_tuple seq)) 239 (tuple_size seq))) 240 241(defun reverse 242 ([seq] (when (is_list seq)) 243 (lists:reverse seq)) 244 ([seq] (when (is_tuple seq)) 245 (list_to_tuple (lists:reverse (tuple_to_list seq))))) 246 247;; Concatanation, mapping and reducing sequences. 248 249(defun some 250 "pred list 251 Return true if pred is true for some element of list." 252 ([pred seq] (when (is_list seq)) 253 (lists:any pred seq)) 254 ([pred seq] (when (is_tuple seq)) 255 (fletrec ((some-loop 256 ([i n] (when (>= i n)) 'false) 257 ([i n] 258 (orelse (funcall pred (tref seq i)) 259 (some-loop (+ i 1) n))))) 260 (some-loop 1 (tuple_size seq))))) 261 262(defun every 263 "pred list 264 Return true if pred is true for every element of list." 265 ([pred seq] (when (is_list seq)) 266 (lists:all pred seq)) 267 ([pred seq] (when (is_tuple seq)) 268 (fletrec ((every-loop 269 ([i n] (when (>= i n)) 'false) 270 ([i n] 271 (andalso (not (funcall pred (tref seq i))) 272 (every-loop (+ i 1) n))))) 273 (every-loop 1 (tuple_size seq))))) 274 275(defun notany (pred seq) 276 "pred list 277 Returns true if pred is false for every element of list." 278 (every (lambda (x) (not (funcall pred x))) seq)) 279 280(defun notevery (pred seq) 281 "pred list 282 Returns true if pred is false for some element of list." 283 (some (lambda (x) (not (funcall pred x))) seq)) 284 285(defun reduce (func seq) 286 (lists:foldl func '() seq)) 287 288(defun reduce 289 ((func seq 'initial-value x) 290 (lists:foldl func x seq)) 291 ((func seq 'from-end 'true) 292 (lists:foldr func '() seq))) 293 294(defun reduce 295 ((func seq 'from-end 'true 'initial-value x) 296 (lists:foldr func x seq)) 297 ((func seq 'initial-value x 'from-end 'true) 298 (lists:foldr func x seq))) 299 300;; Modifying sequences. 301 302(defun remove 303 "item sequence 304 Remove all elements from sequence which are equal to item." 305 ([item seq] (when (is_list seq)) 306 (lc ((<- x seq) (=/= x item)) x)) 307 ([item seq] (when (is_tuple seq)) 308 (list_to_tuple (remove item (tuple_to_list seq))))) 309 310(defun remove-if 311 "pred sequence 312 Remove all elements from sequence for which pred is true." 313 ([pred seq] (when (is_list seq)) 314 (lc ((<- x seq) (not (funcall pred x))) x)) 315 ([pred seq] (when (is_tuple seq)) 316 (list_to_tuple (remove-if pred (tuple_to_list seq))))) 317 318(defun remove-if-not 319 "pred sequence 320 Remove all elements from sequence for which pred is false." 321 ([pred seq] (when (is_list seq)) 322 (lc ((<- x seq) (funcall pred x)) x)) 323 ([pred seq] (when (is_tuple seq)) 324 (list_to_tuple (remove-if-not pred (tuple_to_list seq))))) 325 326(defun remove-duplicates 327 "sequence 328 Remove duplicates from sequence." 329 ([seq] (when (is_list seq)) 330 (fletrec ((rm-loop 331 ([(cons x rest)] 332 (if (lists:member x rest) 333 (rm-loop rest) 334 (cons x (rm-loop rest)))) 335 ([()] ()))) 336 (rm-loop seq))) 337 ([seq] (when (is_tuple seq)) 338 (list_to_tuple (remove-duplicates (tuple_to_list seq))))) 339 340(defun substitute 341 "new old sequence 342 Replace all elements in sequence which are equal to old with new." 343 ([new old seq] (when (is_list seq)) 344 (fletrec ((sub-loop 345 ([n o (cons o xs)] 346 (cons n (sub-loop n o xs))) 347 ([n o (cons x xs)] 348 (cons x (sub-loop n o xs))) 349 ([_ _ ()] ()))) 350 (sub-loop new old seq))) 351 ([new old seq] (when (is_tuple seq)) 352 (list_to_tuple (substitute new old (tuple_to_list seq))))) 353 354(defun substitute-if 355 "new pred sequence 356 Replace all elements in sequence for which pred is true with new." 357 ([new pred seq] (when (is_list seq)) 358 (fletrec ((sub-loop 359 ([n p (cons x xs)] 360 (cons (if (funcall p x) n x) (sub-loop n p xs))) 361 ([_ _ ()] ()))) 362 (sub-loop new pred seq))) 363 ([new pred seq] (when (is_tuple seq)) 364 (list_to_tuple (substitute-if new pred (tuple_to_list seq))))) 365 366(defun substitute-if-not 367 "new pred sequence 368 Replace all elements in sequence for which pred is false with new." 369 ([new pred seq] (when (is_list seq)) 370 (fletrec ((sub-loop 371 ([n p (cons x xs)] 372 (cons (if (funcall p x) x n) (sub-loop n p xs))) 373 ([_ _ ()] ()))) 374 (sub-loop new pred seq))) 375 ([new pred seq] (when (is_tuple seq)) 376 (list_to_tuple (substitute-if-not new pred (tuple_to_list seq))))) 377 378;; Searching sequences. 379 380(defun find (item seq) 381 "item sequence 382 If sequence contains item then it is returned else ()." 383 (fletrec ((find-loop 384 ([x (cons x xs)] x) 385 ([x (cons _ xs)] (find-loop x xs)) 386 ([x ()] ()))) 387 (find-loop item seq))) 388 389(defun find-if (pred seq) 390 "pred sequence 391 Return element in sequnce for which pred is true else ()." 392 (fletrec ((find-if-loop 393 ([pred (cons x xs)] 394 (if (funcall pred x) x (find-if-loop pred xs))) 395 ([pred ()] ()))) 396 (find-if-loop pred seq))) 397 398(defun find-if-not (pred seq) 399 "pred sequence 400 Return element in sequnce for which pred is true else ()." 401 (fletrec ((find-if-not-loop 402 ([pred (cons x xs)] 403 (if (funcall pred x) (find-if-not-loop pred xs) x)) 404 ([pred ()] ()))) 405 (find-if-not-loop pred seq))) 406 407(defun position (item seq) 408 "item sequence 409 Return index of item in sequence else ()." 410 (fletrec ((pos-loop 411 ([x n (cons x xs)] n) 412 ([x n (cons _ xs)] (pos-loop x (+ n 1) xs)) 413 ([x n ()] ()))) 414 (pos-loop item 0 seq))) 415 416(defun position-if (pred seq) 417 "item sequence 418 Return index of item in sequence for which pred is true else ()." 419 (fletrec ((pos-if-loop 420 ([pred n (cons x xs)] 421 (if (funcall pred x) 422 n 423 (pos-if-loop pred (+ n 1) xs))) 424 ([pred n ()] ()))) 425 (pos-if-loop pred 0 seq))) 426 427(defun position-if-not (pred xs) 428 "item sequence 429 Return index of item in sequence for which pred is false else ()." 430 (fletrec ((pos-if-not-loop 431 ([pred n (cons x xs)] 432 (if (funcall pred x) 433 (pos-if-not-loop pred (+ n 1) xs) 434 n)) 435 ([pred n ()] ()))) 436 (pos-if-not-loop pred 0 xs))) 437 438(defun count (item seq) 439 "item sequence 440 Return the number of elements in sequence equal to item." 441 (fletrec ((count-loop 442 ([x n (cons x1 xs)] 443 (let ((n1 (if (=:= x x1) (+ n 1) n))) 444 (count-loop x n1 xs))) 445 ([x n ()] n))) 446 (count-loop item 0 seq))) 447 448(defun count-if (pred seq) 449 "pred sequence 450 Return the number of elements in sequence for which pred is true." 451 (fletrec ((count-if-loop 452 ([pred n (cons x xs)] 453 (let ((n1 (if (funcall pred x) (+ n 1) n))) 454 (count-if-loop pred n1 xs))) 455 ([pred n ()] n))) 456 (count-if-loop pred 0 seq))) 457 458(defun count-if-not (pred seq) 459 "pred sequence 460 Return the number of elements in sequence for which pred is false." 461 (fletrec ((count-if-not-loop 462 ([pred n (cons x xs)] 463 (let ((n1 (if (funcall pred x) n (+ n 1)))) 464 (count-if-not-loop pred n1 xs))) 465 ([pred n ()] n))) 466 (count-if-not-loop pred 0 seq))) 467 468;;; Lists 469 470(defun car 471 ([()] ()) 472 ([xs] (car xs))) 473 474(defun first (xs) 475 (cl:car xs)) 476 477(defun cdr 478 ([()] ()) 479 ([xs] (cdr xs))) 480 481(defun rest (xs) 482 (cl:cdr xs)) 483 484(defun nth 485 ([n xs] (when (< n 0)) ()) 486 ([n xs] 487 (fletrec ((nth-loop 488 ([n ()] ()) ;End of the list 489 ([0 xs] (car xs)) ;Found the one 490 ([n xs] (nth-loop (- n 1) (cdr xs))))) 491 (nth-loop n xs)))) 492 493(defun nthcdr (n xs) 494 (lists:nthtail (+ n 1) xs)) 495 496(defun last (list) 497 (lists:last list)) 498 499(defun butlast (list) 500 (lists:droplast list)) 501 502;; Substitution of expressions 503 504(defun subst 505 "new old tree 506 Substitute `new` for every subtree `old` in `tree`." 507 ([new old old] new) 508 ([new old (cons e rest)] 509 (cons (subst new old e) (subst new old rest))) 510 ([new old tree] tree)) 511 512(defun subst-if (new test tree) 513 "new test tree 514 Substitute `new` for every subtree which satisfies `test` in `tree`." 515 (if (funcall test tree) new 516 (case tree 517 ((cons e rest) 518 (cons (subst-if new test e) (subst-if new test rest))) 519 (_ tree)))) 520 521(defun subst-if-not (new test tree) 522 "new test tree 523 Substitute `new` for every subtree which does not satisfy `test` in `tree`." 524 (if (funcall test tree) 525 (case tree 526 ((cons e rest) 527 (cons (subst-if-not new test e) (subst-if-not new test rest))) 528 (_ tree)) 529 new)) 530 531(defun sublis (a-list tree) 532 "a-list tree 533 Subsitute the value of each key in `a-list` occurring in `tree`." 534 (case (assoc tree a-list) 535 ((cons _ new) new) ;Found it 536 (() ;Not there 537 (case tree 538 ((cons e rest) 539 (cons (sublis a-list e) (sublis a-list rest))) 540 (_ tree))))) 541 542;; Lists as sets. 543 544(defun member (item list) 545 "item list 546 Return true if `item` is a member of `list`." 547 (lists:member item list)) 548 549(defun member-if 550 "pred list 551 Return true if `pred` is satisfied for a member of `list`." 552 ([pred (cons e list)] 553 (orelse (funcall pred e) 554 (member-if pred list))) 555 ([pred ()] 'false)) 556 557(defun member-if-not 558 "pred list 559 Return true if `pred` is not satisfied for a member of `list`." 560 ([pred (cons e list)] 561 (orelse (not (funcall pred e)) (member-if-not pred list))) 562 ([pred ()] 'false)) 563 564(defun adjoin (item list) 565 "item list 566 Add `item` to `list` if it is not already a member." 567 (if (member item list) 568 list 569 (cons item list))) 570 571(defun union 572 "list-1 list-2 573 Returns the elements which are members of lists `list-1` or `list-2`." 574 ([(cons e l1) l2] 575 (if (member e l2) 576 (union l1 l2) 577 (cons e (union l1 l2)))) 578 ([() l2] l2)) 579 580(defun intersection (l1 l2) 581 "list-1 list-2 582 Returns the elements which are members of both lists `list-1` and `list-2`." 583 (lc ((<- e l1) (member e l2)) e)) 584 585(defun set-difference (l1 l2) 586 "list-1 list-2 587 Returns the elements of `list-1` which are not elements in `list-2`." 588 (lc ((<- e l1) (not (member e l2))) e)) 589 590(defun set-exclusive-or (l1 l2) 591 "list-1 list-2 592 Return the elements which are elements of one of `list-1` or `list-2`." 593 (++ (set-difference l1 l2) (set-difference l2 l1))) 594 595(defun subsetp 596 "list-1 list-2 597 Return true if every element in `list-1` is also in `list-2`." 598 ([(cons e l1) l2] (andalso (member e l2) (subsetp l1 l2))) 599 ([() l2] 'true)) 600 601;; Association list functions. 602 603(defun acons (k v a-list) 604 "key value a-list 605 Add `(key . value)` to the front of the `a-list`." 606 (cons (cons k v) a-list)) 607 608(defun pairlis (ks vs) 609 "keys values 610 Make an alist from pairs of keys values." 611 (pairlis ks vs ())) 612 613(defun pairlis 614 "keys values a-list 615 Make an alist from pairs of keys values prepending them to a-list." 616 ([(cons k ks) (cons v vs) a-list] 617 (cons (cons k v) (pairlis ks vs a-list))) 618 ([() () a-list] a-list)) 619 620(defun assoc 621 "key a-list 622 Searches a-list returning the first pair whose car is key." 623 ([k (cons (= (cons k v) pair) _)] pair) 624 ([k (cons _ a-list)] (assoc k a-list)) 625 ([k ()] ())) 626 627(defun assoc-if 628 "pred a-list 629 Searches a-list returning the first pair for which pred is true." 630 ([pred (cons (= (cons k _) pair) a-list)] 631 (if (funcall pred k) pair 632 (assoc-if pred a-list))) 633 ([pred ()] ())) 634 635(defun assoc-if-not 636 "pred a-list 637 Searches a-list returning the first pair for which pred is false." 638 ([pred (cons (= (cons k _) pair) a-list)] 639 (if (funcall pred k) 640 (assoc-if-not pred a-list) 641 pair)) 642 ([pred ()] ())) 643 644(defun rassoc 645 "value a-list 646 Searches a-list returning the first pair whose cdr is value." 647 ([v (cons (= (cons _ v) pair) _)] pair) 648 ([v (cons _ a-list)] (rassoc v a-list)) 649 ([v ()] ())) 650 651(defun rassoc-if 652 "pred a-list 653 Searches a-list returning the first pair for which pred is true." 654 ([pred (cons (= (cons _ v) pair) a-list)] 655 (if (funcall pred v) 656 pair 657 (rassoc-if pred a-list))) 658 ([pred ()] ())) 659 660(defun rassoc-if-not 661 "pred a-list 662 Searches a-list returning the first pair for which pred is false." 663 ([pred (cons (= (cons _ v) pair) a-list)] 664 (if (funcall pred v) 665 (rassoc-if-not pred a-list) 666 pair)) 667 ([pred ()] ())) 668 669;;; Types 670 671(defun type-of 672 ((x) (when (is_boolean x)) 673 'boolean) 674 ((x) (when (is_atom x)) 675 'atom) 676 ((x) (when (is_tuple x)) 677 'tuple) 678 ((x) (when (is_integer x)) 679 'integer) 680 ((x) (when (is_float x)) 681 'float) 682 ((x) (when (is_list x)) 683 (cond ((io_lib:printable_latin1_list x) 'string) 684 ((io_lib:printable_unicode_list x) 'unicode) 685 ((?= `(,a . ,b) (when (not (is_list b))) x) 'cons) 686 ('true 'list))) 687 ((x) (when (is_function x)) 688 'function) 689 ((x) (when (is_binary x)) 690 'binary) 691 ((x) (when (is_bitstring x)) 692 'bitstring) 693 ((x) (when (is_pid x)) 694 'pid) 695 ((x) (when (is_port x)) 696 'port) 697 ((x) (when (is_reference x)) 698 'reference) 699 ((x) 700 (andalso (call 'erlang 'is_map x) 'map))) 701 702(defun coerce 703 ((x 'vector) (when (is_list x)) 704 (list_to_tuple x)) 705 ((x 'tuple) (when (is_list x)) 706 (list_to_tuple x)) 707 ((x 'atom) (when (is_list x)) 708 (list_to_atom x)) 709 ((x 'list) (when (is_atom x)) 710 (atom_to_list x)) 711 ((x 'list) (when (is_tuple x)) 712 (tuple_to_list x)) 713 ((x 'list) (when (is_binary x)) 714 (binary_to_list x)) 715 ((x 'list) (when (is_bitstring x)) 716 (bitstring_to_list x)) 717 ((x 'character) (when (is_atom x)) 718 (car (atom_to_list x))) 719 ((x 'character) (when (is_list x)) 720 (car x)) 721 ((x 'integer) (when (is_float x)) 722 (trunc x)) 723 ((x 'float) (when (is_integer x)) 724 (list_to_float (integer_to_list x))) 725 ((x 'float) (when (is_list x)) 726 (list_to_float x)) 727 ((x 'float) (when (is_atom x)) 728 (list_to_float (atom_to_list x))) 729 ((x 't) 730 x)) 731 732;;; System 733 734(defun posix-argv () 735 (init:get_arguments)) 736 737;; Test defining CL if and cond. We need to put these last so they 738;; won't be used inside this module, but of course the if can't. 739 740(defmacro if args 741 "test true-case false-case 742 CL compatible if macro." 743 (flet ((exp-if (test if-true if-false) 744 `(case ,test 745 (() ,if-false) 746 (_ ,if-true)))) 747 (case args 748 ((list test if-true) (exp-if test if-true ())) 749 ((list test if-true if-false) 750 (exp-if test if-true if-false))))) 751 752(defmacro cond args 753 "args 754 CL compatible cond macro." 755 (fletrec ((exp-cond 756 ([(cons (list test) cond)] 757 `(case ,test 758 (() ,(exp-cond cond)) 759 (|\|-cond-test-\|| |\|-cond-test-\||))) 760 ([(cons (cons test body) cond)] 761 `(case ,test 762 (() ,(exp-cond cond)) 763 (_ (progn . ,body)))) 764 ([()] ()))) 765 (exp-cond args))) 766