commit 1607b4be3f9624451a0a884d991f06c9e50c3413 Author: Kegan Myers Date: Fri Aug 8 23:01:16 2014 -0500 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b512c09 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..c48b0d8 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +slack-roll-command +================== +This command allows people to roll dice for slack. + +Usage: `/roll 2d6` \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..9e19475 --- /dev/null +++ b/index.js @@ -0,0 +1,23 @@ +var PEG = require('pegjs'), + path = require('path'), + fs = require('fs'); + +var parser = PEG.buildParser( + fs.readFileSync( + path.resolve(__dirname, "roll.pegjs") + ).toString() +); + +function roll(text) { + return "" + parser.parse(text); +} + +module.exports = function(ee) { + ee.on('roll', function(slack) { + try { + slack.replyUser(roll(slack.text)); + } catch (e) { + slack.error(e.toString()); + } + }); +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000..afb9485 --- /dev/null +++ b/package.json @@ -0,0 +1,29 @@ +{ + "name": "slack-roll-command", + "version": "0.0.0", + "description": "A slack command to roll dice", + "main": "index.js", + "dependencies": { + "pegjs": "^0.8.0" + }, + "devDependencies": {}, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "https://github.com/terribly-lazy/slack-roll-command.git" + }, + "keywords": [ + "slack", + "command", + "roll", + "dice" + ], + "author": "Kegan Myers ", + "license": "BSD 2-Clause", + "bugs": { + "url": "https://github.com/terribly-lazy/slack-roll-command/issues" + }, + "homepage": "https://github.com/terribly-lazy/slack-roll-command" +} diff --git a/roll.pegjs b/roll.pegjs new file mode 100644 index 0000000..f138877 --- /dev/null +++ b/roll.pegjs @@ -0,0 +1,75 @@ +/* This is a grammar written to be compiled by PEG.js, this is the most human readable form of the parser */ + +/* Here are our tokens that get spit out by our parser, then all combined once the "start" rule finishes */ + +{ + function TokenList(tokens) { + this.getValue = function() { + var tokenListResult = 0; + + for (var i = 0; i < tokens.length; i++) { + tokenListResult += tokens[i].getValue() + } + + return tokenListResult; + } + } + function AdditiveToken(valueToken) { + this.getValue = function() { + return valueToken.getValue(); + } + } + function SubtractiveToken(valueToken) { + this.getValue = function() { + return -1 * valueToken.getValue(); + } + } + function RollToken(countToken, sizeToken) { + this.getValue = function() { + //Figure out how many times we are rolling, and what size die to use. + var count = countToken.getValue(); + var size = sizeToken.getValue(); + + var rollResult = 0; + + for (var i = 0; i < count; i++) { + rollResult += Math.ceil(Math.random() * size); + } + + return rollResult; + } + } + function NumberToken(num) { + this.getValue = function() { + return num; + } + } +} + +/* Here is the grammar itself, what defines all the work that gets done parsing the input */ + +start += tokens:tokenList { return tokens.getValue() } + +tokenList += roll:dieRoll mod:modifier* {return new TokenList([roll, new TokenList(mod)]) } + +modifier += additive +/ subtractive + +additive += "+" number:number { return new AdditiveToken(number) } + +subtractive += "*" number:number { return new SubtractiveToken(number) } + +number += dieRoll +/ integer + +dieRoll += count:integer "d" size:integer { return new RollToken(count, size) } + +integer "integer" += digits:[0-9]+ { return new NumberToken(parseInt(digits.join(""), 10)); } \ No newline at end of file