'キーを変えるプログラム(たぶん不具合だらけ)(!コマンド対応する気になってしまった)
'サブ関数
'調号以外を与えると0、調号を与えると半音上昇なら1、半音下降なら-1を返す(ネーミングセンスをくれ)
DEF ACCIDENTAL(A$)
RETURN (A$=="#")+(A$=="+")-(A$=="-") 'Naさんが良いワンライナーをくれたので採用
END
'MMLの音長を表せる文字か判別する。(面倒なので)
'中身は読者の課題とする
DEF ISMMLLEN(M$)
RETURN INSTR("0123456789.&_",M$)>=0 'Naさんの回答
END
'メイン関数と定数群
'↓お好きな一方をコメントアウトする
'VAR _K$="C C+D D+E F F+G G+A A+B "
'VAR _K$="C D-D E-E F G-G A-A B-B "
VAR _TC=LEN(_K$)/2
DEF KEYCHANGE$(_M$,K)
VAR I,J,V,OC,M$=_M$+"",T$
FOR I=0 TO LEN(M$)-1
'VはC基準の音階の差(度数とは別物)
'Jはインデックス差(Iをむやみに変えられないので)
'OCはオクターブ差
V=INSTR("C D EF G A B",M$[I])
IF V==-1 || V==1 THEN CONTINUE
IF I>=1 && M$[I-1]!="@" && MID$(M$,MAX(I-4,0),4)!="@MOF" THEN
J=1
WHILE (I+J)<=LEN(M$) && ACCIDENTAL(M$[I+J])
INC V,ACCIDENTAL(M$[I+J])
INC J
WEND
OC=V DIV _TC:V=V MOD _TC
IF V<0 THEN V=V+_TC
T$=MID$(_K$,V*2,2)
IF T$[1]==" " THEN T$[1]=""
WHILE (I+J)<=LEN(M$) && ISMMLLEN(M$[I+J])
T$=T$+M$[I+J]
INC J
WEND
IF OC<0 THEN T$=(">"*-OC)+T$+("<"*-OC)
IF OC>0 THEN T$=("<"*OC)+T$+(">"*OC)
M$=SUBST$(M$,I,J,T$)
I=I+J-1
ENDIF
NEXT
RETURN M$
END