1 package acl2s.lib.parse.obj;
2
3 import acl2s.lib.parse.IParseContext;
4 import acl2s.lib.parse.ParseException;
5 import acl2s.lib.parse.Parser;
6 import acl2s.lib.parse.SymOrNumFns;
7
8 public class Char extends Atom {
9 private static final long serialVersionUID = 2L;
10
11 protected final char c;
12
13 private Char(char c) { this.c = c; }
14
15 public char getChar() { return c; }
16
17 String computeString(IParseContext pc) {
18 for (int i = 0; i < named.length; i++) {
19 if (c == named[i]) {
20 return "#\\" + names[i];
21 }
22 }
23 return "#\\" + c;
24 }
25
26 static char[] named = {
27 '\n', ' ', '\177', '\f', '\t', /*'\b', '\r', '\n'*/ };
28 static String[] names = {
29 "Newline", "Space", "Rubout", "Page", "Tab", /*"Backspace", "Return", "Linefeed"*/ };
30
31 public static Character lookupName(String s) {
32 if (s.length() < 3) return null;
33 for (int i = 0; i < names.length; i++) {
34 if (names[i].equalsIgnoreCase(s)) {
35 return new Character(named[i]);
36 }
37 }
38 return null;
39 }
40
41 public static Char parse(Parser p) throws ParseException {
42 if (p.pop() != '#' || p.pop() != '\\') {
43 throw new ParseException("Character constant must start with #\\.");
44 }
45 StringBuilder b = new StringBuilder();
46 char c = p.pop();
47 if (c != Parser.EOF) {
48 b.append(c);
49 } else {
50 throw new ParseException("EOF within character constant.");
51 }
52 for(;;) {
53 c = p.peek();
54 if (SymOrNumFns.isTerminator(c)) break;
55 b.append(c);
56 p.pop();
57 }
58 String s = b.toString();
59 if (s.length() == 1) {
60 return new Char(s.charAt(0));
61 } else {
62 Character v = lookupName(s);
63 if (v != null) {
64 return new Char(v.charValue());
65 }
66 //otherwise
67 throw new ParseException("Unrecognized character name: \"" + s + "\".");
68 }
69 }
70
71 public boolean equals(Object o) {
72 return (o instanceof Char) && this.c == ((Char)o).c;
73 }
74
75 public boolean isPrintableOrNamed() {
76 if (c >= 32 && c <= 127) return true;
77 for (int i = 0; i < named.length; i++) {
78 if (c == named[i]) return true;
79 }
80 return false;
81 }
82
83
84
85 public static Char get(int i) {
86 if (i < 0 || i > 255) throw new IllegalArgumentException("ACL2/Lisp characters are from 0-255");
87 return instances[i];
88 }
89
90 static final Char[] instances = new Char[256];
91
92 static {
93 for (char i = 0; i <= 255; i++) {
94 instances[i] = new Char(i);
95 }
96 }
97 }