package org.mozartoz.truffle.runtime;

import java.io.File;

import org.mozartoz.bootcompiler.BootCompiler;
import org.mozartoz.bootcompiler.ast.Statement;
import org.mozartoz.bootcompiler.symtab.Program;
import org.mozartoz.truffle.nodes.DerefNode;
import org.mozartoz.truffle.nodes.control.SequenceNode;
import org.mozartoz.truffle.nodes.literal.LiteralNode;
import org.mozartoz.truffle.nodes.local.InitializeTmpNode;
import org.mozartoz.truffle.nodes.local.InitializeVarNode;
import org.mozartoz.truffle.nodes.local.ReadLocalVariableNode;
import org.mozartoz.truffle.translator.BuiltinsRegistry;
import org.mozartoz.truffle.translator.Translator;

import com.oracle.truffle.api.RootCallTarget;
import com.oracle.truffle.api.frame.FrameSlot;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.Source;

public class TranslatorDriver {

	private final OzLanguage language;

	private boolean eagerLoad = false;

	public TranslatorDriver(OzLanguage language) {
		this.language = language;
		BootCompiler.registerParserToVM(ParserToVMImpl.INSTANCE);
	}

	public RootCallTarget parseBase(Source source) {
		Metrics.tick("enter parseBase");
		Program program = BootCompiler.buildBaseEnvProgram(source, BuiltinsRegistry.getBuiltins());
		Metrics.tick("parse Base");
		Statement ast = CompilerPipeline.compile(program, "the base environment");

		Translator translator = new Translator(language, null);
		FrameSlot topLevelResultSlot = translator.addRootSymbol(program.topLevelResultSymbol());
		return translator.translateAST("<Base>", ast, node -> {
			return SequenceNode.sequence(
					new InitializeVarNode(topLevelResultSlot),
					node,
					DerefNode.create(new ReadLocalVariableNode(topLevelResultSlot)));
		});
	}

	public RootCallTarget parseMain(Source source) {
		DynamicObject base = OzContext.getInstance().getBase();

		String fileName = new File(source.getPath()).getName();
		Program program = BootCompiler.buildMainProgram(source, BuiltinsRegistry.getBuiltins());
		Statement ast = CompilerPipeline.compile(program, fileName);

		Translator translator = new Translator(language, base);
		FrameSlot baseSlot = translator.addRootSymbol(program.baseEnvSymbol());
		return translator.translateAST(fileName, ast, node -> {
			return SequenceNode.sequence(
					new InitializeTmpNode(baseSlot, new LiteralNode(base)),
					node);
		});
	}

	public RootCallTarget parseFunctor(Source source) {
		DynamicObject base = OzContext.getInstance().getBase();

		String fileName = new File(source.getPath()).getName();
		System.out.println("Loading " + fileName);
		Metrics.tick("start parse");
		Program program = BootCompiler.buildProgram(source, false, eagerLoad, BuiltinsRegistry.getBuiltins());
		Metrics.tick("parse functor " + fileName);
		Statement ast = CompilerPipeline.compile(program, fileName);
		Metrics.tick("compiled functor " + fileName);

		Translator translator = new Translator(language, base);
		FrameSlot baseSlot = translator.addRootSymbol(program.baseEnvSymbol());
		FrameSlot topLevelResultSlot = translator.addRootSymbol(program.topLevelResultSymbol());
		RootCallTarget callTarget = translator.translateAST(fileName, ast, node -> {
			return SequenceNode.sequence(
					new InitializeTmpNode(baseSlot, new LiteralNode(base)),
					new InitializeVarNode(topLevelResultSlot),
					node,
					DerefNode.create(new ReadLocalVariableNode(topLevelResultSlot)));
		});
		Metrics.tick("translated functor " + fileName);
		return callTarget;
	}

	public void setEagerLoad(boolean value) {
		this.eagerLoad = value;
	}

}

@@ -1753,636 +1753,8 @@
 %09%7D%0A%0A
-%09public RootCallTarget parseMain(Source source) %7B%0A%09%09DynamicObject base = OzContext.getInstance().getBase();%0A%0A%09%09String fileName = new File(source.getPath()).getName();%0A%09%09Program program = BootCompiler.buildMainProgram(source, BuiltinsRegistry.getBuiltins());%0A%09%09Statement ast = CompilerPipeline.compile(program, fileName);%0A%0A%09%09Translator translator = new Translator(language, base);%0A%09%09FrameSlot baseSlot = translator.addRootSymbol(program.baseEnvSymbol());%0A%09%09return translator.translateAST(fileName, ast, node -%3E %7B%0A%09%09%09return SequenceNode.sequence(%0A%09%09%09%09%09new InitializeTmpNode(baseSlot, new LiteralNode(base)),%0A%09%09%09%09%09node);%0A%09%09%7D);%0A%09%7D%0A%0A
 %09pub

Remove unused method