package ash.vm;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import ash.compiler.Compiler;
import ash.lang.BasicType;
import ash.lang.CharNode;
import ash.lang.LazyNode;
import ash.lang.ListUtils;
import ash.lang.MacroExpander;
import ash.lang.Node;
import ash.parser.Parser;
import bruce.common.utils.CommonUtils;

public final class JavaMethod implements Serializable {
	private static final long serialVersionUID = -933603269059202413L;
	private static final Map<String, JavaMethod> CACHE = new HashMap<>();
	
	String methodName;

	private JavaMethod(String name) { methodName = name; }
	
	public static JavaMethod create(String methodName) {
		JavaMethod javaMethod = CACHE.get(methodName);
		if (javaMethod == null) {
			javaMethod = new JavaMethod(methodName);
			CACHE.put(methodName, javaMethod);
		}
		return javaMethod;
	}

	@Override
	public String toString() {
		return '.' + methodName;
	}

	@SuppressWarnings("unchecked")
	public Serializable call(Serializable[] args) {
		switch (methodName) {
		case "stream":
			if (args.length == 1)
				return LazyNode.create(args[0], BasicType.NIL);
			return LazyNode.create(args[0], args[1]);
		case "num?":
			return ListUtils.transformBoolean(args[0] instanceof Number);
		case "puts":
			System.out.println(CommonUtils.displayArray(args, ""));
			break;
		case "str":
			return CommonUtils.displayArray(args, "");
		case "seq":
			if (args[0] instanceof String)
				return CharNode.create((String) args[0]);
			else
				return ListUtils.toSeq(((Iterable<Serializable>) args[0]).iterator());
		case "parse":
			return Parser.split((String) args[0]);
		case "compile":
			return Compiler.astsToInsts(new Node(args[0]));
		case "vmexec":
			return new VM().runInMain((Node) args[0]);
		case "new-macro":
			MacroExpander.MARCOS_MAP.put((String)args[0], (Node)args[1]);
			break;
		case "expand-macro":
			return MacroExpander.expand((Node) args[0]);
		default:
			throw new UnsupportedOperationException("Unsupport Java Call:" + methodName);
		}
		return BasicType.NIL;
	}

}

@@ -86,16 +86,48 @@
 til.Map;
+%0Aimport java.util.regex.Pattern;
 %0A%0Aimport
@@ -931,19 +931,17 @@
 ring() %7B
-%0A%09%09
+ 
 return '
@@ -956,18 +956,17 @@
 hodName;
-%0A%09
+ 
 %7D%0A%0A%09@Sup
@@ -1441,28 +1441,31 @@
 e %22seq%22:%0A%09%09%09
-if (
+return 
 args%5B0%5D inst
@@ -1477,28 +1477,23 @@
 f String
-)
 %0A%09%09%09%09
-return
+%09?
  CharNod
@@ -1522,28 +1522,15 @@
 %5B0%5D)
-;
 %0A%09%09%09
-else%0A%09%09%09%09return
+%09%09:
  Lis
@@ -1734,16 +1734,16 @@
 mexec%22:%0A
-
 %09%09%09retur
@@ -1772,32 +1772,93 @@
 Node) args%5B0%5D);%0A
+%09%09case %22regex%22:%0A%09%09%09return Pattern.compile((String) args%5B0%5D);%0A
 %09%09case %22new-macr

add .regex method