2018-11-24 13:35:23 +00:00
|
|
|
using System;
|
2018-11-21 13:49:59 +00:00
|
|
|
using System.Collections;
|
2018-11-23 17:18:07 +00:00
|
|
|
using System.Collections.Generic;
|
2018-11-24 13:35:23 +00:00
|
|
|
using Upsilon.BaseTypes.Number;
|
2018-11-23 17:18:07 +00:00
|
|
|
using Upsilon.BaseTypes.ScriptTypeInterfaces;
|
2018-11-21 13:49:59 +00:00
|
|
|
using Upsilon.Evaluator;
|
2018-12-09 13:05:17 +00:00
|
|
|
using Upsilon.Exceptions;
|
2018-11-21 13:49:59 +00:00
|
|
|
using Upsilon.Text;
|
|
|
|
|
|
|
|
namespace Upsilon.BaseTypes.UserData
|
|
|
|
{
|
2018-11-24 14:11:33 +00:00
|
|
|
internal class ListUserData : ScriptType, IUserData, IIterable, ILengthType
|
2018-11-21 13:49:59 +00:00
|
|
|
{
|
2018-12-09 19:53:07 +00:00
|
|
|
public IList List { get; }
|
2018-11-21 13:49:59 +00:00
|
|
|
|
|
|
|
public ListUserData(IList list)
|
|
|
|
{
|
|
|
|
List = list;
|
|
|
|
}
|
|
|
|
|
2018-11-23 17:18:07 +00:00
|
|
|
public ScriptType Get(Diagnostics diagnostics, TextSpan span, ScriptType index, EvaluationScope scope)
|
2018-11-21 13:49:59 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
if (index.Type == Type.String)
|
|
|
|
{
|
2018-11-23 17:18:07 +00:00
|
|
|
var str = (ScriptString)index;
|
2018-11-21 13:49:59 +00:00
|
|
|
i = int.Parse(str.Value) - 1;
|
|
|
|
}
|
|
|
|
else if (index.Type == Type.Number)
|
|
|
|
{
|
2018-11-23 17:18:07 +00:00
|
|
|
var ind = (Number.ScriptNumberLong) index;
|
2018-11-21 13:49:59 +00:00
|
|
|
i = (int) ind.Value - 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return null;
|
|
|
|
}
|
2018-11-24 12:35:40 +00:00
|
|
|
return List[i].ToScriptType();
|
2018-11-21 13:49:59 +00:00
|
|
|
}
|
|
|
|
|
2018-12-09 13:05:17 +00:00
|
|
|
public void Set(Diagnostics diagnostics, TextSpan span, ScriptType scriptIndex, ScriptType value)
|
2018-11-21 13:49:59 +00:00
|
|
|
{
|
2018-12-09 13:05:17 +00:00
|
|
|
var index = -1;
|
|
|
|
if (scriptIndex.Type == Type.Number || scriptIndex.Type == Type.Unknown)
|
|
|
|
{
|
|
|
|
index = Convert.ToInt32(scriptIndex.ToCSharpObject());
|
|
|
|
}
|
|
|
|
else if (scriptIndex.Type == Type.String)
|
|
|
|
{
|
|
|
|
index = int.Parse(((ScriptString) scriptIndex).Value);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
throw new ScriptRuntimeException(
|
|
|
|
$"Tried indexing a CSharp list with a value that's not an integer. Value: {scriptIndex.ToCSharpObject()}",
|
2019-01-16 22:57:42 +00:00
|
|
|
span, diagnostics.ScriptString.GetSpan(span));
|
2018-12-09 13:05:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
index--;
|
|
|
|
if (index > List.Count)
|
|
|
|
{
|
|
|
|
if (index == List.Count)
|
|
|
|
{
|
|
|
|
List.Add(value.ToCSharpObject());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
throw new Exception(
|
|
|
|
$"Tried adding an item to a list at position {index}, but list is only of length {List.Count}");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
List[index] = value.ToCSharpObject();
|
|
|
|
}
|
2018-11-21 13:49:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public override Type Type => Type.UserData;
|
|
|
|
public override object ToCSharpObject()
|
|
|
|
{
|
|
|
|
return List;
|
|
|
|
}
|
|
|
|
|
|
|
|
public override System.Type GetCSharpType()
|
|
|
|
{
|
|
|
|
return List.GetType();
|
|
|
|
}
|
2018-11-23 17:18:07 +00:00
|
|
|
|
2018-11-24 13:35:23 +00:00
|
|
|
public ScriptType GetValueFromIndex(ScriptType index)
|
2018-11-23 17:18:07 +00:00
|
|
|
{
|
2018-11-24 13:35:23 +00:00
|
|
|
var num = (ScriptNumberLong)index;
|
|
|
|
return List[(int) num.Value].ToScriptType();
|
|
|
|
}
|
|
|
|
|
2018-12-09 17:23:06 +00:00
|
|
|
public IEnumerator<ScriptType> GetScriptEnumerator()
|
2018-11-24 13:35:23 +00:00
|
|
|
{
|
|
|
|
for (int i = 0; i < List.Count; i++)
|
|
|
|
{
|
|
|
|
yield return new ScriptNumberLong(i);
|
|
|
|
}
|
2018-11-23 17:18:07 +00:00
|
|
|
}
|
2018-11-24 14:11:33 +00:00
|
|
|
|
|
|
|
public ScriptNumberLong Length()
|
|
|
|
{
|
|
|
|
return new ScriptNumberLong(List.Count);
|
|
|
|
}
|
2018-12-09 10:45:38 +00:00
|
|
|
|
|
|
|
protected bool Equals(ListUserData other)
|
|
|
|
{
|
|
|
|
return List.Equals(other.List);
|
|
|
|
}
|
|
|
|
|
|
|
|
public override bool Equals(object obj)
|
|
|
|
{
|
|
|
|
if (ReferenceEquals(null, obj)) return false;
|
|
|
|
if (ReferenceEquals(this, obj)) return true;
|
2018-12-09 12:47:13 +00:00
|
|
|
if (obj.GetType() == List.GetType())
|
|
|
|
{
|
|
|
|
return List.Equals(obj);
|
|
|
|
}
|
2018-12-09 10:45:38 +00:00
|
|
|
if (obj.GetType() != this.GetType()) return false;
|
|
|
|
return Equals((ListUserData) obj);
|
|
|
|
}
|
|
|
|
|
2018-11-21 13:49:59 +00:00
|
|
|
}
|
|
|
|
}
|