1
3 package jminusminus;
4
5 import java.util.ArrayList;
6
7
10 abstract class JAST {
11
14 public static JCompilationUnit compilationUnit;
15
16
19 protected int line;
20
21
26 protected JAST(int line) {
27 this.line = line;
28 }
29
30
35 public int line() {
36 return line;
37 }
38
39
45 public abstract JAST analyze(Context context);
46
47
54 public void partialCodegen(Context context, CLEmitter partial) {
55 }
57
58
63 public abstract void codegen(CLEmitter output);
64
65
70 public void toJSON(JSONElement json) {
71 }
73
74
80 public static String unescape(String s) {
81 StringBuffer b = new StringBuffer();
82 for (int i = 0; i < s.length(); i++) {
83 char c = s.charAt(i);
84 if (c == '\\') {
85 i++;
86 if (i >= s.length()) {
87 break;
88 }
89 c = s.charAt(i);
90 switch (c) {
91 case 'b':
92 b.append('\b');
93 break;
94 case 't':
95 b.append('\t');
96 break;
97 case 'n':
98 b.append('\n');
99 break;
100 case 'f':
101 b.append('\f');
102 break;
103 case 'r':
104 b.append('\r');
105 break;
106 case '"':
107 b.append('"');
108 break;
109 case '\'':
110 b.append('\'');
111 break;
112 case '\\':
113 b.append('\\');
114 break;
115 }
116 } else {
117 b.append(c);
118 }
119 }
120 return b.toString();
121 }
122 }
123
124
127 class JSONElement {
128 private ArrayList<String> attrNames;
130
131 private ArrayList<String> attrValues;
133
134 private ArrayList<String> childrenNames;
136
137 private ArrayList<JSONElement> children;
139
140 private int indentation;
142
143
146 public JSONElement() {
147 this.attrNames = new ArrayList<String>();
148 this.attrValues = new ArrayList<String>();
149 this.childrenNames = new ArrayList<String>();
150 this.children = new ArrayList<JSONElement>();
151 indentation = 0;
152 }
153
154
160 public void addAttribute(String name, String value) {
161 attrNames.add(name);
162 attrValues.add(value);
163 }
164
165
171 public void addAttribute(String name, ArrayList<String> value) {
172 attrNames.add(name);
173 attrValues.add(value.toString());
174 }
175
176
182 public void addChild(String name, JSONElement child) {
183 child.indentation = indentation + 4;
184 childrenNames.add(name);
185 children.add(child);
186 }
187
188
193 public String toString() {
194 StringBuilder sb = new StringBuilder();
195 if (indentation > 0) {
196 sb.append(String.format("%" + indentation + "s", " "));
197 }
198 sb.append("{\n");
199 for (int i = 0; i < attrNames.size(); i++) {
200 String name = attrNames.get(i);
201 String value = attrValues.get(i);
202 sb.append(String.format("%" + (indentation + 4) + "s", " "));
203 if (value.startsWith("[") && value.endsWith("]")) {
204 sb.append(String.format("\"%s\": %s", name, value));
205 } else {
206 sb.append(String.format("\"%s\": \"%s\"", name, value));
207 }
208 if (i < attrNames.size() - 1 || childrenNames.size() > 0) {
209 sb.append(",\n");
210 } else {
211 sb.append("\n");
212 }
213 }
214 for (int i = 0; i < childrenNames.size(); i++) {
215 String name = childrenNames.get(i);
216 JSONElement child = children.get(i);
217 sb.append(String.format("%" + (indentation + 4) + "s", " "));
218 sb.append(String.format("\"%s\":\n", name));
219 sb.append(child.toString());
220 if (i < childrenNames.size() - 1) {
221 sb.append(",\n");
222 } else {
223 sb.append("\n");
224 }
225 }
226 if (indentation > 0) {
227 sb.append(String.format("%" + indentation + "s", " "));
228 }
229 sb.append("}");
230 return sb.toString();
231 }
232 }
233