Home

Awesome

CodeMania

CodeManiaは、Beatmania IIDXという音楽ゲームに着想を得たプログラミング言語です。

特徴

コードの解釈について

コマンド一欄

コマンドは以下のような割り振りを基調としていますが、一部例外もあるので確認するのが一番確実です。

<img src="https://i.imgur.com/5OXmBZX.png" width="320px">

標準入出力

コマンド名前機能
10 10 00 00文字列入力文字列型を自由変数に標準入力
10 01 00 00文字列出力文字列型の自由変数を標準出力(改行なし)
10 01 00 01〃(改行あり)
01 10 00 00数値入力整数型の自由変数に標準入力
01 01 00 00数値出力整数型の自由変数を標準出力(改行なし)
01 01 00 01〃(改行あり)

スタック操作

本言語における各データ型の変数は、「自由変数」と「スタック」の2種類のみです。基本的に演算は自由変数のみに対して行えるため、これらの間でデータを上手くやりとりすることが鍵となります。

コマンド名前機能
10 00 01 00文字列push文字列スタックに自由変数をpushする
10 00 10 00文字列pop文字列スタックの先頭を削除する
10 00 10 01文字列top文字列スタックの先頭を自由変数にcopyする
10 00 11 00文字列swap文字列スタックの先頭と自由変数を交換する
01 00 01 00数値push数値スタックに自由変数をpushする
01 00 10 00数値pop数値スタックの先頭を削除する
01 00 10 01数値top数値スタックの先頭を自由変数にcopyする
01 00 11 00数値swap数値スタックの先頭と自由変数を交換する

特に、先頭をコピーすることでスタックの先頭が削除されるわけではない点に要注意です。

文字型と文字列型

文字型は他2つのデータ型と比べて若干弱く、スタックが存在しません。これは、文字型は文字列型の自由変数をより操作しやすくするために導入したという経緯から来ています。ということで、文字型の操作は文字列型の自由変数とのやり取りが主となります。

コマンド名前機能
11 00 01 00文字push文字変数を文字列変数の末尾に挿入する
11 00 10 01文字back文字列変数の末尾を文字変数にcopyする

文字列変数を文字のスタックと見れば、概ね上とコマンドは同じです。

リテラル処理

本言語には数値やアルファベットを記述することができません。そこで、コマンド用鍵盤をbit列と見なすことでその役割を代理させています。

コマンド名前機能
11 00 00 00文字リテラル挿入モードに移動。入力されたbit列のASCIIコードに対応する文字を文字変数に代入する
01 00 00 00整数リテラル挿入モードに移動。まず入力したい数値のbyte長を入力する。その後byte長回だけ挿入モードになり、入力された数値が数値変数に代入される

例えば、文字変数にaを格納したい場合は

   __   _  aのASCIIコード、97=00110001を入力
 __        文字挿入モードへ移動

となり、また数値変数に142857 = 10 0010 1110 0000 1001を格納したい場合は

     _  _  0000 1001
   _ ___   0010 1110
       _   0000 0010
       __  3byte必要なので3を入力
  _        数値挿入モードへ移動

となります。

また、文字変数と数値変数はこれらで初期化できるのだが、文字列変数はそう簡単には初期化できない。そこで、文字列変数を初期化するコマンドも実装してあります。

コマンド名前機能
10 00 00 00文字列初期化文字列変数を初期化する

数値演算

基本的な数値演算5種も実装してあります。これらは数値変数に対して数値スタックの先頭要素を作用させるようにしました。

コマンド名前機能
01 11 00 00加算数値変数に数値スタックの先頭要素を加える
01 11 00 01減算数値変数から数値スタックの先頭要素を引く
01 11 00 10乗算数値変数に数値スタックの先頭要素を掛ける
01 11 00 11除算数値変数を数値スタックの先頭要素で割る(切り捨て)
01 11 00 11剰余算数値変数を数値スタックで割ったときの余りを出す

文字列演算

一応文字列にもわずかながら演算を用意しました。

コマンド名前機能
10 11 00 00文字列長文字列変数の長さを数値変数に代入する
10 11 00 11文字列反転文字列変数を反転させる

文字演算

文字と数値間の演算です。

コマンド名前機能
11 11 00 01キャスト(ASCII)文字列変数のASCIIコードを数値変数に代入
11 11 00 10キャスト(digit)文字列変数を数値と見たときの値を数値変数に代入
11 11 00 11文字加算文字列変数に数値変数を加算

コマンドは以上です。

制御構文

最後に制御構文についてです。本言語には非常に致命的なことに、if文が存在しません。そのかわりfor文とwhile文は存在します。

どちらの構文も基本は同じで、ループしたい部分全体の1文字目を|にするだけです。

for文は初めて|になったときのコマンドが0でないときに実行され、ループを開始時点での数値変数の値の回数だけ実行します。なお、最初の行のコマンドはループの頭で毎回実行されます。

一方while文は初めて|になったときのコマンドが0であったときに実行され、ループ終了時点での数値変数の値が0の場合だけループを抜けます。

コード例

以上で構文の説明は終わりです。最後に、この言語での実装例を参考程度に載せておきます。

 _  _   _
 __   _  
   _    _
 __      
 __   _  
  __  _  
 __      
 __   _  
  __ __  
 __      
 __   _  
  ___  _
 __      
 __   _  
  __ ____
 __      
 __   _  
  _ _ ___
 __      
 __   _  
   _
 __      
 __   _  
   _ __  
 __      
 __   _  
  __ ____
 __      
 __   _  
  __ __  
 __      
 __   _  
  __ __  
 __      
 __   _  
  __  _ _
 __      
 __   _  
  _  _   
 __      
  _ _   _  output
  _  __    swap
| _  __    swap
| _  _     pop
| ___      add
|
  _  __    swap
           0
        _  1
  _        num
| _   _    push
| ___      add
|       _  1
|       _  1
| _        num
  __       input
  _   _    push
           0
        _  1
  _        num