I'm new to SMLNJ. This works:
case (tts t2) of
(other, "<+") => parse_append t t2 ts pre c j
| (other, "<<-") => parse_sample t t2 ts pre c j
| (other, "<-") => parse_assign_or_sub t t2 ts pre c j
| (_, _) => error t2 "parse_stmt: Expected sample, append or assignment operator."
(other
is of type "datatype tokentype", t and t2 are tokens and tts
maps a token to a pair (tokentype, content)
. The rest is context-specific and not important here.)
But it's not very modular. Especially as I'm matching against the same operators in multiple places and I don't want them repeated all over the place. So I attempted this, which doesn't work:
(* this should go in a separate file of declarations *)
structure Ops = struct
val APPEND = "<+"
val SAMPLE = "<<-"
val ASSIGN = "<-"
end
(* this stays in the code *)
case (tts t2) of
(other, Op.APPEND) => parse_append t t2 ts pre c j
| (other, Op.SAMPLE) => parse_sample t t2 ts pre c j
| (other, Op.ASSIGN) => parse_assign_or_sub t t2 ts pre c j
| (_, _) => error t2 "parse_stmt: Expected sample, append or assignment operator."
Apparently you can't pattern-match against the value of a variable (which makes sense, in a way). Is there any kind of "constant" declaration I can apply to the operator definitions so that I can put their values in a separate module, or is there some other nice way to do this in SMLNJ?
You can make them constructors:
datatype Op = APPEND | ...
and then tokenize your stream
datatype Token = Op of Op | Id of string | ...
and then your pattern match can be
case (tts t2) of
(other, APPEND) => ...