<commit_before>package nl.cwi.reo.interpret;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.antlr.v4.runtime.ANTLRFileStream;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;

import nl.cwi.reo.interpret.components.ComponentValue;
import nl.cwi.reo.interpret.listeners.Listener;
import nl.cwi.reo.interpret.programs.ProgramFile;
import nl.cwi.reo.interpret.programs.ProgramValue;
import nl.cwi.reo.interpret.ranges.Expression;
import nl.cwi.reo.interpret.ranges.ExpressionList;
import nl.cwi.reo.interpret.semantics.Assembly;
import nl.cwi.reo.interpret.semantics.Definitions;
import nl.cwi.reo.interpret.semantics.InstanceList;
import nl.cwi.reo.interpret.signatures.SignatureConcrete;
import nl.cwi.reo.interpret.strings.StringValue;
import nl.cwi.reo.interpret.variables.VariableName;
import nl.cwi.reo.semantics.Semantics;
import nl.cwi.reo.semantics.SemanticsType;

public class Interpreter<T extends Semantics<T>> {
	
	/**
	 * Type of semantics.
	 */
	private final SemanticsType semantics;
	
	/**
	 * ANTLR listener.
	 */
	private final Listener<T> listener;
	
	/**
	 * Component paths: base directories of component files.
	 */
	private final List<String> dirs;
	
	/**
	 * list of parameters to instantiate the main component.
	 */
	private final List<String> params;
	
	/**
	 * Constructs a Reo interpreter.
	 * @param dirs		list of directories of Reo components
	 */
	public Interpreter(SemanticsType semantics, Listener<T> listener, List<String> dirs, List<String> params) {
		if (semantics == null || listener == null || dirs == null || params == null)
			throw new NullPointerException();
		this.semantics = semantics;
		this.listener = listener;
		this.dirs = Collections.unmodifiableList(dirs);	
		this.params = Collections.unmodifiableList(params);	
	}

	/**
	 * Interprets a list of Reo files (the first file is the main file) as a 
	 * list of atomic components.
	 * @param file		non-empty list of Reo file names.
	 * @return list of work automata.
	 */
	@SuppressWarnings("unchecked")
	public Assembly<T> interpret(List<String> srcfiles) {
		try {			
			// Find all available component expressions.
			Stack<ProgramFile<T>> stack = new Stack<ProgramFile<T>>();	
			List<String> parsed = new ArrayList<String>();
			Queue<String> components = new LinkedList<String>();
			
			for (String file : srcfiles) {
				ProgramFile<T> program = parse(new ANTLRFileStream(file));
				if (program != null) {
					stack.push(program);
					parsed.add(program.getName());
					components.addAll(program.getImports());
				} else {
					System.out.println("[error] File " + file + " could not be parsed.");
				}
			}		
			
			while (!components.isEmpty()) {
				String comp = components.poll();
				if (!parsed.contains(comp)) {
					parsed.add(comp);
					ProgramFile<T> program = parseComponent(comp);
					if (program != null) {
						stack.push(program);
						List<String> newComponents = program.getImports();
						newComponents.removeAll(parsed);
						components.addAll(newComponents);
					} else {
						System.out.println("[error] Component " + comp + " cannot be found.");
					}

				}
			}

			// Evaluate these component expressions.
			Definitions definitions = new Definitions();
			VariableName name = null;		
			while (!stack.isEmpty()) {
				ProgramFile<T> program = stack.pop();
				name = new VariableName(program.getName());
				Expression cexpr = program.getComponent().evaluate(definitions);
				definitions.put(name, cexpr);
			}
			
			// Get the instance from the main component.		
			Expression expr = definitions.get(name);		
			if (expr instanceof ComponentValue<?>) {				
				ComponentValue<T> main = (ComponentValue<T>)expr;
				ExpressionList values = new ExpressionList();
				for (String x : params) values.add(new StringValue(x));
				SignatureConcrete sign = main.getSignature().evaluate(values, null);
				
				ProgramValue<T> main_p = main.instantiate(values, null);
				
				InstanceList<T> instances = main_p.getInstances();
				
				instances.insertNodes(true, false);
				
				return new Assembly<T>(instances.getComponents(), name.getName(), sign.keySet());
			}
		} catch (IOException e) {
			System.out.print(e.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
		}		

		return null;
	}
	
	/**
	 * Locates the source file that contains the definition of a component.
	 * @param component		fully qualified name of the requested component.
	 * @return path string of the file containing this components definition,
	 * or null, if this path is not found.
	 * @throws IOException 
	 * @throws FileNotFoundException 
	 */
	private ProgramFile<T> parseComponent(String component) throws IOException {
		
		ProgramFile<T> prog = null;
		
		int k = component.lastIndexOf('.') + 1;
		String name = component.substring(k);
		String directory = component.substring(0, k).replace('.', File.separatorChar);
		String cp1 = directory + semantics + File.separator + name + ".treo";
		String cp2 = directory + name + ".treo";
	
	search:
		for (String dir : dirs) {
			
			// Check if this directory contains a .zip file.
			File folder = new File(dir);
			if (folder.exists() && folder.isDirectory()) {<commit_msg>fix the folder semantic type<commit_after>package nl.cwi.reo.interpret;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.antlr.v4.runtime.ANTLRFileStream;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;

import nl.cwi.reo.interpret.components.ComponentValue;
import nl.cwi.reo.interpret.listeners.Listener;
import nl.cwi.reo.interpret.programs.ProgramFile;
import nl.cwi.reo.interpret.programs.ProgramValue;
import nl.cwi.reo.interpret.ranges.Expression;
import nl.cwi.reo.interpret.ranges.ExpressionList;
import nl.cwi.reo.interpret.semantics.Assembly;
import nl.cwi.reo.interpret.semantics.Definitions;
import nl.cwi.reo.interpret.semantics.InstanceList;
import nl.cwi.reo.interpret.signatures.SignatureConcrete;
import nl.cwi.reo.interpret.strings.StringValue;
import nl.cwi.reo.interpret.variables.VariableName;
import nl.cwi.reo.semantics.Semantics;
import nl.cwi.reo.semantics.SemanticsType;

public class Interpreter<T extends Semantics<T>> {
	
	/**
	 * Type of semantics.
	 */
	private final SemanticsType semantics;
	
	/**
	 * ANTLR listener.
	 */
	private final Listener<T> listener;
	
	/**
	 * Component paths: base directories of component files.
	 */
	private final List<String> dirs;
	
	/**
	 * list of parameters to instantiate the main component.
	 */
	private final List<String> params;
	
	/**
	 * Constructs a Reo interpreter.
	 * @param dirs		list of directories of Reo components
	 */
	public Interpreter(SemanticsType semantics, Listener<T> listener, List<String> dirs, List<String> params) {
		if (semantics == null || listener == null || dirs == null || params == null)
			throw new NullPointerException();
		this.semantics = semantics;
		this.listener = listener;
		this.dirs = Collections.unmodifiableList(dirs);	
		this.params = Collections.unmodifiableList(params);	
	}

	/**
	 * Interprets a list of Reo files (the first file is the main file) as a 
	 * list of atomic components.
	 * @param file		non-empty list of Reo file names.
	 * @return list of work automata.
	 */
	@SuppressWarnings("unchecked")
	public Assembly<T> interpret(List<String> srcfiles) {
		try {			
			// Find all available component expressions.
			Stack<ProgramFile<T>> stack = new Stack<ProgramFile<T>>();	
			List<String> parsed = new ArrayList<String>();
			Queue<String> components = new LinkedList<String>();
			
			for (String file : srcfiles) {
				ProgramFile<T> program = parse(new ANTLRFileStream(file));
				if (program != null) {
					stack.push(program);
					parsed.add(program.getName());
					components.addAll(program.getImports());
				} else {
					System.out.println("[error] File " + file + " could not be parsed.");
				}
			}		
			
			while (!components.isEmpty()) {
				String comp = components.poll();
				if (!parsed.contains(comp)) {
					parsed.add(comp);
					ProgramFile<T> program = parseComponent(comp);
					if (program != null) {
						stack.push(program);
						List<String> newComponents = program.getImports();
						newComponents.removeAll(parsed);
						components.addAll(newComponents);
					} else {
						System.out.println("[error] Component " + comp + " cannot be found.");
					}

				}
			}

			// Evaluate these component expressions.
			Definitions definitions = new Definitions();
			VariableName name = null;		
			while (!stack.isEmpty()) {
				ProgramFile<T> program = stack.pop();
				name = new VariableName(program.getName());
				Expression cexpr = program.getComponent().evaluate(definitions);
				definitions.put(name, cexpr);
			}
			
			// Get the instance from the main component.		
			Expression expr = definitions.get(name);		
			if (expr instanceof ComponentValue<?>) {				
				ComponentValue<T> main = (ComponentValue<T>)expr;
				ExpressionList values = new ExpressionList();
				for (String x : params) values.add(new StringValue(x));
				SignatureConcrete sign = main.getSignature().evaluate(values, null);
				
				ProgramValue<T> main_p = main.instantiate(values, null);
				
				InstanceList<T> instances = main_p.getInstances();
				
				instances.insertNodes(true, false);
				
				return new Assembly<T>(instances.getComponents(), name.getName(), sign.keySet());
			}
		} catch (IOException e) {
			System.out.print(e.getMessage());
		} catch (Exception e) {
			e.printStackTrace();
		}		

		return null;
	}
	
	/**
	 * Locates the source file that contains the definition of a component.
	 * @param component		fully qualified name of the requested component.
	 * @return path string of the file containing this components definition,
	 * or null, if this path is not found.
	 * @throws IOException 
	 * @throws FileNotFoundException 
	 */
	private ProgramFile<T> parseComponent(String component) throws IOException {
		
		ProgramFile<T> prog = null;
		
		int k = component.lastIndexOf('.') + 1;
		String name = component.substring(k);
		String directory = component.substring(0, k).replace('.', File.separatorChar);
		String cp1 = directory + name + "." + semantics + ".treo";
		String cp2 = directory + name + ".treo";
	
	search:
		for (String dir : dirs) {
			
			// Check if this directory contains a .zip file.
			File folder = new File(dir);
			if (folder.exists() && folder.isDirectory()) {
{'fraction_non_alphanumeric': 0.1229739252995067, 'fraction_numerical': 0.0017618040873854828, 'mean_word_length': 3.804485823106221, 'pattern_counts': {'":': 0, '<': 63, '<?xml version=': 0, '>': 63, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7059954', 'n_tokens_mistral': 3990, 'n_tokens_neox': 3390, 'n_words': 861}