Conj function has been added
This commit is contained in:
parent
1788aaf866
commit
39a28bd780
|
@ -31,7 +31,7 @@ import static java.util.Arrays.asList;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
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 static final ListNode<?> EMPTY = new ListNode<>();
|
||||||
|
|
||||||
public final T first;
|
public final T first;
|
||||||
|
@ -51,11 +51,11 @@ public class ListNode<T extends Node> extends Node implements Iterable<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SafeVarargs
|
@SafeVarargs
|
||||||
public static <T extends Node> ListNode<T> list(T... objs) {
|
public static <T> ListNode<T> list(T... objs) {
|
||||||
return list(asList(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;
|
ListNode<T> l = (ListNode<T>) EMPTY;
|
||||||
for (int i = objs.size() - 1; i >= 0; i--) {
|
for (int i = objs.size() - 1; i >= 0; i--) {
|
||||||
l = l.cons(objs.get(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>();
|
List<Object> args = new ArrayList<Object>();
|
||||||
|
|
||||||
for (T node : this.rest()) {
|
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(".")) {
|
if (firstElement.name.startsWith(".")) {
|
||||||
|
@ -102,7 +107,7 @@ public class ListNode<T extends Node> extends Node implements Iterable<T> {
|
||||||
throws SereneException {
|
throws SereneException {
|
||||||
|
|
||||||
String mName = firstElement.name.substring(1, firstElement.name.length());
|
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("-")) {
|
if (mName.startsWith("-")) {
|
||||||
return this.evalInteropProperty(
|
return this.evalInteropProperty(
|
||||||
|
@ -179,9 +184,10 @@ public class ListNode<T extends Node> extends Node implements Iterable<T> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T next() {
|
public T next() {
|
||||||
if (this.l == EMPTY) {
|
if (this.l == EMPTY || this.l.length == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
T first = this.l.first;
|
T first = this.l.first;
|
||||||
this.l = this.l.rest;
|
this.l = this.l.rest;
|
||||||
return first;
|
return first;
|
||||||
|
@ -200,8 +206,13 @@ public class ListNode<T extends Node> extends Node implements Iterable<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
String output = "(" + this.first();
|
String output = "(" + this.first();
|
||||||
for(Node x : this.rest()) {
|
for(T x : this.rest()) {
|
||||||
output = output + " " + x.toString();
|
if (x != null) {
|
||||||
|
output = output + " " + x.toString();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
output = output + " nil";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return output + ")";
|
return output + ")";
|
||||||
|
@ -214,4 +225,8 @@ public class ListNode<T extends Node> extends Node implements Iterable<T> {
|
||||||
|
|
||||||
return target.getClass();
|
return target.getClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Object evalNode(IScope s, T node) {
|
||||||
|
return node instanceof Node ? ((Node) node).eval(s) : node;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,8 @@ import java.io.FileInputStream;
|
||||||
* * Primitive functions in Serene. I implemented lots of primitive functions
|
* * Primitive functions in Serene. I implemented lots of primitive functions
|
||||||
* in java rather than Serene itself mostly because of two reasons. Lack of
|
* in java rather than Serene itself mostly because of two reasons. Lack of
|
||||||
* macros and namespaces.
|
* 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
|
* * Quality code. The general quality of this implementation is not great, I
|
||||||
* sacrificed quality for time.
|
* sacrificed quality for time.
|
||||||
*/
|
*/
|
||||||
|
@ -88,15 +90,14 @@ public class Main {
|
||||||
result = n.eval(rootScope);
|
result = n.eval(rootScope);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result != ListNode.EMPTY) {
|
System.out.print(";; ");
|
||||||
System.out.print(";; ");
|
if (result == null) {
|
||||||
if (result == null) {
|
System.out.println("nil");
|
||||||
System.out.println("nil");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
System.out.println(result.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
System.out.println(result.toString());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch(Exception e) {
|
catch(Exception e) {
|
||||||
System.out.println("Error: ");
|
System.out.println("Error: ");
|
||||||
|
|
|
@ -107,8 +107,9 @@ public class Reader {
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
int ch = inputStream.read();
|
int ch = inputStream.read();
|
||||||
|
// 65535 comes from the fact that unsigned -1 is 65535 so unreading -1
|
||||||
if(isWhiteSpace(ch) || isClosingChar(ch) || ch == -1) {
|
// puts 65535 in the buffer of pushbackreader
|
||||||
|
if(isWhiteSpace(ch) || isClosingChar(ch) || ch == -1 || ch == 65535) {
|
||||||
inputStream.unread(ch);
|
inputStream.unread(ch);
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,6 +43,8 @@ public class RootScope extends AScope {
|
||||||
put("and", new AndFn());
|
put("and", new AndFn());
|
||||||
put("or", new OrFn());
|
put("or", new OrFn());
|
||||||
put("not", new NotFn());
|
put("not", new NotFn());
|
||||||
|
put("conj", new ConjFn());
|
||||||
|
//put("reduce", new ReduceFn());
|
||||||
put("System", System.class);
|
put("System", System.class);
|
||||||
put("Boolean", Boolean.class);
|
put("Boolean", Boolean.class);
|
||||||
put("String", String.class);
|
put("String", String.class);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue