Skip to content

Commit

Permalink
Merge branch 'var-args'
Browse files Browse the repository at this point in the history
  • Loading branch information
NPException committed Nov 22, 2018
2 parents 7604bba + 14d4670 commit e2d4207
Show file tree
Hide file tree
Showing 21 changed files with 838 additions and 532 deletions.
61 changes: 60 additions & 1 deletion src/main/java/de/npecomplete/mc/testproject/lisp/Lisp.java
@@ -1,8 +1,14 @@
package de.npecomplete.mc.testproject.lisp;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import de.npecomplete.mc.testproject.lisp.data.CoreLibrary;
import de.npecomplete.mc.testproject.lisp.data.Sequence;
import de.npecomplete.mc.testproject.lisp.data.Symbol;
import de.npecomplete.mc.testproject.lisp.function.LispFunction;
Expand All @@ -23,6 +29,24 @@ public void initStandardEnvironment() {
globalEnv.bind(new Symbol("if"), SpecialForm.IF);
globalEnv.bind(new Symbol("let"), SpecialForm.LET);
globalEnv.bind(new Symbol("quote"), SpecialForm.QUOTE);

globalEnv.bind(new Symbol("eval"), new LispFunction() {
@Override
public Object apply(Object par1) {
return eval(par1);
}
});

// TODO replace with interop in some yet-to-be-written core lisp file
globalEnv.bind(new Symbol("list"), CoreLibrary.FN_LIST);
globalEnv.bind(new Symbol("vector"), CoreLibrary.FN_VECTOR);
globalEnv.bind(new Symbol("hash-set"), CoreLibrary.FN_HASH_SET);
globalEnv.bind(new Symbol("hash-map"), CoreLibrary.FN_HASH_MAP);

globalEnv.bind(new Symbol("seq"), CoreLibrary.FN_SEQ);
globalEnv.bind(new Symbol("first"), CoreLibrary.FN_FIRST);
globalEnv.bind(new Symbol("next"), CoreLibrary.FN_NEXT);
globalEnv.bind(new Symbol("rest"), CoreLibrary.FN_REST);
}

public Object eval(Object obj) throws LispException {
Expand All @@ -37,7 +61,7 @@ public static Object eval(Object obj, Environment env) throws LispException {
if (obj instanceof Sequence) {
Sequence seq = (Sequence) obj;
if (seq.empty()) {
throw new LispException("Can't eval empty sequence");
throw new LispException("Can't evaluate empty list");
}
// evaluate first element
Object callable = eval(seq.first(), env);
Expand Down Expand Up @@ -95,6 +119,41 @@ public static Object eval(Object obj, Environment env) throws LispException {
+ "Call: " + call);
}

if (obj instanceof List) {
List<?> list = (List<?>) obj;
List<Object> result = new ArrayList<>();
for (Object o : list) {
result.add(eval(o, env));
}
return result;
}

if (obj instanceof Set) {
Set<?> set = (Set<?>) obj;
Set<Object> result = new HashSet<>(set.size() * 2);
for (Object o : set) {
Object key = eval(o, env);
if (result.contains(key)) {
throw new LispException("Set creation with duplicate key: " + key);
}
result.add(key);
}
return result;
}

if (obj instanceof Map) {
Map<?, ?> map = (Map<?, ?>) obj;
Map<Object, Object> result = new HashMap<>(map.size() * 2);
for (Entry e : map.entrySet()) {
Object key = eval(e.getKey(), env);
if (result.containsKey(key)) {
throw new LispException("Map creation with duplicate key: " + key);
}
result.put(key, eval(e.getValue(), env));
}
return result;
}

return obj;
}
}
14 changes: 10 additions & 4 deletions src/main/java/de/npecomplete/mc/testproject/lisp/Playground.java
Expand Up @@ -15,9 +15,15 @@
public class Playground {
private static final SpecialForm printlnForm = (args, env) -> {
System.out.print("> ");
while (args != null && !args.empty()) {
if (args != null && !args.empty()) {
System.out.print(Lisp.eval(args.first(), env));
args = args.next();
while (args != null) {
System.out.print(' ');
Object val = Lisp.eval(args.first(), env);
System.out.print(val == null ? "nil" : val);
args = args.next();
}
}
System.out.println();
return null;
Expand Down Expand Up @@ -48,7 +54,9 @@ private static void start() {
lisp.globalEnv.bind(new Symbol("println"), printlnForm);
lisp.globalEnv.bind(new Symbol("prn-str"), prnStrForm);

// next TODO: var-arg functions, macros, recur, loop
// TODO: switch from using java.util.List to own Vector class
// TODO: use "let" in function code for bindings and execution
// TODO: apply, macros, recur, loop

try (InputStream in = Playground.class.getResourceAsStream("/test.edn");
// try (InputStream in = System.in;
Expand All @@ -60,8 +68,6 @@ private static void start() {
} catch (IOException e) {
e.printStackTrace();
}

run(lisp, LispReader.readStr("is-dead"));
}

private static void run(Lisp lisp, Object form) {
Expand Down

This file was deleted.

0 comments on commit e2d4207

Please sign in to comment.