996
|
1 // This software is Public Domain.
|
|
2
|
|
3 import java.util.Stack;
|
|
4 import java.io.*;
|
|
5
|
|
6 public class GlyphoInterpreter {
|
|
7 public static final char[] DEBUG_OPERATORS = "&".toCharArray();
|
|
8 public static final String VERSION = "0.2";
|
|
9 public static final char[] OPERATORS = "niod\\><!1+-*e[]".toCharArray();
|
|
10 public static final char EOL = 10;
|
|
11 public static final char COMMENT_START = '#';
|
|
12 public static final char COMMENT_END = EOL;
|
|
13 protected InputStream in;
|
|
14 protected OutputStream out;
|
|
15 protected PrintStream err;
|
|
16
|
|
17 protected static final char[][] shorthandOps = {
|
|
18 { 0, 'n'},
|
|
19 { 1, 'i'},
|
|
20 { 10, '>'},
|
|
21 { 11, '\\'},
|
|
22 { 12, '1'},
|
|
23 { 100, '<'},
|
|
24 { 101, 'd'},
|
|
25 { 102, '['},
|
|
26 { 110, '+'},
|
|
27 { 111, 'o'},
|
|
28 { 112, '*'},
|
|
29 { 120, '-'},
|
|
30 { 121, ']'},
|
|
31 { 122, '!'},
|
|
32 { 123, 'e'}
|
|
33 };
|
|
34
|
|
35
|
|
36 public GlyphoInterpreter() {
|
|
37 this(System.in, System.out, System.err);
|
|
38 }
|
|
39
|
|
40 public GlyphoInterpreter(InputStream in, OutputStream out, OutputStream err) {
|
|
41 this.in = in;
|
|
42 this.out = out;
|
|
43 this.err = new PrintStream(err);
|
|
44 }
|
|
45
|
|
46
|
|
47 public boolean interpret(String source, boolean shorthand) {
|
|
48
|
|
49 Operator o = tokenize(source, shorthand);
|
|
50 while (o != null) {
|
|
51 o.execute();
|
|
52 o = o.conditionalNext();
|
|
53 }
|
|
54
|
|
55 return true;
|
|
56 }//interpret()
|
|
57
|
|
58
|
|
59
|
|
60 public String removeComments(String source) {
|
|
61 StringBuffer buf = new StringBuffer(source);
|
|
62 int pos = 0, cStart=-1;
|
|
63 while (pos < buf.length()) {
|
|
64 if ((buf.charAt(pos)==COMMENT_START) && (cStart < 0)) cStart=pos;
|
|
65 if ((buf.charAt(pos)==COMMENT_END) && (cStart >= 0)) {
|
|
66 buf.delete(cStart, pos);
|
|
67 pos = cStart;
|
|
68 cStart=-1;
|
|
69 }
|
|
70 pos++;
|
|
71 }
|
|
72 if (cStart>0) buf.delete(cStart, buf.length());
|
|
73 return buf.toString();
|
|
74 }//removeComments
|
|
75
|
|
76 public static boolean isOperator(char ch) {
|
|
77 for (int i = 0; i < OPERATORS.length; i++) if (OPERATORS[i] == ch) return true;
|
|
78 for (int i = 0; i < DEBUG_OPERATORS.length; i++) if (DEBUG_OPERATORS[i] == ch) return true;
|
|
79 return false;
|
|
80 }
|
|
81
|
|
82
|
|
83 public Operator tokenize(String str, boolean shorthand) {
|
|
84 char[] source;
|
|
85 if (shorthand) {
|
|
86 source = removeComments(str).toCharArray();
|
|
87 }else{
|
|
88 source = new char[str.length() / 4];
|
|
89 char[] patterns = str.toCharArray();
|
|
90 for (int i = 0; i < source.length; i++) {
|
|
91 source[i] = getOperator(new int[]
|
|
92 {
|
|
93 (int)patterns[i*4],
|
|
94 (int)patterns[i*4 + 1],
|
|
95 (int)patterns[i*4 + 2],
|
|
96 (int)patterns[i*4 + 3]
|
|
97 }
|
|
98 );
|
|
99 }
|
|
100 }
|
|
101
|
|
102 Operator.in = in;
|
|
103 Operator.out = out;
|
|
104 Operator.err = err;
|
|
105 Operator operator = null, firstOperator = null;
|
|
106
|
|
107 for (int i = 0; i < source.length; i++) {
|
|
108 if (isOperator(source[i])) {
|
|
109 if (firstOperator == null) {
|
|
110 firstOperator = new Operator(source[i]);
|
|
111 operator = firstOperator;
|
|
112 }else{
|
|
113 operator.setNext(new Operator(source[i]));
|
|
114 operator = operator.next();
|
|
115 }
|
|
116 }
|
|
117 }
|
|
118 return firstOperator;
|
|
119 }//tokenize()
|
|
120
|
|
121 protected static String parsePattern(int[] pattern) {
|
|
122 String res = "0";
|
|
123 int n = 0;
|
|
124 for (int i = 1; i < pattern.length; i++) {
|
|
125 char ch = 0;
|
|
126 for (int j = 0; j < i; j++) {
|
|
127 if (pattern[i]==pattern[j]) {
|
|
128 ch = res.charAt(j);
|
|
129 break;
|
|
130 }
|
|
131 }
|
|
132 if (ch == 0) ch = (char)('0' + ++n);
|
|
133 res += ch;
|
|
134 }
|
|
135 return res;
|
|
136 }
|
|
137
|
|
138
|
|
139 public static char getOperator(int[] pattern) {
|
|
140 int opcode = (int)Integer.parseInt(parsePattern(pattern));
|
|
141
|
|
142 for (int i = 0; i < shorthandOps.length; i++) {
|
|
143 if (opcode == shorthandOps[i][0]) return shorthandOps[i][1];
|
|
144 }
|
|
145
|
|
146 return 0;
|
|
147 }
|
|
148
|
|
149 }//Class
|