Conj function has been added

This commit is contained in:
Sameer Rahmani 2020-01-01 16:28:14 +00:00
parent 1788aaf866
commit 39a28bd780
5 changed files with 90 additions and 18 deletions

View File

@ -31,7 +31,7 @@ import static java.util.Arrays.asList;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ListNode<T extends Node> extends Node implements Iterable<T> {
public class ListNode<T> extends Node implements Iterable<T> {
public static final ListNode<?> EMPTY = new ListNode<>();
public final T first;
@ -51,11 +51,11 @@ public class ListNode<T extends Node> extends Node implements Iterable<T> {
}
@SafeVarargs
public static <T extends Node> ListNode<T> list(T... objs) {
public static <T> ListNode<T> list(T... objs) {
return list(asList(objs));
}
public static <T extends Node> ListNode<T> list(List<T> objs) {
public static <T> ListNode<T> list(List<T> objs) {
ListNode<T> l = (ListNode<T>) EMPTY;
for (int i = objs.size() - 1; i >= 0; i--) {
l = l.cons(objs.get(i));
@ -73,7 +73,12 @@ public class ListNode<T extends Node> extends Node implements Iterable<T> {
List<Object> args = new ArrayList<Object>();
for (T node : this.rest()) {
args.add(node.eval(scope));
if (node instanceof Node) {
args.add(((Node) node).eval(scope));
}
else {
args.add(node);
}
}
if (firstElement.name.startsWith(".")) {
@ -102,7 +107,7 @@ public class ListNode<T extends Node> extends Node implements Iterable<T> {
throws SereneException {
String mName = firstElement.name.substring(1, firstElement.name.length());
Object target = this.rest().first().eval(scope);
Object target = this.evalNode(scope, this.rest().first());
if (mName.startsWith("-")) {
return this.evalInteropProperty(
@ -179,9 +184,10 @@ public class ListNode<T extends Node> extends Node implements Iterable<T> {
@Override
public T next() {
if (this.l == EMPTY) {
if (this.l == EMPTY || this.l.length == 0) {
return null;
}
T first = this.l.first;
this.l = this.l.rest;
return first;
@ -200,8 +206,13 @@ public class ListNode<T extends Node> extends Node implements Iterable<T> {
}
String output = "(" + this.first();
for(Node x : this.rest()) {
output = output + " " + x.toString();
for(T x : this.rest()) {
if (x != null) {
output = output + " " + x.toString();
}
else {
output = output + " nil";
}
}
return output + ")";
@ -214,4 +225,8 @@ public class ListNode<T extends Node> extends Node implements Iterable<T> {
return target.getClass();
}
private Object evalNode(IScope s, T node) {
return node instanceof Node ? ((Node) node).eval(s) : node;
}
}

View File

@ -37,6 +37,8 @@ import java.io.FileInputStream;
* * Primitive functions in Serene. I implemented lots of primitive functions
* in java rather than Serene itself mostly because of two reasons. Lack of
* macros and namespaces.
* * Decent [functional] data structures. The only data structure I implemented
* is list.
* * Quality code. The general quality of this implementation is not great, I
* sacrificed quality for time.
*/
@ -88,15 +90,14 @@ public class Main {
result = n.eval(rootScope);
}
if (result != ListNode.EMPTY) {
System.out.print(";; ");
if (result == null) {
System.out.println("nil");
}
else {
System.out.println(result.toString());
}
System.out.print(";; ");
if (result == null) {
System.out.println("nil");
}
else {
System.out.println(result.toString());
}
}
catch(Exception e) {
System.out.println("Error: ");

View File

@ -107,8 +107,9 @@ public class Reader {
while (true) {
int ch = inputStream.read();
if(isWhiteSpace(ch) || isClosingChar(ch) || ch == -1) {
// 65535 comes from the fact that unsigned -1 is 65535 so unreading -1
// puts 65535 in the buffer of pushbackreader
if(isWhiteSpace(ch) || isClosingChar(ch) || ch == -1 || ch == 65535) {
inputStream.unread(ch);
break;
};

View File

@ -43,6 +43,8 @@ public class RootScope extends AScope {
put("and", new AndFn());
put("or", new OrFn());
put("not", new NotFn());
put("conj", new ConjFn());
//put("reduce", new ReduceFn());
put("System", System.class);
put("Boolean", Boolean.class);
put("String", String.class);

View File

@ -0,0 +1,53 @@
/**
* Serene (simple) - A PoC lisp to collect data on Serenes concepts
* Copyright (C) 2019-2020 Sameer Rahmani <lxsameer@gnu.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package serene.simple.builtin;
import java.util.List;
import serene.simple.IScope;
import serene.simple.ListNode;
import serene.simple.SereneException;
public class ConjFn extends AFn {
public String fnName() {
return "conj";
};
public Object eval(IScope scope) throws SereneException{
List<Object> args = this.arguments();
if (args.size() == 0) {
return ListNode.EMPTY;
}
if (args.size() == 1) {
return args.get(0);
}
ListNode<Object> list = (ListNode<Object>) args.get(0);
for (Object x : args.subList(1, args.size())) {
list = new ListNode<Object>(x, list);
}
return list;
}
}