<commit_before>'use strict'


/*

Terms:

* function
* environment
* variable
* global environment
* local environment
* action - function and arguments
* command - name and action

*/


/*

globals:
    annotation_name: Classification
    annotation_scope: Selected
    
commands:

    "\": [clear_command_and_locals]
    
    ">": [show_next_page]
    "<": [show_previous_page]
    ".": [select_next_clip]
    ",": [select_previous_clip]
    "/": [play_selected_clip]
    
    "#": [set_local, annotation_scope, Page]
    "*": [set_local, annotation_scope, All]

    c: [annotate_clips, Call]
    C: [annotate_page_clips, Call]
    n: [annotate_clips, Noise]
    N: [annotate_page_clips, Noise]
    x: [unannotate_clips]
    X: [unannotate_page_clips]
    
    r: [tag_clips, Review]
    u: [untag_clips]

*/


class KeyboardCommandInterpreter {
	
	
	constructor(spec, functions) {
		
		this._functions = this._getFunctions(functions);
		
		this._environment = new Environment();
		this._initGlobals(spec);
		
		this._commandActions = this._getCommandActions(spec);
		this._commandNamePrefixes = this._getCommandNamePrefixes();

		this._clearCommandNameBuffer();
		
	}
	
	
	_getFunctions(functionList) {
		const builtInFunctions = this._createBuiltInFunctions();
		const functions = functionList.map((f) => [f.name, f]);
		return new Map([...builtInFunctions, ...functions]);
	}
		
		
	_createBuiltInFunctions() {
		
		const functionData = [
			['set_global', ['name', 'value'],
				(a, e) => this._setGlobal(e, ...a)],
			['delete_global', ['name'], (a, e) => this._deleteGlobal(e, ...a)],
			['clear_globals', [], (a, e) => this._clearGlobals(e, ...a)],
			['set_local', ['name', 'value'], (a, e) => this._setLocal(e, ...a)],
			['delete_local', ['name'], (a, e) => this._deleteLocal(e, ...a)],
			['clear_locals', [], (a, e) => this._clearLocals(e, ...a)],
			['clear_command_and_locals', [],
				(a, e) => this._clearCommandAndLocals(e, ...a)]
		]
		
		const entries = functionData.map(this._createBuiltInFunctionEntry);
		return new Map(entries);
		
	}
	
	
	_createBuiltInFunctionEntry(functionData) {
		const name = functionData[0];
		const value = new BuiltInFunction(...functionData);
		return [name, value];
	}

	
	_setGlobal(environment, name, value) {
		environment.setGlobal(name, value);
	}
	
	
	_deleteGlobal(environment, name) {
		environment.deleteGlobal(name);
	}
	
	
	_clearGlobals(environment) {
		environment.clearGlobals();
	}
	
	
	_setLocal(environment, name, value) {
		environment.setLocal(name, value);
	}
	
	
	_deleteLocal(environment, name) {
		environment.deleteLocal(name);
	}
	
	
	_clearLocals(environment) {
		environment.clearLocals();
	}
	
	
	_clearCommandAndLocals(environment) {
		this._clearCommandNameBuffer();
		environment.clearLocals();
	}
	
	
	_initGlobals(spec) {
		
		if (spec.globals !== undefined) {
			
			for (const name of Object.keys(spec.globals)) {
				const value = spec.globals[name];
				this._environment.setGlobal(name, value);
			}
			
		}
		
	}
	
	
	_getCommandActions(spec) {
		
		const actions = new Map();
		
		if (spec.commands !== undefined)
			for (const name of Object.keys(spec.commands)) {
				actions.set(name, spec.commands[name]);
			}
		
		return actions;
		
	}
	
	
	// Gets the set of all proper prefixes of this interpreter's command names.
	_getCommandNamePrefixes() {
		
		const prefixes = new Set();
		
		for (const name of this._commandActions.keys())
			for (let i = 1; i < name.length; i++)
				prefixes.add(name.slice(0, i));
	
	    return prefixes;
	    
	}
	
	
	_clearCommandNameBuffer() {
		this._commandNameBuffer = '';
	}
	
	
	handleKey(key) {
		
		console.log(
			'KeyboardCommandInterpreter.handleKey', key,
			this._commandNameBuffer);
		
		const name = this._commandNameBuffer + key;
		const action = this._commandActions.get(name);
		
		if (action !== undefined) {
			// `name` is a command name
			
			this._executeCommand(name, action);
			this._clearCommandNameBuffer();
			
		} else if (this._commandNamePrefixes.has(name)) {
			// `name` is a proper prefix of one or more command names
			
			this._commandNameBuffer = name;
			
		} else {
			// `name` is not a prefix of any command name<commit_msg>Commented out a print statement in the keyboard command interpreter.<commit_after>'use strict'


/*

Terms:

* function
* environment
* variable
* global environment
* local environment
* action - function and arguments
* command - name and action

*/


/*

globals:
    annotation_name: Classification
    annotation_scope: Selected
    
commands:

    "\": [clear_command_and_locals]
    
    ">": [show_next_page]
    "<": [show_previous_page]
    ".": [select_next_clip]
    ",": [select_previous_clip]
    "/": [play_selected_clip]
    
    "#": [set_local, annotation_scope, Page]
    "*": [set_local, annotation_scope, All]

    c: [annotate_clips, Call]
    C: [annotate_page_clips, Call]
    n: [annotate_clips, Noise]
    N: [annotate_page_clips, Noise]
    x: [unannotate_clips]
    X: [unannotate_page_clips]
    
    r: [tag_clips, Review]
    u: [untag_clips]

*/


class KeyboardCommandInterpreter {
	
	
	constructor(spec, functions) {
		
		this._functions = this._getFunctions(functions);
		
		this._environment = new Environment();
		this._initGlobals(spec);
		
		this._commandActions = this._getCommandActions(spec);
		this._commandNamePrefixes = this._getCommandNamePrefixes();

		this._clearCommandNameBuffer();
		
	}
	
	
	_getFunctions(functionList) {
		const builtInFunctions = this._createBuiltInFunctions();
		const functions = functionList.map((f) => [f.name, f]);
		return new Map([...builtInFunctions, ...functions]);
	}
		
		
	_createBuiltInFunctions() {
		
		const functionData = [
			['set_global', ['name', 'value'],
				(a, e) => this._setGlobal(e, ...a)],
			['delete_global', ['name'], (a, e) => this._deleteGlobal(e, ...a)],
			['clear_globals', [], (a, e) => this._clearGlobals(e, ...a)],
			['set_local', ['name', 'value'], (a, e) => this._setLocal(e, ...a)],
			['delete_local', ['name'], (a, e) => this._deleteLocal(e, ...a)],
			['clear_locals', [], (a, e) => this._clearLocals(e, ...a)],
			['clear_command_and_locals', [],
				(a, e) => this._clearCommandAndLocals(e, ...a)]
		]
		
		const entries = functionData.map(this._createBuiltInFunctionEntry);
		return new Map(entries);
		
	}
	
	
	_createBuiltInFunctionEntry(functionData) {
		const name = functionData[0];
		const value = new BuiltInFunction(...functionData);
		return [name, value];
	}

	
	_setGlobal(environment, name, value) {
		environment.setGlobal(name, value);
	}
	
	
	_deleteGlobal(environment, name) {
		environment.deleteGlobal(name);
	}
	
	
	_clearGlobals(environment) {
		environment.clearGlobals();
	}
	
	
	_setLocal(environment, name, value) {
		environment.setLocal(name, value);
	}
	
	
	_deleteLocal(environment, name) {
		environment.deleteLocal(name);
	}
	
	
	_clearLocals(environment) {
		environment.clearLocals();
	}
	
	
	_clearCommandAndLocals(environment) {
		this._clearCommandNameBuffer();
		environment.clearLocals();
	}
	
	
	_initGlobals(spec) {
		
		if (spec.globals !== undefined) {
			
			for (const name of Object.keys(spec.globals)) {
				const value = spec.globals[name];
				this._environment.setGlobal(name, value);
			}
			
		}
		
	}
	
	
	_getCommandActions(spec) {
		
		const actions = new Map();
		
		if (spec.commands !== undefined)
			for (const name of Object.keys(spec.commands)) {
				actions.set(name, spec.commands[name]);
			}
		
		return actions;
		
	}
	
	
	// Gets the set of all proper prefixes of this interpreter's command names.
	_getCommandNamePrefixes() {
		
		const prefixes = new Set();
		
		for (const name of this._commandActions.keys())
			for (let i = 1; i < name.length; i++)
				prefixes.add(name.slice(0, i));
	
	    return prefixes;
	    
	}
	
	
	_clearCommandNameBuffer() {
		this._commandNameBuffer = '';
	}
	
	
	handleKey(key) {
		
//		console.log(
//			'KeyboardCommandInterpreter.handleKey', key,
//			this._commandNameBuffer);
		
		const name = this._commandNameBuffer + key;
		const action = this._commandActions.get(name);
		
		if (action !== undefined) {
			// `name` is a command name
			
			this._executeCommand(name, action);
			this._clearCommandNameBuffer();
			
		} else if (this._commandNamePrefixes.has(name)) {
			// `name` is a proper prefix of one or more command names
			
			this._commandNameBuffer = name;
			
		} else {
			// `name` is not a prefix of any command name
{'fraction_non_alphanumeric': 0.14559432288586635, 'fraction_numerical': 0.0007096392667060911, 'mean_word_length': 3.4249084249084247, 'pattern_counts': {'":': 16, '<': 7, '<?xml version=': 0, '>': 21, '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': '1693059', 'n_tokens_mistral': 3237, 'n_tokens_neox': 2775, 'n_words': 576}