最近、自作言語を作ってみたというような人々をよく見る
僕もBF系のクソ言語作るか~ということで、その前準備として中間言語に変換するやつを作ってみた
言語仕様?は+、-、>、<、は末尾に連続して続く数を付ける、ドット、カンマ、[、]、はそのまま、という感じです
あと無駄なコードは最適化されます
+++--は+1、>>><<>は>2といった感じ
内容
こんなBFコードが
+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.++ +++++..+++.>-.------------.<++++++++.--------.+++.------.--------.>+.
こうなる
+9[>1+8>1+11>1+5<3-1]>1.>1+2.+7..+3.>1-1.-12.<1+8.-8.+3.-6.-8.>1+1.
フォルダ階層
C:/~/BFPREPROCESSOR/ ├─bfsource/ │ helloBF.bf │ ├─bin/ │ FirstOptimize.class │ ├─middleLang/ helloBF.mbf
使い方
java bin/FirstOptimize helloBF.bf
のように打つとmiddleLang/にhelloBF.mbfというファイル名で変換される
実装
いつものコードコピペの垂れ流しである...
import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayDeque; import java.util.Deque; public class FirstOptimize { static Deque<Character> deq = new ArrayDeque<>(200); static BufferedWriter bw; public static void main(String[] args) { if (args.length < 1) { throw new IllegalArgumentException("needs sourcefile name"); } String input = args[0]; String filename = getFileName(input); try { bw = new BufferedWriter(new FileWriter("middleLang/" + filename + ".mbf")); } catch (IOException e) { e.printStackTrace(); } System.out.println("start"); conversion(input); System.out.println("end"); } static String getFileName(String input) { String s; int dotPlace = input.lastIndexOf(".bf"); if (dotPlace == -1) { throw new IllegalArgumentException("this file is not bf file\nfilename example: helloworld.bf"); } int srasyu = input.lastIndexOf("/"); srasyu = Math.max(srasyu + 1, 0); s = input.substring(srasyu, dotPlace); return s; } static void conversion(String source) { try (FileReader r = new FileReader(source)) { char c; int i; while ((i = r.read()) != -1) { c = (char) i; addStack(c); } write(); bw.flush(); bw.close(); } catch (Exception e) { System.err.println("ファイル読み込み中にエラー発生"); e.printStackTrace(); } } static void addStack(char c) { char[] validChars = { '+', '-', '>', '<', '.', ',', '[', ']' }; boolean flag = true; for (char okC : validChars) { if (c == okC) { flag = false; break; } } if (flag) return; if (!deq.isEmpty()) { char lastItem = deq.getLast(); if (c == '+' && lastItem == '-') { deq.pollLast(); return; } else if (c == '-' && lastItem == '+') { deq.pollLast(); return; } else if (c == '>' && lastItem == '<') { deq.pollLast(); return; } else if (c == '<' && lastItem == '>') { deq.pollLast(); return; } else if (c == lastItem && (c == '+' || c == '-' || c == '<' || c == '>')) { deq.offerLast(c); } else { write(); deq.offerLast(c); } } else { deq.offerLast(c); } } static void write() { char c = deq.getLast(); try { if (c == '[' || c == ']' || c == '.' || c == ',') { bw.write(String.valueOf(c)); } else { bw.write(String.valueOf(c) + deq.size()); } } catch (IOException e) { System.err.println("ファイル書き込み中にエラー"); e.printStackTrace(); } deq.clear(); } }
一応解説
最初はファイル名をえいえいする部分、後は一文字ずつ読んでいく
読んだ文字がBFの有効な8文字なら、スタックに積む
スタックの最後が+で今から積むのが-、など、最適化できるところは最適化する
違う種類が入れられると、ファイルに書き出す