To first answer your question about the die/1, you are using COPY to get a range of multiple values out of the source block. You probably want SET to get a single value:
>> parse [d12] [copy die word! (probe die)]
[d12]
== true
>> parse [d12] [set die word! (probe die)]
d12
== true
So concretely:
dice-rule: [
(total: 0)
some [
set die word!
(total: total + roll 1 get die)
|
set n integer!
set die word!
(total: total + roll n get die)
]
]
Broad dialect design concern: you've decided that a symbolic word that looks up to an integer will represent a dice roll of that integer value. You then have another meaning for literal integer values. This ties your hands a bit because it means you can't do ordinary variable substitution.
For instance, what if instead of:
dice: [d2 20 d100 d10 5 d6]
I wanted to write:
x: 20
y: 5
dice: [d2 x d100 d10 y d6]
You could use get-word for this form of non-dice substitution:
dice: [d2 :x d100 d10 :y d6]
But the general heuristic of coming up with dialects is to only dig out a small bit of keyword space, so such an "ugliness" isn't necessary most of the time. Most dialects pick out a finite set of keywords, but there's probably nothing universally wrong with taking all the d*
words.
Yet consider a possible alternative, more like the substitutions in parse, where brackets would be optional:
dice: [
die 2
20 [die 100]
[die 10]
5 die 6
]
Which you might then allow as substitutions, maybe:
d2: [die 2]
d100: [die 100]
d10: [die 10]
d6: [die 6]
dice: [d2 20 d100 d10 5 d6]
Further, I'd think that the dialect (which you might call dice-roll
) should provide all the values of the roll. It's easy enough to sum if that's what people want...but sometimes you might want the highest value, or lowest, or know if there were any doubles of the same value/etc.
Other quick notes. If you know b is a block, say so in the function specification:
calculate: function [b [block!]] [
...
That checks the type at the callsite, and in Red it offers more of an advantage for static typing in the compiler.
I'd define roll
before I defined the dice-rule
. Also, by using a func
instead of a function
you are allowing result
to bleed into the calculate function body. If you don't have a good reason for that, I'd avoid it... func
shouldn't be used for performance reasons, but rather when you really do not want to introduce a new context.
Especially if you go with my suggestion to make die
a word in your dialect, I might use another word for the integer representing the number of possibilities on the die...perhaps something like radix.