A very naive string node has been added

This commit is contained in:
Sameer Rahmani 2019-12-19 23:11:18 +00:00
parent 79312f29ff
commit 7f0a074ddd
3 changed files with 156 additions and 116 deletions

View File

@ -1,19 +1,19 @@
package serene.simple; package serene.simple;
public class NumberNode extends Node { public class NumberNode extends Node {
private final Long value; private final Long value;
public NumberNode(Long v) { public NumberNode(Long v) {
this.value = v; this.value = v;
} }
@Override @Override
public Object eval(BaseScope scope) { public Object eval(BaseScope scope) {
return this.value; return this.value;
} }
@Override @Override
public String toString() { public String toString() {
return String.format("%s", this.value); return String.format("%s", this.value);
} }
} }

View File

@ -10,120 +10,141 @@ import java.util.List;
public class Reader { public class Reader {
public static Node readNode(PushbackReader inputStream) throws IOException, IllegalArgumentException, SereneException { public static Node readNode(PushbackReader inputStream) throws IOException, IllegalArgumentException, SereneException {
char c = (char) inputStream.read(); 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); inputStream.unread(c);
nodes.add(readNode(inputStream));
}
} while(true);
if (c == '(') { return SpecialForm.check(ListNode.list(nodes));
return readList(inputStream); }
}
else if (Character.isDigit(c)) {
return readNumber(inputStream);
}
else if (c == ')') {
throw new IllegalArgumentException("Unmatch paranthesis.");
}
else {
return readSymbol(inputStream);
}
}
public static ListNode<Node> read(InputStream inputStream) throws IOException, IllegalArgumentException, SereneException { private static Node readSymbol(PushbackReader inputStream) throws IOException {
return read(new PushbackReader(new InputStreamReader(inputStream))); String str = "";
}
public static ListNode<Node> read(PushbackReader inputStream) throws IOException, IllegalArgumentException, SereneException { while (true) {
List<Node> nodes = new ArrayList<Node>(); int ch = inputStream.read();
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();
}
if(isWhiteSpace(ch) || isClosingChar(ch) || ch == -1) {
inputStream.unread(ch); inputStream.unread(ch);
return new NumberNode(Long.parseLong(number, 10)); break;
};
str = str + (char) ch;
} }
private static void skipWhiteSpaces(PushbackReader inputStream) throws IOException { switch(str) {
int ch = inputStream.read(); case "true":
return new TrueNode();
while (isWhiteSpace(ch)) { case "false":
ch = inputStream.read(); return new FalseNode();
} case "nil":
inputStream.unread(ch); 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) { inputStream.unread(ch);
return (ch == ')' || ch == ']' || return new NumberNode(Long.parseLong(number, 10));
ch == '}'); }
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 == '}');
}
} }

View File

@ -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;
}
}