Skip to content

Commit

Permalink
#55 - запрет на присваивание void (#120)
Browse files Browse the repository at this point in the history
* #55 - test

* #55 - исправление бага

* #55 - доработка вычисления отрезка для выражения вызова

* #55 - доработка теста
  • Loading branch information
Stepami authored Nov 3, 2024
1 parent f40012b commit 3cbc9eb
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using System.Diagnostics.CodeAnalysis;

namespace HydraScript.Application.StaticAnalysis.Exceptions;

[ExcludeFromCodeCoverage]
public class CannotAssignVoid(string segment) : SemanticException(segment, "Cannot assign void");
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ public Type Visit(UnaryExpression visitable)

public Type Visit(LexicalDeclaration visitable)
{
Type undefined = "undefined";
Type undefined = "undefined", @void = "void";

for (var i = 0; i < visitable.Assignments.Count; i++)
{
Expand All @@ -272,6 +272,8 @@ public Type Visit(LexicalDeclaration visitable)
var sourceType = assignment.Source.Accept(This);
if (sourceType.Equals(undefined))
throw new CannotDefineType(assignment.Source.Segment);
if (sourceType.Equals(@void))
throw new CannotAssignVoid(assignment.Source.Segment);
if (!registeredSymbol.Type.Equals(undefined) && !registeredSymbol.Type.Equals(sourceType))
throw new IncompatibleTypesOfOperands(
assignment.Segment,
Expand Down
11 changes: 11 additions & 0 deletions src/Domain/HydraScript.Domain.FrontEnd/Lexer/Token.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@ public record Segment(Coordinates Start, Coordinates End)

public static implicit operator string(Segment segment) =>
segment.ToString();

public static implicit operator Segment(string segment)
{
var coords = segment.Split("-")
.Select(x => x[1..^1].Replace(" ", string.Empty))
.Select(x => x.Split(',').Select(int.Parse).ToArray())
.ToArray();
return new Segment(
new Coordinates(coords[0][0], coords[0][1]),
new Coordinates(coords[1][0], coords[1][1]));
}
}

[ExcludeFromCodeCoverage]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ private Expression CallExpression()
var member = MemberExpression();
if (CurrentIs("LeftParen"))
{
var lp = Expect("LeftParen");
Expect("LeftParen");
var expressions = new List<Expression>();
if (CurrentIs("Ident") || CurrentIsLiteral() ||
CurrentIs("LeftParen") || CurrentIsOperator("-") ||
Expand All @@ -420,9 +420,9 @@ private Expression CallExpression()
expressions.Add(Expression());
}

Expect("RightParen");
var rp = Expect("RightParen");
return new CallExpression((member as MemberExpression)!, expressions)
{ Segment = lp.Segment };
{ Segment = member.Segment + rp.Segment };
}

return member;
Expand All @@ -436,7 +436,7 @@ private Expression MemberExpression()
!CurrentIs("Assign") && !CurrentIs("LeftParen"))
return primary;

var identRef = primary as IdentifierReference;
var identRef = (primary as IdentifierReference)!;
var accessChain = new List<AccessExpression>();
while (CurrentIs("LeftBracket") || CurrentIs("Dot"))
{
Expand Down Expand Up @@ -464,9 +464,12 @@ private Expression MemberExpression()
}

return new MemberExpression(
identRef!,
identRef,
accessChain.FirstOrDefault(),
tail: accessChain.LastOrDefault());
tail: accessChain.LastOrDefault())
{
Segment = identRef.Segment
};
}

private Expression CastExpression()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.CommandLine.Parsing;
using FluentAssertions;

namespace HydraScript.IntegrationTests.ErrorPrograms;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.CommandLine.Parsing;

namespace HydraScript.IntegrationTests.ErrorPrograms;

public class VoidAssignmentTests(TestHostFixture fixture) : IClassFixture<TestHostFixture>
{
[Fact]
public void FunctionDeclared_VoidReturnAssigned_ExitCodeHydraScriptError()
{
const string script =
"""
function func(b: boolean) {
if (b)
return
return
}
let x = func(true)
""";
var runner = fixture.GetRunner(configureTestServices:
services => services.SetupInMemoryScript(script));
var code = runner.Invoke(fixture.InMemoryScript);
code.Should().Be(ExitCodes.HydraScriptError);
fixture.LogMessages.Should()
.Contain(x => x.Contains("Cannot assign void"));
}
}
3 changes: 2 additions & 1 deletion tests/HydraScript.IntegrationTests/GlobalUsings.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Global using directives

global using Xunit;
global using Xunit;
global using FluentAssertions;
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.CommandLine.Parsing;
using FluentAssertions;

namespace HydraScript.IntegrationTests;

Expand Down

0 comments on commit 3cbc9eb

Please sign in to comment.