<commit_before>﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using MoonSharp.Interpreter.Execution;

namespace MoonSharp.Interpreter.CoreLib
{
	[MoonSharpModule]
	public class BasicModule
	{
		//type (v)
		//----------------------------------------------------------------------------------------------------------------
		//Returns the type of its only argument, coded as a string. The possible results of this function are "nil" 
		//(a string, not the value nil), "number", "string", "boolean", "table", "function", "thread", and "userdata". 
		[MoonSharpMethod]
		public static DynValue type(ScriptExecutionContext executionContext, CallbackArguments args)
		{
			if (args.Count < 1) throw ScriptRuntimeException.BadArgumentValueExpected(0, "type");

			DynValue v = args[0];
			return DynValue.NewString(v.Type.ToLuaTypeString());
		}



		//assert (v [, message])
		//----------------------------------------------------------------------------------------------------------------
		//Issues an error when the value of its argument v is false (i.e., nil or false); 
		//otherwise, returns all its arguments. message is an error message; when absent, it defaults to "assertion failed!" 
		[MoonSharpMethod]
		public static DynValue assert(ScriptExecutionContext executionContext, CallbackArguments args)
		{
			DynValue v = args[0];
			DynValue message = args[1];

			if (!v.CastToBool())
			{
				if (message.IsNil())
					throw new ScriptRuntimeException("assertion failed!") { DoNotDecorateMessage = true };
				else
					throw new ScriptRuntimeException(message.ToPrintString()) { DoNotDecorateMessage = true };
			}

			return DynValue.NewTupleNested(args.GetArray());
		}

		// collectgarbage  ([opt [, arg]])
		// ----------------------------------------------------------------------------------------------------------------
		// This function is mostly a stub towards the CLR GC. If mode is nil, "collect" or "restart", a GC is forced.
		[MoonSharpMethod]
		public static DynValue collectgarbage(ScriptExecutionContext executionContext, CallbackArguments args)
		{
			DynValue opt = args[0];

			string mode = opt.CastToString();

			if (mode == null || mode == "collect" || mode == "restart")
				GC.Collect(2, GCCollectionMode.Forced);

			return DynValue.Nil;
		}

		// error (message [, level])
		// ----------------------------------------------------------------------------------------------------------------
		// Terminates the last protected function called and returns message as the error message. Function error never returns.
		// Usually, error adds some information about the error position at the beginning of the message. 
		// The level argument specifies how to get the error position. 
		// With level 1 (the default), the error position is where the error function was called. 
		// Level 2 points the error to where the function that called error was called; and so on. 
		// Passing a level 0 avoids the addition of error position information to the message. 
		[MoonSharpMethod]
		public static DynValue error(ScriptExecutionContext executionContext, CallbackArguments args)
		{
			DynValue message = args.AsType(0, "error", DataType.String, false);
			throw new ScriptRuntimeException(message.String) { DoNotDecorateMessage = true };
		}


		// tostring (v)
		// ----------------------------------------------------------------------------------------------------------------
		// Receives a value of any type and converts it to a string in a reasonable format. (For complete control of how 
		// numbers are converted, use string.format.)
		// 
		// If the metatable of v has a "__tostring" field, then tostring calls the corresponding value with v as argument, 
		// and uses the result of the call as its result. 
		[MoonSharpMethod]
		public static DynValue tostring(ScriptExecutionContext executionContext, CallbackArguments args)
		{
			if (args.Count < 1) throw ScriptRuntimeException.BadArgumentValueExpected(0, "tostring");

			DynValue v = args[0];
			DynValue tail = executionContext.GetMetamethodTailCall(v, "__tostring", v);
			
			if (tail == null || tail.IsNil())
				return DynValue.NewString(v.ToPrintString());

			tail.TailCallData.Continuation = new CallbackFunction(__tostring_continuation, "__tostring");

			return tail;
		}

		private static DynValue __tostring_continuation(ScriptExecutionContext executionContext, CallbackArguments args)
		{
			DynValue b = args[0].ToScalar();

			if (b.IsNil())
				return b;

			if (b.Type != DataType.String)
				throw new ScriptRuntimeException("'tostring' must return a string");


			return b;
		}

		// select (index, ...)
		// -----------------------------------------------------------------------------
		// If index is a number, returns all arguments after argument number index; a negative number indexes from 
		// the end (-1 is the last argument). Otherwise, index must be the string "#", and select returns the total
		// number of extra arguments it received. 
		[MoonSharpMethod]
		public static DynValue select(ScriptExecutionContext executionContext, CallbackArguments args)
		{
			
			if (args[0].Type == DataType.String && args[0].String == "#")
				return DynValue.NewNumber(args.Count - 1);

			DynValue v_num = args.AsType(0, "select", DataType.Number, false);
			int num = (int)v_num.Number;

			List<DynValue> values = new List<DynValue>();

			if (num > 0)
			{
				for (int i = num; i < args.Count; i++)
					values.Add(args[i]);
			}<commit_msg>fix select() on varargs<commit_after>﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using MoonSharp.Interpreter.Execution;

namespace MoonSharp.Interpreter.CoreLib
{
	[MoonSharpModule]
	public class BasicModule
	{
		//type (v)
		//----------------------------------------------------------------------------------------------------------------
		//Returns the type of its only argument, coded as a string. The possible results of this function are "nil" 
		//(a string, not the value nil), "number", "string", "boolean", "table", "function", "thread", and "userdata". 
		[MoonSharpMethod]
		public static DynValue type(ScriptExecutionContext executionContext, CallbackArguments args)
		{
			if (args.Count < 1) throw ScriptRuntimeException.BadArgumentValueExpected(0, "type");

			DynValue v = args[0];
			return DynValue.NewString(v.Type.ToLuaTypeString());
		}



		//assert (v [, message])
		//----------------------------------------------------------------------------------------------------------------
		//Issues an error when the value of its argument v is false (i.e., nil or false); 
		//otherwise, returns all its arguments. message is an error message; when absent, it defaults to "assertion failed!" 
		[MoonSharpMethod]
		public static DynValue assert(ScriptExecutionContext executionContext, CallbackArguments args)
		{
			DynValue v = args[0];
			DynValue message = args[1];

			if (!v.CastToBool())
			{
				if (message.IsNil())
					throw new ScriptRuntimeException("assertion failed!") { DoNotDecorateMessage = true };
				else
					throw new ScriptRuntimeException(message.ToPrintString()) { DoNotDecorateMessage = true };
			}

			return DynValue.NewTupleNested(args.GetArray());
		}

		// collectgarbage  ([opt [, arg]])
		// ----------------------------------------------------------------------------------------------------------------
		// This function is mostly a stub towards the CLR GC. If mode is nil, "collect" or "restart", a GC is forced.
		[MoonSharpMethod]
		public static DynValue collectgarbage(ScriptExecutionContext executionContext, CallbackArguments args)
		{
			DynValue opt = args[0];

			string mode = opt.CastToString();

			if (mode == null || mode == "collect" || mode == "restart")
				GC.Collect(2, GCCollectionMode.Forced);

			return DynValue.Nil;
		}

		// error (message [, level])
		// ----------------------------------------------------------------------------------------------------------------
		// Terminates the last protected function called and returns message as the error message. Function error never returns.
		// Usually, error adds some information about the error position at the beginning of the message. 
		// The level argument specifies how to get the error position. 
		// With level 1 (the default), the error position is where the error function was called. 
		// Level 2 points the error to where the function that called error was called; and so on. 
		// Passing a level 0 avoids the addition of error position information to the message. 
		[MoonSharpMethod]
		public static DynValue error(ScriptExecutionContext executionContext, CallbackArguments args)
		{
			DynValue message = args.AsType(0, "error", DataType.String, false);
			throw new ScriptRuntimeException(message.String) { DoNotDecorateMessage = true };
		}


		// tostring (v)
		// ----------------------------------------------------------------------------------------------------------------
		// Receives a value of any type and converts it to a string in a reasonable format. (For complete control of how 
		// numbers are converted, use string.format.)
		// 
		// If the metatable of v has a "__tostring" field, then tostring calls the corresponding value with v as argument, 
		// and uses the result of the call as its result. 
		[MoonSharpMethod]
		public static DynValue tostring(ScriptExecutionContext executionContext, CallbackArguments args)
		{
			if (args.Count < 1) throw ScriptRuntimeException.BadArgumentValueExpected(0, "tostring");

			DynValue v = args[0];
			DynValue tail = executionContext.GetMetamethodTailCall(v, "__tostring", v);
			
			if (tail == null || tail.IsNil())
				return DynValue.NewString(v.ToPrintString());

			tail.TailCallData.Continuation = new CallbackFunction(__tostring_continuation, "__tostring");

			return tail;
		}

		private static DynValue __tostring_continuation(ScriptExecutionContext executionContext, CallbackArguments args)
		{
			DynValue b = args[0].ToScalar();

			if (b.IsNil())
				return b;

			if (b.Type != DataType.String)
				throw new ScriptRuntimeException("'tostring' must return a string");


			return b;
		}

		// select (index, ...)
		// -----------------------------------------------------------------------------
		// If index is a number, returns all arguments after argument number index; a negative number indexes from 
		// the end (-1 is the last argument). Otherwise, index must be the string "#", and select returns the total
		// number of extra arguments it received. 
		[MoonSharpMethod]
		public static DynValue select(ScriptExecutionContext executionContext, CallbackArguments args)
		{
			if (args[0].Type == DataType.String && args[0].String == "#")
			{
				if (args[args.Count - 1].Type == DataType.Tuple)
				{
					return DynValue.NewNumber(args.Count - 1 + args[args.Count - 1].Tuple.Length);
				}
				else
				{
					return DynValue.NewNumber(args.Count - 1);
				}
			}

			DynValue v_num = args.AsType(0, "select", DataType.Number, false);
			int num = (int)v_num.Number;

			List<DynValue> values = new List<DynValue>();

			if (num > 0)
			{
				for (int i = num; i < args.Count; i++)
					values.Add(args[i]);
			}
{'fraction_non_alphanumeric': 0.20581714995122816, 'fraction_numerical': 0.0039904229848363925, 'mean_word_length': 2.3053927315357563, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 9, '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': '7551093', 'n_tokens_mistral': 3374, 'n_tokens_neox': 2896, 'n_words': 1009}