Vous n'êtes pas identifié(e).

Top posteurs

Statistiques

Partenaires

  • eXolia Hosting
  • Eggdrop.fr

#1 16/03/2012 20:18:09

iZy
Nouveau IRCzien
Inscription : 27/08/2011
Messages : 17

(LISP) Exemple de robot

Pour la culture, voilà un squelette de robot basique en LISP, à base de macrofonctions que j'ai déniché dans un coin. Une grande partie de la puissance du LISP est basée sur la possibilité d'écrire des fonctions qui sont executées à la compilation, et qui génèrent du code. Ainsi, on fait des fonctions qui écrivent le programme qu'on souhaite : on peut surcharger la syntaxe (eh ouais, on peut faire ça en TCL ?)

Pour vous donner une idée, le code ci dessous permet de développer un robot IRC basique, à partir de la programmation evenementielle. Par exemple, pour écrire un robot qui réagit aux messages privés et aux notices,

Code: Lisp
(with-irc (sock "irc.citytchat.com" 6667)                                                                                                                                                                                    
      ("PRIVMSG" #'on-privmsg)
      ("NOTICE" #'on-notice))

Il suffit d'écrire un couple (mot clef, fonction à appeller) pour implémenter un système. Il n'est pas extrêmement complet, mais c'est à titre d'exemple.

Il fonctionne sur Closure Common Lisp (CCL)

Code: Lisp
;;Module IRC permettant la connexion et la programmation évènementielle à l'aide
;;de la macrofonction (WITH-IRC decl &body hooks)
 
(defpackage :com.izy.irc
  (:use 
	:common-lisp
	:ccl
	:openmcl-socket))
 
 
(defmacro string-concat (&body l)
  `(concatenate 'string ,@l))
 
;;Symboles aléatoires pour les macros
(defmacro with-gen (declaration &body expr)
    `(let ,(mapcar (lambda (sym)
		      `(,sym (gensym)))
		    declaration)
            ,@expr))
 
 
;;Réalise une connexion au serveur spécifié
;;et execute la liste d'instructions
(defmacro with-connection-to (decl &body b)
    `(with-open-stream
	        (,(car decl)
		   (make-socket
		                         :remote-port ,(caddr decl)
					 :remote-host ,(cadr decl)
					 :external-format :ISO-8859-1))
       ,@b))
 
 
 
 
;;Tokenisation
(defun split (string separateur)
   (loop for i = 0 then (1+ j)
     as j = (position separateur string :start i)
     collect (subseq string i j)
     while j))
(defmacro words (string)
  `(split ,string #\Space))
 
;;Génération des commandes IRC
(defmacro generer-3args (nom)
  `(defun ,nom (socket target data)
    (format socket ,(string-concat (string nom) " ~a :~a~%") target data)))
(defmacro generer-irc-cmds (&body cmds)
  (cons 'progn (reduce (lambda (acc elem)
	     (cons `(generer-3args ,elem) acc))
	   cmds
	   :initial-value nil)))
 
;;Permet de lier un mot clef avec un callback
;;la fonction function sera automatiquement appellée
;; à chaque fois que le keyword se trouve en seconde position
;; dans la chaîne
(defmacro hook (tag keyword function socket wordlist)
  `(if (string= ,keyword (cadr ,wordlist))
       (progn
	 (funcall ,function ,socket ,wordlist)
	 (go ,tag))))
;;Permet de lier une liste de mots clefs
(defmacro hookit (tag liste s w)
  `(progn
     ,@(mapcar (lambda (c) `(hook ,tag ,(car c) ,(cadr c) ,s ,w))
	       liste)))
 
;;Coeur du robot : permet de déterminer un serveur auquel se connecter
;;et de relier des évènements avec des fonctions callback
(defmacro with-irc (decl &body hooklist)
  (with-gen (tag)
    (let ((sock (car decl)))
      `(with-connection-to ,decl
	 (init sock "Monads`Power")
	 (tagbody ,tag
	    (let* ((raw (read-line ,sock))
		   (tokenised-raw (words raw)))
	      ;(format t "~a~%" (cadr tokenised-raw))
	      (verif-ping ,tag ,sock tokenised-raw)
	      (hookit ,tag ,hooklist ,sock tokenised-raw))
	    (go ,tag))))))
 
 
(defun init (socket nickname)
  (format socket "NICK ~a~%" nickname)
  (format socket "USER sin sin sin :17 F Back in TeH BuiZnesS<3~%"))
 
(defun on-privmsg (socket tokenizedString)
  (format t "PRIVMSG RECEIVED"))
(defmacro verif-ping (tag socket tokenizedString)
  `(if (string= "PING" (car ,tokenizedString))   
      (progn
       (format ,socket "PONG ~a" (cadr ,tokenizedString))
       (go ,tag))))
 
(defun test ()
    (with-irc (sock "irc.citytchat.com" 6667)
      ("PRIVMSG" #'on-privmsg)))

Ah j'adore ces parenthèses de partout !

Cordialement,
iZy

Dernière modification par iZy (16/03/2012 20:19:08)


i love mankind ; it's people i can't stand
[Charles M. Schulz]

Hors ligne

Pied de page des forums

412059 visites ( 68 aujourd'hui ) 1 visiteur en ligne
Copyright © 2004 - 2013 IRCz