<commit_before>/** 
 * Copyright (c) 2005-2006 <NAME>. All rights reserved.
 */

package com.xruby.runtime.lang;

import java.util.concurrent.*;
import java.util.*;
import com.xruby.runtime.value.*;

class MultipleMap<T> {
	private ConcurrentMap<String, Vector<T>> values_ = new ConcurrentHashMap<String, Vector<T>>();

	public void put(String s, T proc) {
		if (!values_.containsKey(s)) {
			values_.put(s, new Vector<T>());
		}
		
		Vector<T> set = values_.get(s);
		set.add(0, proc);
	}

	public List<T> get(String name) {
		return values_.get(name);
	}
	
	public void remove(String s, T proc) {
		Vector<T> set = values_.get(s);
		if (null == set) {
			return;
		}
		
		set.remove(proc);
	}
	
	public void removeAll(String s) {
		Vector<T> set = values_.get(s);
		if (null != set) {
			set.clear();
		}
	}
}

/*
$* $ARGV
$" $LOADED_FEATURES
$? $CHILD_STATUS 
$& $MATCH
$< $DEFAULT_INPUT 
$. $NR
$> $DEFAULT_OUTPUT 
$, $OFS
$! $ERROR_INFO 
$\ $ORS
$@ $ERROR_POSITION 
$, $OUTPUT_FIELD_SEPARATOR
$; $FIELD_SEPARATOR 
$\ $OUTPUT_RECORD_SEPARATOR
$; $FS 
$$ $PID
$= $IGNORECASE 
$' $POSTMATCH
$. $INPUT_LINE_NUMBER 
$` $PREMATCH
$/ $INPUT_RECORD_SEPARATOR 
$$ $PROCESS_ID
$~ $LAST_MATCH_INFO 
$0 $PROGRAM_NAME
$+ $LAST_PAREN_MATCH 
$/ $RS
$_ $LAST_READ_LINE
*/
public class GlobalVariables {
	
	private static ConcurrentHashMap<String, RubyValue> values_ = new ConcurrentHashMap<String, RubyValue>();
	private static MultipleMap<RubyProc> traces_procs_ = new MultipleMap<RubyProc>();

	private static boolean in_tracing_ = false;//TODO should this be global or per variable?

	static {
		values_.put("$stdout", new RubyObject(RubyRuntime.IOClass));
		values_.put("$/", ObjectFactory.createString("\n"));
		values_.put("$$",ObjectFactory.fixnum0);//no way to get pid in java
	}
	
	public static RubyValue get(String name) {
		assert('$' == name.charAt(0));

		RubyValue v = values_.get(name);
		if (null != v) {
			return v;
		} else {
			return ObjectFactory.nilValue;
		}
	}
	
	public static boolean isReadOnly(String name) {
		if (name.equals("$$")) {
			return true;
		}
		
		//TODO more
		
		return false;
	}
	
	public static void throwNameError(String name) {
		throw new RubyException(RubyRuntime.NameErrorClass, name + " is a read-only variable");
	}
	
	public static RubyValue set(RubyValue value, String name) {
		assert('$' == name.charAt(0));
		values_.put(name, value);

		if (!in_tracing_) {
			in_tracing_ = true;

			try {
				List<RubyProc> set = traces_procs_.get(name);
				if (null != set) {
					for (RubyProc p : set) {
						p.getValue().invoke(value, new RubyArray(value));//TODO What the receiver should be?
					}
				}
			} finally {
				in_tracing_ = false;
			}<commit_msg>do not pass any parameter when tracing<commit_after>/** 
 * Copyright (c) 2005-2006 <NAME>. All rights reserved.
 */

package com.xruby.runtime.lang;

import java.util.concurrent.*;
import java.util.*;
import com.xruby.runtime.value.*;

class MultipleMap<T> {
	private ConcurrentMap<String, Vector<T>> values_ = new ConcurrentHashMap<String, Vector<T>>();

	public void put(String s, T proc) {
		if (!values_.containsKey(s)) {
			values_.put(s, new Vector<T>());
		}
		
		Vector<T> set = values_.get(s);
		set.add(0, proc);
	}

	public List<T> get(String name) {
		return values_.get(name);
	}
	
	public void remove(String s, T proc) {
		Vector<T> set = values_.get(s);
		if (null == set) {
			return;
		}
		
		set.remove(proc);
	}
	
	public void removeAll(String s) {
		Vector<T> set = values_.get(s);
		if (null != set) {
			set.clear();
		}
	}
}

/*
$* $ARGV
$" $LOADED_FEATURES
$? $CHILD_STATUS 
$& $MATCH
$< $DEFAULT_INPUT 
$. $NR
$> $DEFAULT_OUTPUT 
$, $OFS
$! $ERROR_INFO 
$\ $ORS
$@ $ERROR_POSITION 
$, $OUTPUT_FIELD_SEPARATOR
$; $FIELD_SEPARATOR 
$\ $OUTPUT_RECORD_SEPARATOR
$; $FS 
$$ $PID
$= $IGNORECASE 
$' $POSTMATCH
$. $INPUT_LINE_NUMBER 
$` $PREMATCH
$/ $INPUT_RECORD_SEPARATOR 
$$ $PROCESS_ID
$~ $LAST_MATCH_INFO 
$0 $PROGRAM_NAME
$+ $LAST_PAREN_MATCH 
$/ $RS
$_ $LAST_READ_LINE
*/
public class GlobalVariables {
	
	private static ConcurrentHashMap<String, RubyValue> values_ = new ConcurrentHashMap<String, RubyValue>();
	private static MultipleMap<RubyProc> traces_procs_ = new MultipleMap<RubyProc>();

	private static boolean in_tracing_ = false;//TODO should this be global or per variable?

	static {
		values_.put("$stdout", new RubyObject(RubyRuntime.IOClass));
		values_.put("$/", ObjectFactory.createString("\n"));
		values_.put("$$",ObjectFactory.fixnum0);//no way to get pid in java
	}
	
	public static RubyValue get(String name) {
		assert('$' == name.charAt(0));

		RubyValue v = values_.get(name);
		if (null != v) {
			return v;
		} else {
			return ObjectFactory.nilValue;
		}
	}
	
	public static boolean isReadOnly(String name) {
		if (name.equals("$$")) {
			return true;
		}
		
		//TODO more
		
		return false;
	}
	
	public static void throwNameError(String name) {
		throw new RubyException(RubyRuntime.NameErrorClass, name + " is a read-only variable");
	}
	
	public static RubyValue set(RubyValue value, String name) {
		assert('$' == name.charAt(0));
		values_.put(name, value);

		if (!in_tracing_) {
			in_tracing_ = true;

			try {
				List<RubyProc> set = traces_procs_.get(name);
				if (null != set) {
					for (RubyProc p : set) {
						p.getValue().invoke(value, null);//TODO What the receiver should be?
					}
				}
			} finally {
				in_tracing_ = false;
			}
{'fraction_non_alphanumeric': 0.15265200517464425, 'fraction_numerical': 0.004805026797264831, 'mean_word_length': 3.7640845070422535, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 37, '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': '4816009', 'n_tokens_mistral': 2213, 'n_tokens_neox': 1927, 'n_words': 451}