diff options
Diffstat (limited to 'plugins/eval')
-rwxr-xr-x | plugins/eval | 312 |
1 files changed, 0 insertions, 312 deletions
diff --git a/plugins/eval b/plugins/eval deleted file mode 100755 index 982d78b..0000000 --- a/plugins/eval +++ /dev/null @@ -1,312 +0,0 @@ -#!/usr/bin/awk -f -# -# ZyklonB eval plugin, LISP-like expression evaluator -# -# Copyright 2013, 2014 Přemysl Janouch -# See the file LICENSE for licensing information. -# - -BEGIN \ -{ - RS = "\r" - ORS = "\r\n" - IGNORECASE = 1 - srand() - - prefix = get_config("prefix") - - print "ZYKLONB register" - fflush("") - - # All functions have to be in this particular array - min_args["int"] = 1 - min_args["+"] = 1 - min_args["-"] = 1 - min_args["*"] = 1 - min_args["/"] = 1 - min_args["%"] = 1 - min_args["^"] = 1 - min_args["**"] = 1 - min_args["exp"] = 1 - min_args["sin"] = 1 - min_args["cos"] = 1 - min_args["atan2"] = 2 - min_args["log"] = 1 - min_args["rand"] = 0 - min_args["sqrt"] = 1 - - min_args["pi"] = 0 - min_args["e"] = 0 - - min_args["min"] = 1 - min_args["max"] = 1 - - # Whereas here their presence is only optional - max_args["int"] = 1 - max_args["sin"] = 1 - max_args["cos"] = 1 - max_args["atan2"] = 2 - max_args["log"] = 1 - max_args["rand"] = 0 - max_args["sqrt"] = 1 - - max_args["pi"] = 0 - max_args["e"] = 0 -} - -{ - parse($0) -} - -msg_command == "PRIVMSG" \ -{ - # Context = either channel or user nickname - match(msg_prefix, /^[^!]+/) - ctx = substr(msg_prefix, RSTART, RLENGTH) - if (msg_param[0] ~ /^[#&!+]/) - { - ctx_quote = ctx ": " - ctx = msg_param[0] - } - else - ctx_quote = "" - - - if (substr(msg_param[1], 1, length(prefix)) == prefix) - { - keyword = "eval" - text = substr(msg_param[1], 1 + length(prefix)) - if (match(text, "^" keyword "([^A-Za-z0-9].*|$)")) - process_request(substr(text, 1 + length(keyword))) - } -} - -{ - fflush("") -} - -function pmrespond (text) -{ - print "PRIVMSG " ctx " :" ctx_quote text -} - -function process_request (input, res, x) -{ - delete funs - delete accumulator - delete n_args - - res = "" - fun_top = 0 - funs[0] = "" - accumulator[0] = 0 - n_args[0] = 0 - - if (match(input, "^[ \t]*")) - input = substr(input, RLENGTH + 1) - if (input == "") - res = "expression missing" - - while (res == "" && input != "") { - if (match(input, "^-?[0-9]+\\.?[0-9]*")) { - x = substr(input, RSTART, RLENGTH) - input = substr(input, RLENGTH + 1) - - match(input, "^ *") - input = substr(input, RLENGTH + 1) - - res = process_argument(x) - } else if (match(input, "^[(]([^ ()]+)")) { - x = substr(input, RSTART + 1, RLENGTH - 1) - input = substr(input, RLENGTH + 1) - - match(input, "^ *") - input = substr(input, RLENGTH + 1) - - if (!(x in min_args)) { - res = "undefined function '" x "'" - } else { - fun_top++ - funs[fun_top] = x - accumulator[fun_top] = 636363 - n_args[fun_top] = 0 - } - } else if (match(input, "^[)] *")) { - input = substr(input, RLENGTH + 1) - res = process_end() - } else - res = "invalid input at '" substr(input, 1, 10) "...'" - } - - if (res == "") { - if (fun_top != 0) - res = "unclosed '" funs[fun_top] "'" - else if (n_args[0] != 1) - res = "internal error, expected one result" \ - ", got " n_args[0] " instead" - } - - if (res == "") - pmrespond(accumulator[0]) - else - pmrespond(res) -} - -function process_argument (arg) -{ - if (fun_top == 0) { - if (n_args[0]++ != 0) - return "too many results, I only expect one" - - accumulator[0] = arg - return "" - } - - fun = funs[fun_top] - if (fun in max_args && max_args[fun] <= n_args[fun_top]) - return "too many operands for " fun - - if (fun == "int") { - accumulator[fun_top] = int(arg) - } else if (fun == "+") { - if (n_args[fun_top] == 0) - accumulator[fun_top] = arg - else - accumulator[fun_top] += arg - } else if (fun == "-") { - if (n_args[fun_top] == 0) - accumulator[fun_top] = arg - else - accumulator[fun_top] -= arg - } else if (fun == "*") { - if (n_args[fun_top] == 0) - accumulator[fun_top] = arg - else - accumulator[fun_top] *= arg - } else if (fun == "/") { - if (n_args[fun_top] == 0) - accumulator[fun_top] = arg - else if (arg == 0) - return "division by zero" - else - accumulator[fun_top] /= arg - } else if (fun == "%") { - if (n_args[fun_top] == 0) - accumulator[fun_top] = arg - else if (arg == 0) - return "division by zero" - else - accumulator[fun_top] %= arg - } else if (fun == "^" || fun == "**" || fun == "exp") { - if (n_args[fun_top] == 0) - accumulator[fun_top] = arg - else - accumulator[fun_top] ^= arg - } else if (fun == "sin") { - accumulator[fun_top] = sin(arg) - } else if (fun == "cos") { - accumulator[fun_top] = cos(arg) - } else if (fun == "atan2") { - if (n_args[fun_top] == 0) - accumulator[fun_top] = arg - else - accumulator[fun_top] = atan2(accumulator[fun_top], arg) - } else if (fun == "log") { - accumulator[fun_top] = log(arg) - } else if (fun == "rand") { - # Just for completeness, execution never gets here - } else if (fun == "sqrt") { - accumulator[fun_top] = sqrt(arg) - } else if (fun == "min") { - if (n_args[fun_top] == 0) - accumulator[fun_top] = arg - else if (accumulator[fun_top] > arg) - accumulator[fun_top] = arg - } else if (fun == "max") { - if (n_args[fun_top] == 0) - accumulator[fun_top] = arg - else if (accumulator[fun_top] < arg) - accumulator[fun_top] = arg - } else - return "internal error, unhandled operands for " fun - - n_args[fun_top]++ - return "" -} - -function process_end () -{ - if (fun_top <= 0) - return "extraneous ')'" - - fun = funs[fun_top] - if (!(fun in min_args)) - return "internal error, unhandled ')' for '" fun "'" - if (min_args[fun] > n_args[fun_top]) - return "not enough operands for '" fun "'" - - # There's no 'init' function to do it in - if (fun == "rand") - accumulator[fun_top] = rand() - else if (fun == "pi") - accumulator[fun_top] = 3.141592653589793 - else if (fun == "e") - accumulator[fun_top] = 2.718281828459045 - - return process_argument(accumulator[fun_top--]) -} - -function get_config (key) -{ - print "ZYKLONB get_config :" key - fflush("") - - getline - parse($0) - return msg_param[0] -} - -function parse (line, s, n, id, token) -{ - s = 1 - id = 0 - - # NAWK only uses the first character of RS - if (line ~ /^\n/) - line = substr(line, 2) - - msg_prefix = "" - msg_command = "" - delete msg_param - - n = match(substr(line, s), / |$/) - while (n) - { - token = substr(line, s, n - 1) - if (token ~ /^:/) - { - if (s == 1) - msg_prefix = substr(token, 2) - else - { - msg_param[id] = substr(line, s + 1) - break - } - } - else if (!msg_command) - msg_command = toupper(token) - else - msg_param[id++] = token - - s = s + n - n = index(substr(line, s), " ") - - if (!n) - { - n = length(substr(line, s)) + 1 - if (n == 1) - break; - } - } -} - |