Skip to content

Commit

Permalink
fix read and eval of Lists, Sets, and Maps
Browse files Browse the repository at this point in the history
  • Loading branch information
NPException committed Nov 12, 2018
1 parent 041e38b commit 62ed37f
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 2 deletions.
40 changes: 40 additions & 0 deletions src/main/java/de/npecomplete/mc/testproject/lisp/Lisp.java
@@ -1,7 +1,12 @@
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.Sequence;
import de.npecomplete.mc.testproject.lisp.data.Symbol;
Expand Down Expand Up @@ -95,6 +100,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;
}
}
Expand Up @@ -9,6 +9,7 @@
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.stream.IntStream;

import de.npecomplete.mc.testproject.lisp.LispException;
Expand Down Expand Up @@ -125,7 +126,9 @@ private static void buildCollection(Collection<Object> base, Token end, Iterator
if (value == end) {
return;
}
base.add(value);
if (!base.add(value) && base instanceof Set) {
throw new LispException("Duplicate key in set literal: " + value);
}
}
throw new LispException("Encountered end of data while reading a collection");
}
Expand All @@ -139,7 +142,11 @@ private static Object buildMap(Iterator<Token> it) {
Map<Object, Object> map = new HashMap<>(mapContents.size());
Iterator mapIt = mapContents.iterator();
while (mapIt.hasNext()) {
map.put(mapIt.next(), mapIt.next());
Object key = mapIt.next();
if (map.containsKey(key)) {
throw new LispException("Duplicate key in map literal: " + key);
}
map.put(key, mapIt.next());
}
return Collections.unmodifiableMap(map);
}
Expand Down

0 comments on commit 62ed37f

Please sign in to comment.