A few binary functions


#1

Hi,

I’ve added a few functions for bitwise operations. Here is my code in order of appearance in the file.
Maybe it could be useful to others.

Cheers,

Sébastien.

#define cddr(x)            (cdr(cdr(x)))

...

... LOGAND, LOGIOR, LOGXOR, LOGNOT, ASH, LOGBITP, ENDFUNCTIONS };

...

object *fn_logand (object *args, object *env) {
  (void) env;
  int arg1 = integer(first(args));
  int arg2 = integer(second(args));
  int result = arg1 & arg2;
  args = cddr(args);
  while (args != NULL) {
    result = result & integer(car(args));
    args = cdr(args);
  }
  return number(result);
}

object *fn_logior (object *args, object *env) {
  (void) env;
  int arg1 = integer(first(args));
  int arg2 = integer(second(args));
  int result = arg1 | arg2;
  args = cddr(args);
  while (args != NULL) {
    result = result | integer(car(args));
    args = cdr(args);
  }
  return number(result);
}

object *fn_logxor (object *args, object *env) {
  (void) env;
  int arg1 = integer(first(args));
  int arg2 = integer(second(args));
  int result = arg1 ^ arg2;
  args = cddr(args);
  while (args != NULL) {
    result = result ^ integer(car(args));
    args = cdr(args);
  }
  return number(result);
}

object *fn_lognot (object *args, object *env) {
  (void) env;
  int result = integer(car(args));
  return number(~result);
}

object *fn_ash (object *args, object *env) {
  (void) env;
  int value = integer(first(args));
  int count = integer(second(args));
  if (count > 0)
    return number(value << count);
  else
    return number(value >> abs(count));
}

object *fn_logbitp (object *args, object *env) {
  (void) env;
  int index = integer(first(args));
  int value = integer(second(args));
  if (bitRead(value, index) == 1)
    return tee;
  else
    return nil;
}

...

const char string110[] PROGMEM = "logand";
const char string111[] PROGMEM = "logior";
const char string112[] PROGMEM = "logxor";
const char string113[] PROGMEM = "lognot";
const char string114[] PROGMEM = "ash";
const char string115[] PROGMEM = "logbitp";

...

  { string110, fn_logand, 2, 127 },
  { string111, fn_logior, 2, 127 },
  { string112, fn_logxor, 2, 127 },
  { string113, fn_lognot, 1, 1 },
  { string114, fn_ash, 2, 2 },
  { string115, fn_logbitp, 2, 2 },

#2

Good suggestion. It was on my to-do list but you’ve beaten me to it!


#3

Hello,

As an example of the new functions here is my code to emit morse code.
The code just fits on a arduino uno and is capable of issuing short messages (due to the small amount of ram).
It is even possible to do a (save-image 'sos) and the board will boot looping the message.
I had to hardcode the blinking delay and the led pin in order to shorten the image size.

Have fun,

Sébastien.

;; morse code grouped by ten  
;; 0-9, A-J, K-T, U-Z
;; encoding is : 
;; left three bits for char size
;; five right bits : 0 => short, 1 => long, non used bits left at 0
;; ----------------------------------------------------------------
(defvar mrs '(191 175 167 163 161 160 176 184 188 190
	65 136 138 100 32 130 102 128 64 135
	101 132 67 66 103 134 141 98 96 33
	97 129 99 137 139 140))

;; blink
;; given a pos in the morse code list, make the led blink the morse digit/letter
;; -----------------------------------------------------------------------------
(defun bli(ch)
	(let* ((bin (nth ch mrs))
		   (i (1- (ash bin -5))))
		(loop
		   (analogwrite 10 255)
		   (if (logbitp i bin)
		   		(delay 600)
		   		(delay 200))   
		   (analogwrite 10 0)
		   (delay 200)
		   (decf i)
		   (when (< i 0) (return)))))

;; emit
;; given a list of morse code positions, successively emit the code
;; a negative value indicates a word separation
;; ----------------------------------------------------------------
(defun emt(lst)
	(dolist (elm lst)
		(if (< elm 0)
			(delay 1400)
			(progn
				(bli elm)
				(delay 600)))))

;; usage example
;; emit the digits then the full alphabet
;; --------------------------------------
(emt '(0 1 2 3 4 5 6 7 8 9))
(emt '(10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35))

(defun sos()
	(loop (emt '(28 24 28 -1))))