Upsilon/Upsilon/BaseTypes/UserData/ListUserData.cs

126 lines
3.6 KiB
C#
Raw Normal View History

using System;
using System.Collections;
2018-11-23 17:18:07 +00:00
using System.Collections.Generic;
using Upsilon.BaseTypes.Number;
2018-11-23 17:18:07 +00:00
using Upsilon.BaseTypes.ScriptTypeInterfaces;
using Upsilon.Evaluator;
2018-12-09 13:05:17 +00:00
using Upsilon.Exceptions;
using Upsilon.Text;
namespace Upsilon.BaseTypes.UserData
{
2018-11-24 14:11:33 +00:00
internal class ListUserData : ScriptType, IUserData, IIterable, ILengthType
{
2018-12-09 19:53:07 +00:00
public IList List { get; }
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)
{
int i;
if (index.Type == Type.String)
{
2018-11-23 17:18:07 +00:00
var str = (ScriptString)index;
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;
i = (int) ind.Value - 1;
}
else
{
return null;
}
return List[i].ToScriptType();
}
2018-12-09 13:05:17 +00:00
public void Set(Diagnostics diagnostics, TextSpan span, ScriptType scriptIndex, ScriptType value)
{
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()}",
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();
}
}
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
public ScriptType GetValueFromIndex(ScriptType index)
2018-11-23 17:18:07 +00:00
{
var num = (ScriptNumberLong)index;
return List[(int) num.Value].ToScriptType();
}
public IEnumerator<ScriptType> GetScriptEnumerator()
{
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);
}
}
}