4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

和音プログラミング言語のPlaygroundの共有リンクについて

4
Last updated at Posted at 2025-12-19

TL; DR

  • playgroundの共有リンクでソースコードを共有
  • 各命令をアルファベットに変換しクエリパラメータに格納

はじめに

今年のはじめに、Brainf*ck系のEsolang 「Cholc」を作成しました。

A A A A A A A A A |: F G E Am :| F Fm |: C C C C C C C C A A A B Em :| C Cm X |: Db Eb Eb Eb Eb Eb C C C Fm :| C C X |: C C#m :| Cm Cm X X C C C X Ebm X D Dm A A A A A X |: F G Cm :| Gm X F Fm X F F F X Gm Gm D F# Bm |: Gm D F# Bm :| Gm X |: Gm Dm :| G X A X
Hello, world!

Cholcでは、音楽のコード進行によって計算を行います("Chord" + "Calculate" でCholcです)。

operator role
{メジャーコード} ポインタが指す値をインクリメント
{マイナーコード} ポインタが指す値をデクリメント
|: ポインタが指す値が0のとき、対応する :| の直後へ飛ぶ
:| ポインタが指す値が0でないとき、対応する |: の直後へ飛ぶ
v 入力から1バイト読み込み(asciiとして)ポインタへ保存する
X ポインタが指す値を(asciiとして)出力へ書き出す

ポインタ移動はコードとコードの間で行われ、その距離は「完全5度いくつ分離れているか」によって決まります(詳しくは過去の記事をご覧ください)。

image.png

Playgroundでは実際に和音が鳴りながらプログラムが実行されるので、ぜひ試してみてください。

そして、せっかくPlaygroundを用意したので、書いたソースコードを他人に共有できるようにしたいです。
本記事では、共有リンクの実装方法について紹介します。

共有リンク

共有リンクとしてよくあるのがサーバー側にソースコードを保存するパターンです。
ただし今回はGitHub Pagesで完結させたかったため、UI1だけで共有リンクを作る方法を検討しました。

ソースコードをクエリパラメータに埋め込む

そこで、ソースコードをまるごとクエリパラメータに埋め込むことにしました。

playgroundのURL
https://syuparn.github.io/cholc
URLのクエリパラメータpにソースコード情報を埋め込む
https://syuparn.github.io/cholc/?p=abc

Cholcには命令が28種類2しかありません。そのため、英数字[a-z0-9]の36種類あれば1文字で1命令を表すことができます。

cholcソースコード
C C# D
クエリパラメータにエンコードされたソースコード
abc
命令をエンコード
function codeToQuery(code: ByteCode): string {
  // 変換できないものは無視
  if (code === byteCodes.Unknown) {
    return ""
  }

  // 英数字(a, b, c, ..., z, 0, ..., 9)に変換
  const alphabetOffset = "a".charCodeAt(0)
  const numOffset = "0".charCodeAt(0)
  if (code < 26) {
    return String.fromCharCode(code + alphabetOffset)
  }
  if (code < 36) {
    return String.fromCharCode(code - 26 + numOffset) 
  }

  throw new Error(`code must not be ${code}`)
}

逆に、クエリパラメータが与えられた場合は命令にデコードすることでソースコードを復元します。

ただし、命令のバイトコードを使用している都合上以下の制約があり、完全に復元することはできません。

  • 命令でない文字列(コメント等)はエンコードできず消えてしまう
  • 表記の違う同じコード(異名同音、C#Db 等)は処理系のデフォルトの表記に統一されてしまう3

コメントが消えてしまうのは少し不便なので、今後改修するかもしれません。

(余談)命令のバイトコード化

ここからは余談です。
先に述べたように、命令は内部的にバイトコードに変換されています。

音程の順に並べることで、コード進行によるポインタ移動量を計算しやすくしています。
(バイトコードの差を12で割ったあまりが「半音何個分離れているか」を表す)

和音 バイトコード
C 0
C# 1
D 2
... ...
B 11
Cm 12
... ...
Bm 23

特殊な命令 バイトコード
` :`
`: `
, 26
X 27

ポインタ移動は、2つの和音の音程が完全5度(=半音7個)何個分であるかで計算可能です。

ポインタ移動量の計算
export function keySignatureMove(pitch1: number, pitch2: number): number {
  let pitch = pitch1
  // move: ポインタ移動量
  // 音程が同じになるまで完全5度1つ分ずつ音程を上げて比較
  for (let move = 0; move < 12; move++) {
    if (pitch == pitch2) {
      // 完全5度5個分以上進む場合はマイナスとして扱う(前述の五度圏の図を参照)
      return move > 5 ? move - 12 : move
    }

    // 完全5度1つ分音程を上げる
    pitch = (pitch + 7) % 12
  }

  throw new Error(`must not be reacted: pitch1: "${pitch1}", pitch2: "${pitch2}"`)
}

おわりに

以上、playgroundのリンクでソースコードを共有する方法の紹介でした。
Esolangなら同様の方法が使えると思うので、皆さんも試してみてはいかがでしょうか?

  1. Webサービスのいわゆるフロントエンドですが、言語実装で「フロントエンド」と書くとコンパイラのフロントエンドと紛らわしいですね...

  2. メジャーコード12種 + マイナーコード12種 + 特殊な命令4種

  3. UIに表示されているボタンと同じ表記になります(例のC#, Db であれば Db)。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?