Penguin
Note: You are viewing an old revision of this page. View the current version.

GCBot is an IRC bot that Isomer? made to see what happens if you give a bunch of programmers a shared programming environment (IRC) and what happens.

GCBot's programming language is very simple, everything is either a symbol, a function call, a list, a string or a number.

The grammer is very simple

<literal>::= "string"

| 'string' | 0-9?\.0-9?

<symbol> ::= ^,()\[\?]

<comma-expression> ::= <expression>

| <expression> ',' <comma-expression>

<symbol-or-literal> ::= <symbol>

| <literal>

<term> ::= '' <comma-expression> '?'

| <symbol-or-literal>

<expression> ::= <term>

| <term> '(' <comma-expression ')'

  • strings, lists and numbers, when called with no arguments evaluate to themselves
  • everything is prefix notation, eg: to add four numbers, you need to do +(1,2,3,4)

Builtins:

+(args...)

Returns the sum of all of it's arguments

/(args...)

Returns the first argument divided by the second etc.

<(a,b)

Returns non zero if a is less than b, 0 otherwise.

->string(x)

Returns the string representation of x. Beware, this does not evaluate x.

apply(expression,list of arguments)

Calls expression with arguments.

eg
apply(+,1,2,3?)

at(list,expression)

Returns the expressionth item in list

catch(expression,exception handler)

Calls expression, if an exception is raised, then exception handler is called with the exception passed as the only argument.

decompose(functioncall)

Returns a list of the head of the function call, a the list of the arguments.

eg
decompose(+(1,2,3)) => +,[1,2,3?]

define(name,vars,expression)

This works like lambda, however it also binds it to a name. define could have been implemented as
lambda(name,vars,expression?,set(name,lambda(vars,expression)))

head(list)

Returns the first item of list.

ifelse(cond,true,false)

This function evaluates cond, then evaluates either true or false depending on the result of cond. Anything that isn't 0 is considered true.

lambda(vars,expression)

Takes a list of variables, and when called replaces each variable with it's corresponding positional argument everywhere in the expression. For example
lambda(a,b?,+(a,b))
will create an anonymous function that takes two arguments (a and b) and returns their sum. eg
lambda(a,b?,+(a,b))(1,2) => 3

beaware that the bindings of lambda's variables can be cached, so if a function can return different values every time it's called, you may end up with some unexpected results.

now()

Returns the number of seconds since 1970-01-01. Beaware that this function changes it's result everytime you call it, and may interact badly with lambda's primative caching.

say(channel,expression)

Will say in channel the result of expression

set(name,expression)

Binds expression to name.

syms()

Returns the list of all symbols that are currently defined in the symbol table.

tail(list)

Returns everything but the first item of list.

throw(string)

Throws an exception given by string.

undef(name)

Unbinds name, returning the previous expression that name was bound to.

eg
define(rename,old,new?,set(new,undef(old)))