slack-roll-command/roll.pegjs

76 lines
1.8 KiB
JavaScript

/* 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)); }