A very naive string node has been added
This commit is contained in:
parent
79312f29ff
commit
7f0a074ddd
|
@ -1,19 +1,19 @@
|
|||
package serene.simple;
|
||||
|
||||
public class NumberNode extends Node {
|
||||
private final Long value;
|
||||
private final Long value;
|
||||
|
||||
public NumberNode(Long v) {
|
||||
this.value = v;
|
||||
}
|
||||
public NumberNode(Long v) {
|
||||
this.value = v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object eval(BaseScope scope) {
|
||||
return this.value;
|
||||
}
|
||||
@Override
|
||||
public Object eval(BaseScope scope) {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s", this.value);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s", this.value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,120 +10,141 @@ import java.util.List;
|
|||
|
||||
|
||||
public class Reader {
|
||||
public static Node readNode(PushbackReader inputStream) throws IOException, IllegalArgumentException, SereneException {
|
||||
char c = (char) inputStream.read();
|
||||
public static Node readNode(PushbackReader inputStream) throws IOException, IllegalArgumentException, SereneException {
|
||||
char c = (char) inputStream.read();
|
||||
inputStream.unread(c);
|
||||
|
||||
if (c == '(') {
|
||||
return readList(inputStream);
|
||||
}
|
||||
else if (Character.isDigit(c)) {
|
||||
return readNumber(inputStream);
|
||||
}
|
||||
else if (c == '"') {
|
||||
return readString(inputStream);
|
||||
}
|
||||
else if (c == ')') {
|
||||
throw new IllegalArgumentException("Unmatch paranthesis.");
|
||||
}
|
||||
else {
|
||||
return readSymbol(inputStream);
|
||||
}
|
||||
}
|
||||
|
||||
public static ListNode<Node> read(InputStream inputStream) throws IOException, IllegalArgumentException, SereneException {
|
||||
return read(new PushbackReader(new InputStreamReader(inputStream)));
|
||||
}
|
||||
|
||||
public static ListNode<Node> read(PushbackReader inputStream) throws IOException, IllegalArgumentException, SereneException {
|
||||
List<Node> nodes = new ArrayList<Node>();
|
||||
skipWhiteSpaces(inputStream);
|
||||
|
||||
char c = (char) inputStream.read();
|
||||
while ((byte) c != -1) {
|
||||
inputStream.unread(c);
|
||||
nodes.add(readNode(inputStream));
|
||||
skipWhiteSpaces(inputStream);
|
||||
c = (char) inputStream.read();
|
||||
}
|
||||
|
||||
return ListNode.list(nodes);
|
||||
}
|
||||
|
||||
private static Node readList(PushbackReader inputStream) throws IOException, SereneException {
|
||||
char opening = (char) inputStream.read();
|
||||
assert opening == '(' : "Lists must start with a '('";
|
||||
|
||||
List<Node> nodes = new ArrayList<Node>();
|
||||
|
||||
do {
|
||||
skipWhiteSpaces(inputStream);
|
||||
char c = (char) inputStream.read();
|
||||
|
||||
if (c == ')') {
|
||||
break;
|
||||
} else if ((byte) c == -1) {
|
||||
throw new EOFException("EOF reached before closing of list");
|
||||
} else {
|
||||
inputStream.unread(c);
|
||||
nodes.add(readNode(inputStream));
|
||||
}
|
||||
} while(true);
|
||||
|
||||
if (c == '(') {
|
||||
return readList(inputStream);
|
||||
}
|
||||
else if (Character.isDigit(c)) {
|
||||
return readNumber(inputStream);
|
||||
}
|
||||
else if (c == ')') {
|
||||
throw new IllegalArgumentException("Unmatch paranthesis.");
|
||||
}
|
||||
else {
|
||||
return readSymbol(inputStream);
|
||||
}
|
||||
}
|
||||
return SpecialForm.check(ListNode.list(nodes));
|
||||
}
|
||||
|
||||
public static ListNode<Node> read(InputStream inputStream) throws IOException, IllegalArgumentException, SereneException {
|
||||
return read(new PushbackReader(new InputStreamReader(inputStream)));
|
||||
}
|
||||
private static Node readSymbol(PushbackReader inputStream) throws IOException {
|
||||
String str = "";
|
||||
|
||||
public static ListNode<Node> read(PushbackReader inputStream) throws IOException, IllegalArgumentException, SereneException {
|
||||
List<Node> nodes = new ArrayList<Node>();
|
||||
skipWhiteSpaces(inputStream);
|
||||
|
||||
char c = (char) inputStream.read();
|
||||
while ((byte) c != -1) {
|
||||
inputStream.unread(c);
|
||||
nodes.add(readNode(inputStream));
|
||||
skipWhiteSpaces(inputStream);
|
||||
c = (char) inputStream.read();
|
||||
}
|
||||
|
||||
return ListNode.list(nodes);
|
||||
}
|
||||
|
||||
private static Node readList(PushbackReader inputStream) throws IOException, SereneException {
|
||||
char opening = (char) inputStream.read();
|
||||
assert opening == '(' : "Lists must start with a '('";
|
||||
|
||||
List<Node> nodes = new ArrayList<Node>();
|
||||
|
||||
do {
|
||||
skipWhiteSpaces(inputStream);
|
||||
char c = (char) inputStream.read();
|
||||
|
||||
if (c == ')') {
|
||||
break;
|
||||
} else if ((byte) c == -1) {
|
||||
throw new EOFException("EOF reached before closing of list");
|
||||
} else {
|
||||
inputStream.unread(c);
|
||||
nodes.add(readNode(inputStream));
|
||||
}
|
||||
} while(true);
|
||||
|
||||
return SpecialForm.check(ListNode.list(nodes));
|
||||
}
|
||||
|
||||
private static Node readSymbol(PushbackReader inputStream) throws IOException {
|
||||
String str = "";
|
||||
|
||||
while (true) {
|
||||
int ch = inputStream.read();
|
||||
|
||||
if(isWhiteSpace(ch) || isClosingChar(ch) || ch == -1) {
|
||||
inputStream.unread(ch);
|
||||
break;
|
||||
};
|
||||
str = str + (char) ch;
|
||||
}
|
||||
|
||||
switch(str) {
|
||||
case "true":
|
||||
return new TrueNode();
|
||||
case "false":
|
||||
return new FalseNode();
|
||||
case "nil":
|
||||
return new NilNode();
|
||||
default:
|
||||
return new SymbolNode(str);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static Node readNumber(PushbackReader inputStream) throws IOException {
|
||||
int ch = inputStream.read();
|
||||
String number = "";
|
||||
|
||||
while (Character.isDigit((char) ch)) {
|
||||
number = number + (char) ch;
|
||||
ch = inputStream.read();
|
||||
}
|
||||
while (true) {
|
||||
int ch = inputStream.read();
|
||||
|
||||
if(isWhiteSpace(ch) || isClosingChar(ch) || ch == -1) {
|
||||
inputStream.unread(ch);
|
||||
return new NumberNode(Long.parseLong(number, 10));
|
||||
break;
|
||||
};
|
||||
str = str + (char) ch;
|
||||
}
|
||||
|
||||
private static void skipWhiteSpaces(PushbackReader inputStream) throws IOException {
|
||||
int ch = inputStream.read();
|
||||
|
||||
while (isWhiteSpace(ch)) {
|
||||
ch = inputStream.read();
|
||||
}
|
||||
inputStream.unread(ch);
|
||||
switch(str) {
|
||||
case "true":
|
||||
return new TrueNode();
|
||||
case "false":
|
||||
return new FalseNode();
|
||||
case "nil":
|
||||
return new NilNode();
|
||||
default:
|
||||
return new SymbolNode(str);
|
||||
}
|
||||
|
||||
private static boolean isWhiteSpace(int ch) {
|
||||
return (ch == ' ' || ch == '\t' || ch == '\f' || ch == '\r' || ch == '\n');
|
||||
}
|
||||
|
||||
private static Node readNumber(PushbackReader inputStream) throws IOException {
|
||||
int ch = inputStream.read();
|
||||
String number = "";
|
||||
|
||||
while (Character.isDigit((char) ch)) {
|
||||
number = number + (char) ch;
|
||||
ch = inputStream.read();
|
||||
}
|
||||
|
||||
private static boolean isClosingChar(int ch) {
|
||||
return (ch == ')' || ch == ']' ||
|
||||
ch == '}');
|
||||
inputStream.unread(ch);
|
||||
return new NumberNode(Long.parseLong(number, 10));
|
||||
}
|
||||
|
||||
private static Node readString(PushbackReader inputStream) throws IOException {
|
||||
char opening = (char) inputStream.read();
|
||||
assert opening == '"' : "Strings should start with \"";
|
||||
String str = "";
|
||||
|
||||
while (true) {
|
||||
char ch = (char) inputStream.read();
|
||||
|
||||
if(ch == '"') {
|
||||
break;
|
||||
}
|
||||
str = str + ch;
|
||||
};
|
||||
|
||||
return new StringNode(str);
|
||||
|
||||
}
|
||||
|
||||
private static void skipWhiteSpaces(PushbackReader inputStream) throws IOException {
|
||||
int ch = inputStream.read();
|
||||
|
||||
while (isWhiteSpace(ch)) {
|
||||
ch = inputStream.read();
|
||||
}
|
||||
inputStream.unread(ch);
|
||||
}
|
||||
|
||||
private static boolean isWhiteSpace(int ch) {
|
||||
return (ch == ' ' || ch == '\t' || ch == '\f' || ch == '\r' || ch == '\n');
|
||||
}
|
||||
|
||||
private static boolean isClosingChar(int ch) {
|
||||
return (ch == ')' || ch == ']' ||
|
||||
ch == '}');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package serene.simple;
|
||||
|
||||
public class StringNode extends Node {
|
||||
private final String value;
|
||||
|
||||
public StringNode(String v) {
|
||||
this.value = v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object eval(BaseScope scope) {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue