Brainfuck
Что-то взбрело в голову и решил написать интерпретатор Brainfuck’а :) Вот что получилось:
Сам Интерпретатор
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | //BFInt.java public class BFInt { /** * Указатель на текущую ячейку памяти */ private int pointer; /** * Память */ private Memory mem; /** * Текст Программы */ private byte[] text; /** * Указатель на текущую инструкцию */ private int pinst; /** * Выходная лента */ private String out; /** * Входная лента */ private String in; /** * Указатель на входной символ */ private int pin; /** * Конструктор * @param s - тест программы * @param i - входная строка */ public BFInt(String s, String i){ mem = new Memory(); pointer = 0; text = s.getBytes(); in = i; out = ""; pinst = 0; } /** * Переход на следующую ячейку памяти */ private void nextCeil(){ pointer++; pinst++; } /** * Переход на предыдущую ячейку памяти */ private void prevCeil(){ pointer--; pinst++; } /** * Увеличить значение на 1 */ private void incValue(){ char cur = mem.getValue(pointer); mem.setValue(pointer,(char)((cur+1)%256)); pinst++; } /** * Уменьшить значение на 1 */ private void decValue(){ char cur = mem.getValue(pointer); mem.setValue(pointer,(char)((cur+255)%256)); pinst++; } /** * поведение при чтении '[' */ private void goForrward(){ char cur = mem.getValue(pointer); int count = 1; if (cur == 0){ int i = pinst+1; for (; i < text.length; i++){ if (text[i]=='[') {count++;} if (text[i]==']') {count--;} if (count == 0 )break; } pinst = i; } else { pinst++; } } /** * поведение при чтении ']' */ private void goBack(){ char cur = mem.getValue(pointer); int count = 1; if (cur != 0){ int i = pinst-1; for (; i >= 0; i--){ if (text[i]=='[') {count--;} if (text[i]==']') {count++;} if (count == 0 )break; } pinst = i; } else { pinst++; } } /** * Запись на выходную ленту */ private void print(){ char cur = mem.getValue(pointer); out += cur; pinst++; } /** * Чтение с входной ленты */ private void read(){ mem.setValue(pointer,in.charAt(pin)); pin++; pinst++; } public String run(){ while(pinst < text.length && pinst >=0){ switch(text[pinst]){ case '>':nextCeil();break; case '<':prevCeil();break; case '+':incValue();break; case '-':decValue();break; case '[':goForrward();break; case ']':goBack();break; case '.':print();break; case ',':read();break; default:System.out.println("Error"); } } return out; } } |
И класс памяти, решил вот так реализовать.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | //Memory.java public class Memory { /** * Указатель на нулевую ячейку */ private int pointerzero; /** * Память */ private char[] memory; /** * Конструктор */ public Memory(){ pointerzero = 0; memory = new char [1]; } /** * Геттер * @param pointer - указатель на ячейку, значение которой нужно получить * @return - значение ячейки, на которую указывает pointer */ public char getValue(int pointer){ int newpointer = pointerzero + pointer; if ( memory.length > newpointer && newpointer >= 0){ return memory[newpointer]; } else { char [] tmp = new char[(newpointer>0)?newpointer+1:memory.length+Math.abs(newpointer)]; for (int i = 0; i < tmp.length; i++){ tmp[i] = 0; } for (int i =0, k=(newpointer>0?0:Math.abs(newpointer)); i < memory.length; i++){ tmp[k++] = memory[i]; } memory = tmp; if (newpointer < 0 ){ pointerzero += Math.abs(newpointer); } return 0; } } /** * Сеттер * @param pointer - указатель на ячейку * @param value - новое значение */ public void setValue(int pointer,char value){ int newpointer = pointerzero + pointer; if ( memory.length > newpointer && newpointer >= 0){ memory[newpointer] = value; } else { char [] tmp = new char[(newpointer>0)?newpointer+1:memory.length+Math.abs(newpointer)]; for (int i = 0; i < tmp.length; i++){ tmp[i] = 0; } for (int i =0, k=(newpointer>0?0:Math.abs(newpointer)); i < memory.length; i++){ tmp[k++] = memory[i]; } memory = tmp; if (newpointer > 0){ memory[newpointer] = value; } else { memory[0] = value; pointerzero += Math.abs(newpointer); } } } } |