<commit_before>
var repl = require("repl");
var vm = require("vm");
var readline = require("readline");
var Console = require('console').Console;

var core = require('ralph/core');
var compile = require('ralph/compiler/compile');
var reader = require('ralph/compiler/reader');
var module = require('ralph/compiler/module');
var stream = require('ralph/stream');
var format = require('ralph/format');
var fileStream = require('ralph/file-stream');


var builtinLibs = ['assert', 'buffer', 'child_process', 'cluster',
  'crypto', 'dgram', 'dns', 'domain', 'events', 'fs', 'http', 'https', 'net',
  'os', 'path', 'punycode', 'querystring', 'readline', 'stream',
  'string_decoder', 'tls', 'tty', 'url', 'util', 'vm', 'zlib', 'smalloc',
  'tracing'];

function createContext(outputStream) {
  	var context = vm.createContext();
	for (var i in global) {
		context[i] = global[i];
	}
	context.console = new Console(outputStream);
	context.global = context;
	context.global.global = context;

	context.module = module;
	context.require = require;
	context.exports = Object.create(null);

	// make built-in modules available directly
	// (loaded lazily)
	builtinLibs.forEach(function(name) {
		Object.defineProperty(context, name, {
			get: function() {
				var lib = require(name);
				context._ = context[name] = lib;
				return lib;
			},
			// allow the creation of other globals with this name
			set: function(val) {
				delete context[name];
				context[name] = val;
			},
			configurable: true
		});
	});

	return context;
}

function evalInContext(context, code) {
  var script = vm.createScript(code, {
    displayErrors: false
  });
  return script.runInContext(context, {
  	displayErrors: false
  });
}

function makeEnvironment(name) {
	var env = compile['make-module-environment'](name);
	var coreExports = [];
	for (var exp in core) {
		if (exp !== '%eval') {
			coreExports.push(exp);
		}
	}
	env.module.imports.unshift([$S('ralph/core'), coreExports]);
	return env;
}

var output = process.stdout;

// prepare module
var context = createContext(output);
var env = makeEnvironment('user');
var prologue = compile['compile-to-string'](module['*module-prologue*'], env)
evalInContext(context, prologue);


var rl = readline.createInterface({
	input: process.stdin,
	output: output
});
var currentLine = '';
var incomplete = new Object();
var outputStream = core['make'](fileStream['<file-stream>'],
	   			 				$K('file'), output);

rl.setPrompt('user> ');
rl.prompt();
rl.on('line', function (line) {
	currentLine += " " + line;
	var s = core['make'](stream['<string-stream>'],
			 			 $K('string'), currentLine);
	var exp = reader['read'](s, env, $K('if-incomplete'), incomplete);
	if (exp == incomplete) {
		rl.setPrompt('... ');
	} else {
		// format['format'](outputStream, "READ: %=\n", result);
		var code = compile['compile-to-string'](exp, env);
		// format['format'](outputStream, "COMPILED: %=\n", code);
		try {
			var result = evalInContext(context, code);
			format['format'](outputStream, "%=\n", result);
		} catch (e) {
			console.log('' + e);
		}
		rl.setPrompt('user> ');
		currentLine = '';
	}
 	rl.prompt();
});

rl.on('close', function() {
 	console.log('\nBye!');
  	process.exit(0);
});<commit_msg>repl: enable module switches, don't crash on empty lines and during compilation<commit_after>
var repl = require("repl");
var vm = require("vm");
var readline = require("readline");
var Console = require('console').Console;

var core = require('ralph/core');
var compile = require('ralph/compiler/compile');
var reader = require('ralph/compiler/reader');
var module = require('ralph/compiler/module');
var stream = require('ralph/stream');
var format = require('ralph/format');
var fileStream = require('ralph/file-stream');

var environments = {};

var currentEnvironment;

function makeEnvironment(name) {
	var env = compile['make-module-environment'](name);
	// TODO: actually use module description, maybe compile,
	//       so it is available at runtime
	if (name !== 'ralph/core') {
		var coreExports = [];
		for (var exp in core) {
			if (exp !== '%eval') {
				coreExports.push(exp);
			}
		}
		env.module.imports.unshift([$S('ralph/core'), coreExports]);
	}
	return env;
}

function inModule(name) {
	var environment = environments[name];
	if (!environment) {
		environment = makeEnvironment(name);
		try {
			// exisiting module
			var exports = require(name);
			environment.eval = exports['%eval'];
		} catch (e) {
			// new module
			var prologue = compile['compile-to-string'](module['*module-prologue*'],
				environment);
			environment.eval = evalInContext("(function () { " + prologue
				+ "; return ($module)['%eval']; })()");
		}
	}
	currentEnvironment = environment;
}

var builtinLibs = ['assert', 'buffer', 'child_process', 'cluster',
  'crypto', 'dgram', 'dns', 'domain', 'events', 'fs', 'http', 'https', 'net',
  'os', 'path', 'punycode', 'querystring', 'readline', 'stream',
  'string_decoder', 'tls', 'tty', 'url', 'util', 'vm', 'zlib', 'smalloc',
  'tracing'];

function createContext() {
  	var context = vm.createContext({'$inModule': inModule});
	for (var i in global) {
		context[i] = global[i];
	}
	context.console = new Console(output);
	context.global = context;
	context.global.global = context;

	context.module = module;
	context.require = require;
	context.exports = Object.create(null);

	// make built-in modules available directly
	// (loaded lazily)
	builtinLibs.forEach(function(name) {
		Object.defineProperty(context, name, {
			get: function() {
				var lib = require(name);
				context._ = context[name] = lib;
				return lib;
			},
			// allow the creation of other globals with this name
			set: function(val) {
				delete context[name];
				context[name] = val;
			},
			configurable: true
		});
	});

	return context;
}

function evalInContext(code) {
	return vm.runInContext(code, context, {
  		displayErrors: false
	});
}

function setModulePrompt() {
	rl.setPrompt(currentEnvironment.module.name + '> ');
}

var output = process.stdout;

var context = createContext();
evalInContext("require('ralph/core');"
	+ "$moduleRoot['%in-module'] = $inModule");

inModule('user');

var currentLine = '';
var incomplete = new Object();
var outputStream = core['make'](fileStream['<file-stream>'],
	   			 				$K('file'), output);

var rl = readline.createInterface({
	input: process.stdin,
	output: output
});
setModulePrompt();
rl.prompt();
rl.on('line', function (line) {
	currentLine += " " + line;
	var s = core['make'](stream['<string-stream>'],
			 			 $K('string'), currentLine);
	var exp = reader['read'](s, currentEnvironment,
							 $K('eof-error?'), false,
							 $K('eof-value'), incomplete,
							 $K('if-incomplete'), incomplete);
	if (exp == incomplete) {
		rl.setPrompt('... ');
	} else {
		try {
			// format['format'](outputStream, "READ: %=\n", result);
			var code = compile['compile-to-string'](exp, currentEnvironment);
			// format['format'](outputStream, "COMPILED: %=\n", code);
			var result = currentEnvironment.eval(code);
			format['format'](outputStream, "%=\n", result);
		} catch (e) {
			console.log('' + e.stack);
		}
		setModulePrompt();
		currentLine = '';
	}
 	rl.prompt();
});

rl.on('close', function() {
 	console.log('\nBye!');
  	process.exit(0);
});
{'fraction_non_alphanumeric': 0.1882822170265438, 'fraction_numerical': 0.00027506532801540364, 'mean_word_length': 4.331378299120234, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 10, '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': '4562629', 'n_tokens_mistral': 2601, 'n_tokens_neox': 2404, 'n_words': 556}