Upsilon/Upsilon/BaseTypes/UserData/ListUserData.cs

154 lines
4.7 KiB
C#
Raw Normal View History

using System;
using System.Collections;
2018-11-23 17:18:07 +00:00
using System.Collections.Generic;
2019-01-21 13:03:11 +00:00
using System.Collections.Immutable;
using Upsilon.BaseTypes.Number;
2018-11-23 17:18:07 +00:00
using Upsilon.BaseTypes.ScriptTypeInterfaces;
using Upsilon.BoundTypes;
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 string TypeName { get; }
public ListUserData(IList list)
{
List = list;
2019-01-21 13:03:11 +00:00
var type = list.GetType();
System.Type elementType;
2019-01-21 13:03:11 +00:00
if (type.IsArray)
{
elementType = type.GetElementType();
TypeName = BoundTypeHandler.GetTypeName(elementType);
2019-01-21 13:03:11 +00:00
}
else
{
elementType = type.GetGenericArguments()[0];
TypeName = BoundTypeHandler.GetTypeName(elementType);
}
if (TypeName == null)
{
Type = new CompositeTypeContainer(new TypeContainer[] {BaseTypes.Type.Number, new UndefinedUserDataTypeContainer(elementType)}
.ToImmutableArray());
}
else
{
Type = new CompositeTypeContainer(new TypeContainer[] {BaseTypes.Type.Number, new TypeContainer(TypeName)}
.ToImmutableArray());
2019-01-21 13:03:11 +00:00
}
}
2018-11-23 17:18:07 +00:00
public ScriptType Get(Diagnostics diagnostics, TextSpan span, ScriptType index, EvaluationScope scope)
{
int i;
if (index.Type == BaseTypes.Type.String)
{
2018-11-23 17:18:07 +00:00
var str = (ScriptString)index;
i = int.Parse(str.Value) - 1;
}
else if (index.Type == BaseTypes.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 == BaseTypes.Type.Number || scriptIndex.Type == BaseTypes.Type.Unknown)
2018-12-09 13:05:17 +00:00
{
index = Convert.ToInt32(scriptIndex.ToCSharpObject());
}
else if (scriptIndex.Type == BaseTypes.Type.String)
2018-12-09 13:05:17 +00:00
{
index = int.Parse(((ScriptString) scriptIndex).Value);
}
else
{
2019-01-22 11:28:21 +00:00
throw new ScriptRuntimeException(null,
2018-12-09 13:05:17 +00:00
$"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)
{
throw new Exception(
$"Tried adding an item to a list at position {index}, but list is only of length {List.Count}");
}
if (index == List.Count)
{
List.Add(value.ToCSharpObject());
2018-12-09 13:05:17 +00:00
}
else
{
List[index] = value.ToCSharpObject();
}
}
public override TypeContainer Type { get; }
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);
}
2019-01-20 22:09:08 +00:00
public override string ToString()
{
return string.Join(", ", List);
}
}
}