Skip to content

Commit ad5ed02

Browse files
committed
#31 - удалил Type из TypeValue
1 parent bbf9d74 commit ad5ed02

22 files changed

+170
-88
lines changed

src/HydraScript.Lib/HydraScript.Lib.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
</PropertyGroup>
99

1010
<ItemGroup>
11-
<PackageReference Include="Visitor.NET" Version="4.1.1" />
11+
<PackageReference Include="Visitor.NET" Version="4.1.2" />
1212
<PackageReference Include="Visitor.NET.AutoVisitableGen" Version="1.3.0" />
1313
</ItemGroup>
1414

src/HydraScript.Lib/IR/Ast/IAbstractSyntaxTreeNode.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ public interface IAbstractSyntaxTreeNode :
77
IVisitable<IAbstractSyntaxTreeNode>
88
{
99
public IAbstractSyntaxTreeNode Parent { get; }
10-
public SymbolTable SymbolTable { get; set; }
10+
public SymbolTable SymbolTable { get; }
11+
public void InitScope(SymbolTable? scope = null);
1112
public IReadOnlyList<IAbstractSyntaxTreeNode> GetAllNodes();
1213
}

src/HydraScript.Lib/IR/Ast/Impl/AbstractSyntaxTreeNode.cs

+10-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,16 @@ public abstract class AbstractSyntaxTreeNode : IAbstractSyntaxTreeNode
77
{
88
public IAbstractSyntaxTreeNode Parent { get; set; } = default!;
99

10-
public SymbolTable SymbolTable { get; set; } = default!;
10+
public SymbolTable SymbolTable { get; protected set; } = default!;
11+
12+
/// <summary>Базовая стратегия - инициализация через родительский узел</summary>
13+
/// <param name="scope">Обязательно <c>null</c></param>
14+
public virtual void InitScope(SymbolTable? scope = null)
15+
{
16+
if (scope is not null)
17+
throw new ArgumentException("'scope' must be null");
18+
SymbolTable = Parent.SymbolTable;
19+
}
1120

1221
public string Segment { get; init; } = string.Empty;
1322

src/HydraScript.Lib/IR/Ast/Impl/Nodes/Declarations/AfterTypesAreLoaded/FunctionDeclaration.cs

+18-2
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
using HydraScript.Lib.IR.Ast.Impl.Nodes.Expressions.PrimaryExpressions;
22
using HydraScript.Lib.IR.Ast.Impl.Nodes.Statements;
3+
using HydraScript.Lib.IR.CheckSemantics.Variables;
34

45
namespace HydraScript.Lib.IR.Ast.Impl.Nodes.Declarations.AfterTypesAreLoaded;
56

67
[AutoVisitable<IAbstractSyntaxTreeNode>]
78
public partial class FunctionDeclaration : AfterTypesAreLoadedDeclaration
89
{
10+
private readonly List<PropertyTypeValue> _arguments;
11+
912
protected override IReadOnlyList<IAbstractSyntaxTreeNode> Children => [Statements];
1013

1114
public IdentifierReference Name { get; }
1215
public TypeValue ReturnTypeValue { get; }
13-
public List<PropertyTypeValue> Arguments { get; }
16+
public IReadOnlyList<PropertyTypeValue> Arguments => _arguments;
17+
1418
public BlockStatement Statements { get; }
1519

1620
public FunctionDeclaration(
@@ -21,7 +25,7 @@ public FunctionDeclaration(
2125
{
2226
Name = name;
2327
ReturnTypeValue = returnTypeValue;
24-
Arguments = arguments;
28+
_arguments = arguments;
2529

2630
Statements = blockStatement;
2731
Statements.Parent = this;
@@ -32,6 +36,18 @@ public FunctionDeclaration(
3236
.ToArray();
3337
}
3438

39+
/// <summary>Стратегия "блока" - углубление скоупа</summary>
40+
/// <param name="scope">Новый скоуп</param>
41+
public override void InitScope(SymbolTable? scope = null)
42+
{
43+
ArgumentNullException.ThrowIfNull(scope);
44+
SymbolTable = scope;
45+
SymbolTable.AddOpenScope(Parent.SymbolTable);
46+
47+
_arguments.ForEach(x => x.TypeValue.SymbolTable = Parent.SymbolTable);
48+
ReturnTypeValue.SymbolTable = Parent.SymbolTable;
49+
}
50+
3551
public bool HasReturnStatement() =>
3652
ReturnStatements.Count > 0;
3753

Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
using HydraScript.Lib.IR.Ast.Impl.Nodes.Expressions.PrimaryExpressions;
2+
using HydraScript.Lib.IR.CheckSemantics.Variables;
23

34
namespace HydraScript.Lib.IR.Ast.Impl.Nodes.Declarations;
45

56
[AutoVisitable<IAbstractSyntaxTreeNode>]
67
public partial class TypeDeclaration(IdentifierReference typeId, TypeValue typeValue) : Declaration
78
{
89
public IdentifierReference TypeId { get; } = typeId;
10+
public TypeValue TypeValue { get; } = typeValue;
911

10-
public Type BuildType() =>
11-
typeValue.BuildType(SymbolTable);
12+
/// <inheritdoc cref="AbstractSyntaxTreeNode.InitScope"/>
13+
public override void InitScope(SymbolTable? scope = null)
14+
{
15+
base.InitScope(scope);
16+
TypeValue.SymbolTable = SymbolTable;
17+
}
1218

1319
protected override string NodeRepresentation() =>
14-
$"type {TypeId.Name} = {typeValue}";
20+
$"type {TypeId.Name} = {TypeValue}";
1521
}
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,29 @@
11
using HydraScript.Lib.IR.Ast.Impl.Nodes.Expressions.PrimaryExpressions;
2-
using HydraScript.Lib.IR.CheckSemantics.Exceptions;
3-
using HydraScript.Lib.IR.CheckSemantics.Types;
42
using HydraScript.Lib.IR.CheckSemantics.Variables;
5-
using HydraScript.Lib.IR.CheckSemantics.Variables.Symbols;
63

74
namespace HydraScript.Lib.IR.Ast.Impl.Nodes.Declarations;
85

9-
public abstract record TypeValue
6+
public abstract record TypeValue : IVisitable<TypeValue>
107
{
11-
public abstract Type BuildType(SymbolTable symbolTable);
8+
public SymbolTable SymbolTable { get; set; } = default!;
9+
public abstract TReturn Accept<TReturn>(IVisitor<TypeValue, TReturn> visitor);
1210
}
1311

14-
public record TypeIdentValue(IdentifierReference TypeId) : TypeValue
12+
[AutoVisitable<TypeValue>]
13+
public partial record TypeIdentValue(IdentifierReference TypeId) : TypeValue
1514
{
16-
public override Type BuildType(SymbolTable symbolTable) =>
17-
symbolTable.FindSymbol<TypeSymbol>(TypeId)?.Type ??
18-
throw new UnknownIdentifierReference(TypeId);
19-
2015
public override string ToString() => TypeId;
2116
}
2217

23-
public record ArrayTypeValue(TypeValue TypeValue) : TypeValue
18+
[AutoVisitable<TypeValue>]
19+
public partial record ArrayTypeValue(TypeValue TypeValue) : TypeValue
2420
{
25-
public override Type BuildType(SymbolTable symbolTable) =>
26-
new ArrayType(TypeValue.BuildType(symbolTable));
27-
2821
public override string ToString() => $"{TypeValue}[]";
2922
}
3023

31-
public record NullableTypeValue(TypeValue TypeValue) : TypeValue
24+
[AutoVisitable<TypeValue>]
25+
public partial record NullableTypeValue(TypeValue TypeValue) : TypeValue
3226
{
33-
public override Type BuildType(SymbolTable symbolTable) =>
34-
new NullableType(TypeValue.BuildType(symbolTable));
35-
3627
public override string ToString() => $"{TypeValue}?";
3728
}
3829

@@ -44,15 +35,10 @@ public override string ToString() =>
4435
$"{Key}: {TypeValue}";
4536
}
4637

47-
public record ObjectTypeValue(
38+
[AutoVisitable<TypeValue>]
39+
public partial record ObjectTypeValue(
4840
IEnumerable<PropertyTypeValue> Properties) : TypeValue
4941
{
50-
public override Type BuildType(SymbolTable symbolTable) =>
51-
new ObjectType(
52-
Properties.Select(x => new PropertyType(
53-
Id: x.Key,
54-
x.TypeValue.BuildType(symbolTable))));
55-
5642
public override string ToString() =>
5743
$"{{{string.Join(';', Properties)}}}";
5844
}

src/HydraScript.Lib/IR/Ast/Impl/Nodes/Expressions/AssignmentExpression.cs

+9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using HydraScript.Lib.IR.Ast.Impl.Nodes.Declarations;
2+
using HydraScript.Lib.IR.CheckSemantics.Variables;
23

34
namespace HydraScript.Lib.IR.Ast.Impl.Nodes.Expressions;
45

@@ -26,5 +27,13 @@ public AssignmentExpression(
2627
DestinationType = destinationType;
2728
}
2829

30+
/// <inheritdoc cref="AbstractSyntaxTreeNode.InitScope"/>
31+
public override void InitScope(SymbolTable? scope = null)
32+
{
33+
base.InitScope(scope);
34+
if (DestinationType is not null)
35+
DestinationType.SymbolTable = SymbolTable;
36+
}
37+
2938
protected override string NodeRepresentation() => "=";
3039
}

src/HydraScript.Lib/IR/Ast/Impl/Nodes/Expressions/CastAsExpression.cs

+8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using HydraScript.Lib.IR.Ast.Impl.Nodes.Declarations;
2+
using HydraScript.Lib.IR.CheckSemantics.Variables;
23

34
namespace HydraScript.Lib.IR.Ast.Impl.Nodes.Expressions;
45

@@ -19,5 +20,12 @@ public CastAsExpression(Expression expression, TypeValue cast)
1920
Cast = cast;
2021
}
2122

23+
/// <inheritdoc cref="AbstractSyntaxTreeNode.InitScope"/>
24+
public override void InitScope(SymbolTable? scope = null)
25+
{
26+
base.InitScope(scope);
27+
Cast.SymbolTable = SymbolTable;
28+
}
29+
2230
protected override string NodeRepresentation() => $"as {Cast}";
2331
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using HydraScript.Lib.IR.Ast.Impl.Nodes.Declarations;
2+
using HydraScript.Lib.IR.CheckSemantics.Variables;
3+
4+
namespace HydraScript.Lib.IR.Ast.Impl.Nodes.Expressions.PrimaryExpressions;
5+
6+
public abstract class AbstractLiteral(TypeValue type) : PrimaryExpression
7+
{
8+
public TypeValue Type { get; } = type;
9+
10+
/// <inheritdoc cref="AbstractSyntaxTreeNode.InitScope"/>
11+
public override void InitScope(SymbolTable? scope = null)
12+
{
13+
base.InitScope(scope);
14+
Type.SymbolTable = Parent.SymbolTable;
15+
}
16+
}

src/HydraScript.Lib/IR/Ast/Impl/Nodes/Expressions/PrimaryExpressions/ImplicitLiteral.cs

+2-3
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@
33
namespace HydraScript.Lib.IR.Ast.Impl.Nodes.Expressions.PrimaryExpressions;
44

55
[AutoVisitable<IAbstractSyntaxTreeNode>]
6-
public partial class ImplicitLiteral(TypeValue typeValue) : PrimaryExpression
6+
public partial class ImplicitLiteral(TypeValue type) : AbstractLiteral(type)
77
{
8-
public TypeValue TypeValue { get; } = typeValue;
98
public object? ComputedDefaultValue { private get; set; }
109

1110
protected override string NodeRepresentation() =>
12-
TypeValue.ToString();
11+
Type.ToString();
1312

1413
public override ValueDto ToValueDto() =>
1514
ValueDto.ConstantDto(

src/HydraScript.Lib/IR/Ast/Impl/Nodes/Expressions/PrimaryExpressions/Literal.cs

+2-4
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,17 @@
33
namespace HydraScript.Lib.IR.Ast.Impl.Nodes.Expressions.PrimaryExpressions;
44

55
[AutoVisitable<IAbstractSyntaxTreeNode>]
6-
public partial class Literal : PrimaryExpression
6+
public partial class Literal : AbstractLiteral
77
{
8-
public TypeValue Type { get; }
98
private readonly object? _value;
109
private readonly string _label;
1110

1211
public Literal(
1312
TypeValue type,
1413
object? value,
1514
string segment,
16-
string? label = null)
15+
string? label = null) : base(type)
1716
{
18-
Type = type;
1917
_label = (label ?? value?.ToString())!;
2018
_value = value;
2119
Segment = segment;

src/HydraScript.Lib/IR/Ast/Impl/Nodes/ScriptBody.cs

+10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using HydraScript.Lib.IR.CheckSemantics.Variables;
2+
13
namespace HydraScript.Lib.IR.Ast.Impl.Nodes;
24

35
[AutoVisitable<IAbstractSyntaxTreeNode>]
@@ -16,5 +18,13 @@ public ScriptBody(IEnumerable<StatementListItem> statementList)
1618
_statementList.ForEach(item => item.Parent = this);
1719
}
1820

21+
/// <summary>В корень дерева загружается стандартная библиотека</summary>
22+
/// <param name="scope">Скоуп std</param>
23+
public override void InitScope(SymbolTable? scope = null)
24+
{
25+
ArgumentNullException.ThrowIfNull(scope);
26+
SymbolTable = scope;
27+
}
28+
1929
protected override string NodeRepresentation() => "Script";
2030
}

src/HydraScript.Lib/IR/Ast/Impl/Nodes/Statements/BlockStatement.cs

+11
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using HydraScript.Lib.IR.CheckSemantics.Variables;
2+
13
namespace HydraScript.Lib.IR.Ast.Impl.Nodes.Statements;
24

35
[AutoVisitable<IAbstractSyntaxTreeNode>]
@@ -16,5 +18,14 @@ public BlockStatement(IEnumerable<StatementListItem> statementList)
1618
_statementList.ForEach(item => item.Parent = this);
1719
}
1820

21+
/// <summary>Стратегия "блока" - углубление скоупа</summary>
22+
/// <param name="scope">Новый скоуп</param>
23+
public override void InitScope(SymbolTable? scope = null)
24+
{
25+
ArgumentNullException.ThrowIfNull(scope);
26+
SymbolTable = scope;
27+
SymbolTable.AddOpenScope(Parent.SymbolTable);
28+
}
29+
1930
protected override string NodeRepresentation() => "{}";
2031
}

src/HydraScript.Lib/IR/CheckSemantics/Visitors/DeclarationVisitor.cs

+5-4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public class DeclarationVisitor : VisitorNoReturnBase<IAbstractSyntaxTreeNode>,
1616
{
1717
private readonly IFunctionWithUndefinedReturnStorage _functionStorage;
1818
private readonly IMethodStorage _methodStorage;
19+
private readonly IVisitor<TypeValue, Type> _typeBuilder = new TypeBuilder();
1920

2021
public DeclarationVisitor(
2122
IFunctionWithUndefinedReturnStorage functionStorage,
@@ -41,8 +42,8 @@ public VisitUnit Visit(LexicalDeclaration visitable)
4142
if (visitable.SymbolTable.ContainsSymbol(assignment.Destination.Id))
4243
throw new DeclarationAlreadyExists(assignment.Destination.Id);
4344

44-
var destinationType = assignment.DestinationType?.BuildType(
45-
assignment.SymbolTable) ?? "undefined";
45+
var destinationType = assignment.DestinationType?.Accept(
46+
_typeBuilder) ?? "undefined";
4647

4748
if (destinationType == "undefined" &&
4849
assignment.Source is ImplicitLiteral or ArrayLiteral { Expressions.Count: 0 })
@@ -68,15 +69,15 @@ public VisitUnit Visit(FunctionDeclaration visitable)
6869
{
6970
var arg = new VariableSymbol(
7071
id: x.Key,
71-
x.TypeValue.BuildType(visitable.Parent.SymbolTable));
72+
x.TypeValue.Accept(_typeBuilder));
7273
visitable.SymbolTable.AddSymbol(arg);
7374
return arg;
7475
}).ToList();
7576

7677
var functionSymbol = new FunctionSymbol(
7778
visitable.Name,
7879
parameters,
79-
visitable.ReturnTypeValue.BuildType(visitable.Parent.SymbolTable),
80+
visitable.ReturnTypeValue.Accept(_typeBuilder),
8081
isEmpty: !visitable.Statements.Any());
8182
if (parameters is [{ Type: ObjectType objectType }, ..] &&
8283
visitable.Arguments is [{ TypeValue: TypeIdentValue }, ..])

src/HydraScript.Lib/IR/CheckSemantics/Visitors/SemanticChecker.cs

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using HydraScript.Lib.IR.Ast;
22
using HydraScript.Lib.IR.Ast.Impl.Nodes;
3+
using HydraScript.Lib.IR.Ast.Impl.Nodes.Declarations;
34
using HydraScript.Lib.IR.Ast.Impl.Nodes.Declarations.AfterTypesAreLoaded;
45
using HydraScript.Lib.IR.Ast.Impl.Nodes.Expressions;
56
using HydraScript.Lib.IR.Ast.Impl.Nodes.Expressions.AccessExpressions;
@@ -41,6 +42,7 @@ public class SemanticChecker : VisitorBase<IAbstractSyntaxTreeNode, Type>,
4142
private readonly IDefaultValueForTypeCalculator _calculator;
4243
private readonly IFunctionWithUndefinedReturnStorage _functionStorage;
4344
private readonly IMethodStorage _methodStorage;
45+
private readonly IVisitor<TypeValue, Type> _typeBuilder = new TypeBuilder();
4446

4547
public SemanticChecker(
4648
IDefaultValueForTypeCalculator calculator,
@@ -131,11 +133,11 @@ public Type Visit(IdentifierReference visitable)
131133
}
132134

133135
public Type Visit(Literal visitable) =>
134-
visitable.Type.BuildType(visitable.Parent.SymbolTable);
136+
visitable.Type.Accept(_typeBuilder);
135137

136138
public Type Visit(ImplicitLiteral visitable)
137139
{
138-
var type = visitable.TypeValue.BuildType(visitable.Parent.SymbolTable);
140+
var type = visitable.Type.Accept(_typeBuilder);
139141
visitable.ComputedDefaultValue = _calculator.GetDefaultValueForType(type);
140142
return type;
141143
}
@@ -365,7 +367,7 @@ public Type Visit(CastAsExpression visitable)
365367
if (exprType.Equals(undefined))
366368
throw new CannotDefineType(visitable.Expression.Segment);
367369

368-
return visitable.Cast.BuildType(visitable.SymbolTable) == "string"
370+
return visitable.Cast.Accept(_typeBuilder) == "string"
369371
? "string"
370372
: throw new NotSupportedException("Other types but 'string' have not been supported for casting yet");
371373
}

0 commit comments

Comments
 (0)