-- First we'll define some helper functions -- Splits a string by spaces, or until it encounters a :, whereby the following is considered one element. splitirc'("", stracc, acc) -> acc + [stracc]. splitirc'(" "::xs, stracc, acc) -> do splitirc'(xs, "", acc + [stracc]) end. -- prefix message splitirc'(":"::xs, _, acc) -> do acc + [xs] end. splitirc'(x::xs, stracc, acc) -> splitirc'(xs, stracc + x, acc). -- helper function splitirc(str) -> splitirc'(str, "", []). head(x::_) -> x. tail(_::xs) -> xs. -- (result, rest) takeUntilSpace'(" "::xs, acc) -> (acc, xs). takeUntilSpace'(x::xs, acc) -> takeUntilSpace'(xs, acc + x). takeUntilSpace(str) -> takeUntilSpace'(str, ""). -- takes x!y and returns x ircnick'("!"::xs, acc) -> acc. ircnick'(x::xs, acc) -> ircnick'(xs, acc + x). ircnick(str) -> ircnick'(str, ""). say(chan, msg) -> fputstr(sock, "PRIVMSG " + chan + " :" + msg + "\r\n"). handleMessage(nick, chan, "$ping") -> say(chan, nick + ": pong"). handleMessage("darkf", chan, "$quit") -> do say(chan, "bye!"); fputstr(sock, "QUIT\r\n"); fclose(sock) end. handleMessage(nick, chan, msg) -> (). -- handleCommand(source, cmd, args) handleCommand(_, "PING", [ping]) -> do putstrln("ping: " + ping); fputstr(sock, "PONG :" + ping) end. handleCommand(user, "JOIN", [chan]) -> do putstrln("nick " + ircnick(user) + " joins " + chan) end. handleCommand(user, "PRIVMSG", [chan, msg]) -> do nick = ircnick(user); putstrln("<" + nick + "> " + msg); handleMessage(nick, chan, msg) end. -- nick list handleCommand(_, "353", _::"="::chan::[nicks]) -> do -- nicks is space-separated putstrln("nicks in " + chan + ": " + nicks) end. handleCommand(_, "372", [_,msg]) -> putstrln("MOTD: " + msg). handleCommand(_, "422", [_,msg]) -> putstrln(msg). -- MOTD is missing handleCommand(_, "251", _) -> (). -- There are X users and Y services on Z server(s) handleCommand(_, "331", _) -> (). -- No topic is set handleCommand(_, "366", _) -> (). -- End of NAMES list handleCommand(src, cmd, args) -> putstrln("Unhandled command: " + cmd + ", with args: " + repr(args) + " from " + src). handleLine(":" :: line) -> do -- sourced message (source, rest) = takeUntilSpace(line); command::args = splitirc(rest); handleCommand(source, command, args) end. handleLine(line) -> do -- non-sourced message command::args = splitirc(line); handleCommand(source, command, args) end. -- now for our actual program! -- build our socket and connect to the server sock = sockopen("127.0.0.1", 6667). -- send introduction fputstr(sock, "PASS foobar\r\n"). fputstr(sock, "NICK quaileggeater\r\n"). fputstr(sock, "USER fooname 0 * :Foo G. Bar\r\n"). fputstr(sock, "JOIN #TYBG\r\n"). fputstr(sock, "PRIVMSG #TYBG :sup.\r\n"). -- loop receiving lines mainloop() -> if feof(sock) != true then do line = fgetline(sock); handleLine(line); true end else false. putstrln("beginning mainloop"). loop(mainloop). fclose(sock). putstrln("done").