Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion Yail.Shared/Objects/ArrayObj.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

public class ArrayObj : ValueObj, IAccessible
{
public List<ValueObj> Items => Value as List<ValueObj>;

Check warning on line 7 in Yail.Shared/Objects/ArrayObj.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference return.

public ArrayObj(List<ValueObj> items)
public ArrayObj(IEnumerable<ValueObj> items)
{
Value = items;
DataType = EDataType.Array;
Expand Down Expand Up @@ -55,10 +55,25 @@
if (idx >= 0 && idx < Items.Count)
Items[idx] = value;
}

public EDataType GetItemsDataType()
{
return Get().Select(x => x.DataType).FirstOrDefault();
}

public override void Print(bool newLine = false)
{
var x = Get().Select(x => x.Value.ToString()).ToArray();

Check warning on line 66 in Yail.Shared/Objects/ArrayObj.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.

if (GetItemsDataType() == EDataType.String)
{
x = x.Select(x => $@"""{x}""").ToArray();
}
if (GetItemsDataType() == EDataType.Char)
{
x = x.Select(x => $@"'{x}'").ToArray();
}

var output = $"[{string.Join(", ", x)}]";

if (newLine)
Expand All @@ -71,4 +86,9 @@
{
Items.RemoveAt(idxValue);
}

public static ArrayObj operator+ (ArrayObj obj1, ArrayObj obj2)
{
return new ArrayObj(obj1.Get().Concat(obj2.Get()));
}
}
5 changes: 5 additions & 0 deletions Yail.Shared/ValueObj.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ public ValueObj(EDataType dataType, bool isConst = false)
public object? Value { get; set; }
public EDataType DataType { get; set; }

public TValue? GetValue<TValue>()
{
return Value is null ? default : (TValue)Value;
}

public override bool Equals(object? obj)
{
if (obj is ValueObj other)
Expand Down
126 changes: 126 additions & 0 deletions Yail.Tests/ScalarAdditionsTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
using Yail.Tests.Shared;

namespace Yail.Tests;

public class ScalarAdditionsTest : BaseYailTest
{
[Test]
public void PreAddition_Int_On_IntArr()
{
var code = @"
package main

var a = [1, 2, 3] i32;

var x = 1 + a;

print(x);
";

var actual = RunCode(code);

Assert.That(actual, Is.EqualTo("[2, 3, 4]"));
}

[Test]
public void PostAddition_Int_On_IntArr()
{
var code = @"
package main

var a = [1, 2, 3] i32;

var x = a + 1;

print(x);
";

var actual = RunCode(code);

Assert.That(actual, Is.EqualTo("[2, 3, 4]"));
}

[Test]
public void PreAddition_StringArr_On_String()
{
var code = @"
package main

var a = [""foo"", ""bar""] string;

var x = ""foo"" + a;

print(x);
";

var actual = RunCode(code);

Assert.That(actual, Is.EqualTo(@"[""foofoo"", ""foobar""]"));
}

[Test]
public void PostAddition_StringArr_On_String()
{
var code = @"
package main

var a = [""foo"", ""bar""] string;

var x = a + ""foo"";

print(x);
";

var actual = RunCode(code);

Assert.That(actual, Is.EqualTo(@"[""foofoo"", ""barfoo""]"));
}

[Test]
public void PreAddition_Int_On_StringArr_ShouldFail()
{
var code = @"
package main

var a = [""foo"", ""bar""] string;

var x = ""foo"" + 1;

print(x);
";

try
{
RunCode(code);
Assert.Fail();
}
catch
{
Assert.Pass();
}
}

[Test]
public void PostAddition_Int_On_StringArr_ShouldFail()
{
var code = @"
package main

var a = [""foo"", ""bar""] string;

var x = a + 1;

print(x);
";

try
{
RunCode(code);
Assert.Fail();
}
catch
{
Assert.Pass();
}
}
}
61 changes: 61 additions & 0 deletions Yail/Common/OperationsHelper.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
using Yail.Shared;
using Yail.Shared.Objects;

namespace Yail.Common;

public static class OperationsHelper
{
public static ValueObj Add(ValueObj left, ValueObj right)
{
if (left is ArrayObj leftArr && right is ArrayObj rightArr)
{
return leftArr + rightArr;
}

if (left is ArrayObj || right is ArrayObj)
{
return ScalarAdd(left, right);
}

if (left.DataType == EDataType.String || right.DataType == EDataType.String || right.DataType == EDataType.Char)
{
// String concatenation
Expand Down Expand Up @@ -300,4 +311,54 @@ public static object PerformOperation(ValueObj lhs, ValueObj rhs, string operato
_ => throw new InvalidOperationException($"Unsupported operation for types {lhs.DataType} and {rhs.DataType}")
};
}

public static ArrayObj ScalarAdd(ValueObj left, ValueObj right)
{
var output = new ArrayObj(new List<ValueObj>());

// pre add
if (left.DataType == EDataType.Int32 && right is ArrayObj rightArr)
{
var val1 = left.GetValue<int>();
var val2 = rightArr.GetValue<List<ValueObj>>();

foreach (var x in val2)
{
output.Push(new ValueObj(val1 + x.GetValue<int>(), EDataType.Int32));
}
}
// post add
else if (left is ArrayObj leftArr && right.DataType == EDataType.Int32)
{
var val1 = right.GetValue<int>();
var val2 = leftArr.GetValue<List<ValueObj>>();

foreach (var x in val2)
{
output.Push(new ValueObj(x.GetValue<int>() + val1, EDataType.Int32));
}
}
// pre add
else if (right is ArrayObj rightArr2 && rightArr2.Get().First().DataType == EDataType.String)
{
var val = rightArr2.GetValue<List<ValueObj>>();

foreach (var x in val)
{
output.Push(new ValueObj(left.Value + x.GetValue<string>(), EDataType.String));
}
}
// post add
else if (left is ArrayObj leftArr2 && leftArr2.Get().First().DataType == EDataType.String)
{
var val = leftArr2.GetValue<List<ValueObj>>();

foreach (var x in val)
{
output.Push(new ValueObj(x.GetValue<string>() + right.Value, EDataType.String));
}
}

return output;
}
}
Loading