package org.mozartoz.truffle;

import java.io.File;
import java.io.IOException;

import org.mozartoz.truffle.nodes.OzRootNode;
import org.mozartoz.truffle.translator.Translator;

import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.vm.PolyglotEngine;

public class Main {

	public static final PolyglotEngine ENGINE = PolyglotEngine.newBuilder().build();

	public static final String PROJECT_ROOT = getProjectRoot();

	public static void main(String[] args) throws IOException {
		eval("{Show 3 + 2}");
		eval("local A=3 B=2 in {Show A + B} end");
		eval("local fun {Inc Arg} Arg + 1 end in {Show {Inc 1}} end");
		eval("local Fact in\nfun {Fact N} if N == 0 then 1 else N * {Fact N-1} end end\n{Show {Fact 30}}\nend");
		eval("local L in L = [1 2 3] {Show L} {Show L.1} {Show L.2} end");
		eval("local A in A=1+2 {Show A} end");
		eval("local A B in A=B B=42 {Show B} {Show A} end");

		eval("local Add in fun {Add A B} A + B end {Show {Add 2 4}} end");
		eval("local H=5 V T in T=V V=[6 7 8] {Show H|T} end");
		eval("local H=5 V T in V=T {Show H|T} {proc {$} V=[6 7 8] end} {Show H|T} end");
		eval("local fun {Binder A} A=43 unit end X R in R={Binder X} {Show X} end");

		eval("local Tree=tree(left:1 right:2) in {Show Tree} {Show Tree.left} end");

		eval("local F=functor\n import\n Property(get)\n export\n Return\n define\n Return=42\n end in {Show F} end");

		eval("local fun {MakeList N} if N>0 then _|{MakeList N-1} else nil end end in {Show {MakeList 3}} end");

		eval("local fun {Append Xs Ys} case Xs of nil then Ys [] X|Xr then X|{Append Xr Ys} end end in {Show {Append [1 2] [3 4]}} end");

		eval("local fun {Member X Ys} case Ys of nil then false [] Y|Yr then X==Y orelse {Member X Yr} end end in {Show {Member nil [1 2 3]}} end");

		Source source = Source.fromFileName(PROJECT_ROOT + "/test.oz");
		eval(source.getCode());
	}

	private static void eval(String code) {
		// ENGINE.eval(Source.fromText(code, "test.oz").withMimeType(OzLanguage.MIME_TYPE));
		parseAndExecute(code);
	}

	public static void parseAndExecute(String code) {
		execute(new Translator().parseAndTranslate(code));
	}

	private static Object execute(OzRootNode rootNode) {
		return Truffle.getRuntime().createCallTarget(rootNode).call();
	}

	private static String getProjectRoot() {
		String thisFile = Main.class.getProtectionDomain().getCodeSource().getLocation().getPath();
		String path = new File(thisFile).getParent();
		return path;
	}

}

@@ -537,1283 +537,8 @@
 n %7B%0A
-%09%09eval(%22%7BShow 3 + 2%7D%22);%0A%09%09eval(%22local A=3 B=2 in %7BShow A + B%7D end%22);%0A%09%09eval(%22local fun %7BInc Arg%7D Arg + 1 end in %7BShow %7BInc 1%7D%7D end%22);%0A%09%09eval(%22local Fact in%5Cnfun %7BFact N%7D if N == 0 then 1 else N * %7BFact N-1%7D end end%5Cn%7BShow %7BFact 30%7D%7D%5Cnend%22);%0A%09%09eval(%22local L in L = %5B1 2 3%5D %7BShow L%7D %7BShow L.1%7D %7BShow L.2%7D end%22);%0A%09%09eval(%22local A in A=1+2 %7BShow A%7D end%22);%0A%09%09eval(%22local A B in A=B B=42 %7BShow B%7D %7BShow A%7D end%22);%0A%0A%09%09eval(%22local Add in fun %7BAdd A B%7D A + B end %7BShow %7BAdd 2 4%7D%7D end%22);%0A%09%09eval(%22local H=5 V T in T=V V=%5B6 7 8%5D %7BShow H%7CT%7D end%22);%0A%09%09eval(%22local H=5 V T in V=T %7BShow H%7CT%7D %7Bproc %7B$%7D V=%5B6 7 8%5D end%7D %7BShow H%7CT%7D end%22);%0A%09%09eval(%22local fun %7BBinder A%7D A=43 unit end X R in R=%7BBinder X%7D %7BShow X%7D end%22);%0A%0A%09%09eval(%22local Tree=tree(left:1 right:2) in %7BShow Tree%7D %7BShow Tree.left%7D end%22);%0A%0A%09%09eval(%22local F=functor%5Cn import%5Cn Property(get)%5Cn export%5Cn Return%5Cn define%5Cn Return=42%5Cn end in %7BShow F%7D end%22);%0A%0A%09%09eval(%22local fun %7BMakeList N%7D if N%3E0 then _%7C%7BMakeList N-1%7D else nil end end in %7BShow %7BMakeList 3%7D%7D end%22);%0A%0A%09%09eval(%22local fun %7BAppend Xs Ys%7D case Xs of nil then Ys %5B%5D X%7CXr then X%7C%7BAppend Xr Ys%7D end end in %7BShow %7BAppend %5B1 2%5D %5B3 4%5D%7D%7D end%22);%0A%0A%09%09eval(%22local fun %7BMember X Ys%7D case Ys of nil then false %5B%5D Y%7CYr then X==Y orelse %7BMember X Yr%7D end end in %7BShow %7BMember nil %5B1 2 3%5D%7D%7D end%22);%0A%0A
 %09%09So

move to test.oz