epic_scripting
no way to compare when less than two revisions
Differences
This shows you the differences between two versions of the page.
— | epic_scripting [2013/09/11 14:17] (current) – created - external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | =====An introduction to scripting with EPIC===== | ||
+ | The intended audience for this guide is users of EPIC5 who have some programming experience and want to understand the scripting language that is used to customize EPIC. This guide only begins the learning process and does not cover all of the important details. | ||
+ | |||
+ | =====The ircII language===== | ||
+ | EPIC is a fork of ircII. EPIC uses the same fundamental scripting language as ircII, which we call the "ircII language" | ||
+ | |||
+ | IrcII is like, and unlike, anything else: IrcII has things in common with Perl, TCL, Ruby, and PHP, but it is more unlike them than like them. The ircII language is inanely simple -- there are very few rules, and the rules that are there are strictly enforced, and where there are no rules, all bets are off. This is often a stumbling block for the new user. | ||
+ | |||
+ | Rule #1 -- Everything is a string and strings are everything: In ircII, everything is a Plain Old C String. All data, and all code, are stored as strings, and there is little distinction made between them. You are free to treat your data as code and your code as data. Because of this fluidity, ircII does not have byte compiling or flow control in the normal sense. | ||
+ | |||
+ | Rule #2 -- Whitespace is important (usually): In most languages, whitespace is not important. You can run letters and punctuation together with reckless abandon. But in ircII, whitespace is used to separate things in a list. Most nearly everything in ircII is a list. Spaces are always treated as normal characters: you would not expect a language to ignore ' | ||
+ | |||
+ | =====Writing code===== | ||
+ | |||
+ | The syntax of the ircII language is suprisingly simple. | ||
+ | |||
+ | * Block -- A block is a set of semicolon-separated statements. | ||
+ | * Statement -- A statement is a single operation in the language. Statements are either Command Statements, Block Statements, or Expression Statements. | ||
+ | * Expression Statement -- A statement that begins with the @ character, or a statement that is surrounded entirely by parenthesis, | ||
+ | * Block Statement -- A statement that is surrounded entirely by curly braces is a block statement. The block statement contains a block, naturally. | ||
+ | * Command Statement -- Any statement that is not an expression statement and not a block statement is by rule a command statement. A command statement is a list of space-separated words, where the first word is the name of a command and the rest of the words are the arguments to that command. | ||
+ | |||
+ | An Expression is a thing that has operands and operators, where the operators consume one or more operands and replace them with a new value. A expression is a thing like "3 + 4" or "var = 7". Expressions are explained in much more detail below. | ||
+ | |||
+ | A Command is an action to be performed. A command can either be built-in to the client (such as JOIN or QUIT) or it can be a string that you have registered as an alias. Everything that is not an expression is a command. That's it, really! Unlike most normal programming languages, ircII has no builtin block statements or flow control. Whereas other languages have native flow control built in, these things are Command Statements in ircII. | ||
+ | |||
+ | =====What you can do with your code===== | ||
+ | |||
+ | The ircII programming model is event driven -- your script does not control EPIC, but rather you tell EPIC what things you are interested in. Whenever your event handlers are not being run, EPIC is off busy doing all the other things that IRC clients do. | ||
+ | |||
+ | So if you don't register any event handlers, EPIC is happy to be a very simple IRC client that behaves very much like ircII. Unfortunately, | ||
+ | |||
+ | =====Events===== | ||
+ | |||
+ | One of the first things people want to change is how channel joins look. You know the default appearance... | ||
+ | |||
+ | < | ||
+ | |||
+ | But let's say you want to put the time in there, and you want to change the order of things. Here's an example that we'll walk through: | ||
+ | |||
+ | on ^join "* *" (nick, chan, userhost) { | ||
+ | xecho -b [$chan] JOIN: $nick \($userhost\) | ||
+ | } | ||
+ | |||
+ | If you skip ahead and read the intermediate technical stuff below, you will already understand a lot of what you see here. | ||
+ | |||
+ | You register event handlers by using the '' | ||
+ | |||
+ | When something interesting happens, we say that an "event is thrown" | ||
+ | |||
+ | In this case we are hooking the JOIN event, which is thrown any time someone (including yourself) joins a channel you are in. The argument list for JOIN is: | ||
+ | |||
+ | * Nickname -- Who joined the channel | ||
+ | * Channel -- What channel was joined | ||
+ | * Userhost -- The user@host of the person who joined | ||
+ | |||
+ | We use an argument list to automatically assign these values to local variables. Lots of older code doesn' | ||
+ | |||
+ | You'll notice that there is a caret before the '' | ||
+ | |||
+ | The wildcard pattern in this case is the star, which means we want to match everything. The wildcard pattern is a double-quoted word. Normally arguments cannot contain spaces, but sometimes you must (such as here), so you can surround words with spaces in double quotes and ircII will figure out you mean one argument that has spaces in it. You can't just use double quoted words anywhere you want (alas) but only where it is expected. | ||
+ | |||
+ | You use the wildcard pattern to filter out events that you are not interested in. The wildcard pattern is matched against the argument list, and if and only if the pattern matches the argument, does your code get run. This allows you to set up overlapping ons that act as exceptions: | ||
+ | |||
+ | on ^join "* *" (nick, chan, userhost) { | ||
+ | xecho -b [$chan] JOIN: $nick \($userhost\) | ||
+ | } | ||
+ | on ^join "bob *" (nick, chan, userhost) { | ||
+ | xecho -b HUZZAH! HUZZAH! HUZZAH! $nick!$userhost has joined $chan! | ||
+ | } | ||
+ | |||
+ | So when Bob joins the channel, the second event handler is run, and when anyone else joins, the first one is run. How does ircII know which on to use? Each handler gets scored based on how many non-wildcard characters it has in it. The first handler has a score of 1 (the space), and the second handler has a score of 4 (" | ||
+ | |||
+ | Next after the wildcard pattern is the argument list. As I said before, the argument list is optional. If you use the argument list, then the values of the event' | ||
+ | |||
+ | Finally comes a block of code you want to have run. The block of code is surrounded by curly braces (this is a requirement of the '' | ||
+ | |||
+ | =====Aliases===== | ||
+ | |||
+ | Aliases are commands that you create yourself. As I said before, an alias is nothing more and nothing less than a Plain Old String (POS) that you say contains a block of ircII code. When you create an alias, it is inserted into the list of valid commands, and it can be used by he user at the input prompt, and it can be used by your script in any command statement. | ||
+ | |||
+ | But what it doesn' | ||
+ | |||
+ | Specifically, | ||
+ | |||
+ | alias MyNewAlias { | ||
+ | echo Eek! You scared me! | ||
+ | } | ||
+ | |||
+ | This adds a new command " | ||
+ | |||
+ | Aliases, like On event handlers, can receive arguments. If you provide an argument list, the arguments are put into the variables in the list. If you do not provide an argument list, the arguments are put into '' | ||
+ | |||
+ | =====Variables===== | ||
+ | |||
+ | Variables (also called Assigns) are macro values you create yourself. All variables are strings, and there are no other types available. IrcII stores variables as C strings, so they cannot contain nuls (ascii 0). This means that variables are not suitable for storing binary data. | ||
+ | |||
+ | Variables can either be Global Variables or Local Variables. A Global Variable can be seen in any place, and never goes away or loses its value. But you can only have one value per global variable name, and this is a hassle for people who need temporary values or are writing recursive aliases. Local variables allow you to keep variables that won't conflict with anybody else, and get automatically deleted when you're done with them. Remember argument lists? Those use local variables, so those variables can only be seen while the alias or on is running, and get automatically deleted when the alias or on is finished. | ||
+ | |||
+ | =====Intermediate, | ||
+ | |||
+ | Language syntax: | ||
+ | The ircII language' | ||
+ | |||
+ | * Block -- A block is a set of semicolon-separated statements, optionally surrounded by curly braces. | ||
+ | * Statement -- A statement is a single operation in the language. Statements are either Command Statements, or Expression Statements. | ||
+ | * Expression Statement -- A statement that begins with the @ character, or a statement that is surrounded entirely by parenthesis, | ||
+ | * Expression -- A thing like "3 + 4" or "var = 7" where there are operands and operators, and operators reduce operands by performing operations until there is only one operand left. This is the value of the expression. An expression is considered " | ||
+ | * Block Statement -- A statement that is surrounded by curly braces is a block statement. The block statement contains a block, naturally. | ||
+ | * Command Statement -- Any statement that is not an expression statement and not a block statement is by rule a command statement. Each command statement is made up of a command, and optionally a single space and an argument list. The command is executed with the argument list, and it does not return a value. | ||
+ | * Command -- A command is some action to be performed, such as '' | ||
+ | |||
+ | That's it, really! Unlike most normal programming languages, ircII has no builtin block statements or flow control. Whereas other languages have native flow control built in, these things are Command Statements in ircII. | ||
+ | |||
+ | Basic Flow Control: | ||
+ | It's assumed if you're reading this document you already know about the command statements that control things on irc (like JOIN and SERVER). But you probably are not familiar with how to do things like if's and while' | ||
+ | |||
+ | The basic flow control commands in ircII are: | ||
+ | |||
+ | if (expression) { | ||
+ | block | ||
+ | } | ||
+ | |||
+ | If the value of the expression (described generally above, and specifically below) is true, execute the block of code. | ||
+ | |||
+ | Wait -- here is an important aside -- it is important to understand that '' | ||
+ | |||
+ | The '' | ||
+ | |||
+ | if (expression) { | ||
+ | block | ||
+ | } else { | ||
+ | block | ||
+ | } | ||
+ | |||
+ | If the value of the expression is true, execute the first block of code, and if it is false, execute the second block of code. | ||
+ | |||
+ | if (expression) { | ||
+ | block | ||
+ | } elsif (expression) { | ||
+ | block | ||
+ | } else { | ||
+ | block | ||
+ | } | ||
+ | |||
+ | If the value of the first expression is true, execute the first block of code, and if it is false, but the value of the second expression is true, execute the second block of code, and if they are both false, execute the third block of code. | ||
+ | |||
+ | while (expression) { | ||
+ | block | ||
+ | } | ||
+ | |||
+ | Execute the block of code forever, as long as the expression is true. If expression is false to begin with, then the block is not executed. You may run the '' | ||
+ | |||
+ | fe (words list) variable list { | ||
+ | block | ||
+ | } | ||
+ | |||
+ | Loop over the Space Separated List of Words, putting them into local variables and then executing the block of code. The list of words must be surrounded by parenthesis. The variable list can contain 1 to 254 space separated variable names. The block of code must be surrounded by curly braces. The variables you provide are regular local variables, so they will clobber any local variables by the same name, and they will retain their final value when the command is finished. You may use the '' | ||
+ | |||
+ | Wildcard patterns: | ||
+ | |||
+ | About scripts: | ||
+ | When the EPIC client starts up, it reads a special startup script (usually '' |
epic_scripting.txt · Last modified: 2013/09/11 14:17 by 127.0.0.1