Skip to content

Commit f74636f

Browse files
authored
Feature/input (#218)
* #200 - InputStatement -> OutputStatement * #200 - `IOutputWriter` -> `IConsole` * #200 - `IConsole.ReadLine` method * #200 - update grammar and lex regex * #200 - fix * #200 - fix * #200 - new ast node + parsing * #200 rename * #200 - static analysis * #200 - codegen * #200 - rename * #200 - fix typing * #200 - tests
1 parent 290d02d commit f74636f

File tree

26 files changed

+188
-64
lines changed

26 files changed

+188
-64
lines changed

src/Application/HydraScript.Application.CodeGeneration/IValueFactory.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public interface IValueFactory
88
{
99
public IValue Create(ValueDto dto);
1010

11-
public Name CreateName(IdentifierReference id);
11+
public Name Create(IdentifierReference id);
1212

13-
public Name CreateName(string id);
13+
public Name Create(string id);
1414
}

src/Application/HydraScript.Application.CodeGeneration/Impl/ValueFactory.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public IValue Create(ValueDto dto) =>
2121
_ => throw new ArgumentOutOfRangeException(nameof(dto))
2222
};
2323

24-
public Name CreateName(IdentifierReference id)
24+
public Name Create(IdentifierReference id)
2525
{
2626
var dto = id.ToValueDto();
2727
return dto switch
@@ -34,7 +34,7 @@ public Name CreateName(IdentifierReference id)
3434
};
3535
}
3636

37-
public Name CreateName(string id) => new(id, CurrentFrame);
37+
public Name Create(string id) => new(id, CurrentFrame);
3838

3939
private CurrentFrame CurrentFrame { get; } = new(frameContext);
4040

src/Application/HydraScript.Application.CodeGeneration/Visitors/ExpressionInstructionProvider.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public AddressedInstructions Visit(ArrayLiteral visitable)
4747
{
4848
var arraySize = visitable.Expressions.Count;
4949

50-
var arrayName = _valueFactory.CreateName(visitable.Id);
50+
var arrayName = _valueFactory.Create(visitable.Id);
5151
var createArray = new CreateArray(arrayName, arraySize);
5252

5353
var result = new AddressedInstructions { createArray };
@@ -75,7 +75,7 @@ public AddressedInstructions Visit(ArrayLiteral visitable)
7575

7676
public AddressedInstructions Visit(ObjectLiteral visitable)
7777
{
78-
var objectId = _valueFactory.CreateName(visitable.Id);
78+
var objectId = _valueFactory.Create(visitable.Id);
7979
var createObject = new CreateObject(objectId);
8080

8181
var result = new AddressedInstructions { createObject };
@@ -90,7 +90,7 @@ public AddressedInstructions Visit(ObjectLiteral visitable)
9090

9191
public AddressedInstructions Visit(Property visitable)
9292
{
93-
var objectId = _valueFactory.CreateName(visitable.Object.Id);
93+
var objectId = _valueFactory.Create(visitable.Object.Id);
9494

9595
var (id, expression) = visitable;
9696
var propertyId = new Constant(id);
@@ -123,7 +123,7 @@ public AddressedInstructions Visit(UnaryExpression visitable)
123123
public AddressedInstructions Visit(BinaryExpression visitable)
124124
{
125125
if (visitable is { Left: IdentifierReference arr, Right: PrimaryExpression primary, Operator: "::" })
126-
return [new RemoveFromArray(_valueFactory.CreateName(arr), index: _valueFactory.Create(primary.ToValueDto()))];
126+
return [new RemoveFromArray(_valueFactory.Create(arr), index: _valueFactory.Create(primary.ToValueDto()))];
127127

128128
var result = new AddressedInstructions();
129129
IValue left, right;
@@ -172,7 +172,7 @@ public AddressedInstructions Visit(CastAsExpression visitable)
172172

173173
public AddressedInstructions Visit(WithExpression visitable)
174174
{
175-
var objectId = _valueFactory.CreateName(visitable.ObjectLiteral.Id);
175+
var objectId = _valueFactory.Create(visitable.ObjectLiteral.Id);
176176
var createObject = new CreateObject(objectId);
177177

178178
var result = new AddressedInstructions { createObject };
@@ -197,15 +197,15 @@ public AddressedInstructions Visit(WithExpression visitable)
197197
result.AddRange(visitable.Expression is PrimaryExpression ? [] : visitable.Expression.Accept(This));
198198

199199
var copyFrom = visitable.Expression is IdentifierReference objectIdent
200-
? _valueFactory.CreateName(objectIdent)
200+
? _valueFactory.Create(objectIdent)
201201
: result.OfType<Simple>().Last().Left!;
202202

203203
for (var i = 0; i < visitable.ComputedCopiedProperties.Count; i++)
204204
{
205205
var property = new Constant(visitable.ComputedCopiedProperties[i]);
206206
result.Add(new DotRead(copyFrom, property));
207207
var read = result[result.End].Address.Name;
208-
result.Add(new DotAssignment(objectId, property, _valueFactory.CreateName(read)));
208+
result.Add(new DotAssignment(objectId, property, _valueFactory.Create(read)));
209209
}
210210

211211
return result;
@@ -255,7 +255,7 @@ public AddressedInstructions Visit(AssignmentExpression visitable)
255255
}
256256

257257
if (visitable.Destination.Empty())
258-
result.OfType<Simple>().Last().Left = _valueFactory.CreateName(visitable.Destination.Id);
258+
result.OfType<Simple>().Last().Left = _valueFactory.Create(visitable.Destination.Id);
259259
else
260260
{
261261
var last = result.OfType<Simple>().Last().Left!;
@@ -277,7 +277,7 @@ public AddressedInstructions Visit(DotAccess visitable)
277277
var right = new Constant(visitable.Property.Name);
278278

279279
if (!visitable.HasPrev() && visitable.Parent is LeftHandSideExpression lhs)
280-
return [new DotRead(_valueFactory.CreateName(lhs.Id), right)];
280+
return [new DotRead(_valueFactory.Create(lhs.Id), right)];
281281

282282
var result = visitable.Prev?.Accept(This) ?? [];
283283
var left = result.OfType<Simple>().Last().Left!;
@@ -301,7 +301,7 @@ public AddressedInstructions Visit(IndexAccess visitable)
301301
}
302302

303303
if (!visitable.HasPrev() && visitable.Parent is LeftHandSideExpression lhs)
304-
result.Add(new IndexRead(_valueFactory.CreateName(lhs.Id), right));
304+
result.Add(new IndexRead(_valueFactory.Create(lhs.Id), right));
305305
else
306306
{
307307
result.AddRange(visitable.Prev?.Accept(This) ?? []);
@@ -332,7 +332,7 @@ public AddressedInstructions Visit(CallExpression visitable)
332332
{
333333
var caller = result.Count > 0
334334
? result.OfType<Simple>().Last().Left!
335-
: _valueFactory.CreateName(visitable.Id);
335+
: _valueFactory.Create(visitable.Id);
336336
result.Add(new PushParameter(caller));
337337
}
338338

src/Application/HydraScript.Application.CodeGeneration/Visitors/InstructionProvider.cs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ internal class InstructionProvider : VisitorBase<IAbstractSyntaxTreeNode, Addres
2424
IVisitor<FunctionDeclaration, AddressedInstructions>,
2525
IVisitor<WhileStatement, AddressedInstructions>,
2626
IVisitor<IfStatement, AddressedInstructions>,
27-
IVisitor<PrintStatement, AddressedInstructions>
27+
IVisitor<OutputStatement, AddressedInstructions>,
28+
IVisitor<InputStatement, AddressedInstructions>
2829
{
2930
private readonly IValueFactory _valueFactory;
3031
private readonly IVisitor<IAbstractSyntaxTreeNode, AddressedInstructions> _expressionVisitor;
@@ -132,7 +133,7 @@ public AddressedInstructions Visit(FunctionDeclaration visitable)
132133
for (var i = 0; i < visitable.Arguments.Count; i++)
133134
{
134135
var arg = visitable.Arguments[i];
135-
result.Add(new PopParameter(_valueFactory.CreateName(arg.Name), arg.Info.Value));
136+
result.Add(new PopParameter(_valueFactory.Create(arg.Name), arg.Info.Value));
136137
}
137138

138139
result.AddRange(visitable.Statements.Accept(This));
@@ -230,18 +231,18 @@ public AddressedInstructions Visit(IfStatement visitable)
230231
return result;
231232
}
232233

233-
public AddressedInstructions Visit(PrintStatement visitable)
234+
public AddressedInstructions Visit(OutputStatement visitable)
234235
{
235236
if (visitable.Expression is PrimaryExpression prim)
236237
{
237238
var valueDto = prim.ToValueDto();
238239
var printedValue = _valueFactory.Create(valueDto);
239240
IExecutableInstruction instruction = valueDto is { Type: ValueDtoType.Env } or { Type: ValueDtoType.Constant, Value: string }
240-
? new Print(printedValue)
241+
? new Output(printedValue)
241242
: new AsString(printedValue);
242243
AddressedInstructions shortResult = [instruction];
243244
if (instruction is AsString asString)
244-
shortResult.Add(new Print(asString.Left!));
245+
shortResult.Add(new Output(asString.Left!));
245246
return shortResult;
246247
}
247248

@@ -251,8 +252,11 @@ public AddressedInstructions Visit(PrintStatement visitable)
251252
var name = result.OfType<Simple>().Last().Left!;
252253
var nameAsString = new AsString(name);
253254
result.Add(nameAsString);
254-
result.Add(new Print(nameAsString.Left!));
255+
result.Add(new Output(nameAsString.Left!));
255256

256257
return result;
257258
}
259+
260+
public AddressedInstructions Visit(InputStatement visitable) =>
261+
[new Input(_valueFactory.Create(visitable.Destination))];
258262
}

src/Application/HydraScript.Application.StaticAnalysis/Visitors/SemanticChecker.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ internal class SemanticChecker : VisitorBase<IAbstractSyntaxTreeNode, Type>,
4242
IVisitor<CallExpression, Type>,
4343
IVisitor<FunctionDeclaration, Type>,
4444
IVisitor<BlockStatement, Type>,
45-
IVisitor<PrintStatement, Type>
45+
IVisitor<OutputStatement, Type>,
46+
IVisitor<InputStatement, Type>
4647
{
4748
private readonly IDefaultValueForTypeCalculator _calculator;
4849
private readonly IFunctionWithUndefinedReturnStorage _functionStorage;
@@ -367,7 +368,8 @@ public Type Visit(AssignmentExpression visitable)
367368

368369
public Type Visit(MemberExpression visitable)
369370
{
370-
var idType = visitable.Id.Accept(This);
371+
IAbstractSyntaxTreeNode id = visitable.Id;
372+
var idType = id.Accept(This);
371373
visitable.ComputedIdTypeGuid = _computedTypes.Save(idType);
372374
return visitable.Empty() ? idType : visitable.AccessChain?.Accept(This) ?? "undefined";
373375
}
@@ -548,9 +550,18 @@ public Type Visit(BlockStatement visitable)
548550
return "undefined";
549551
}
550552

551-
public Type Visit(PrintStatement visitable)
553+
public Type Visit(OutputStatement visitable)
552554
{
553555
visitable.Expression.Accept(This);
554556
return "undefined";
555557
}
558+
559+
public Type Visit(InputStatement visitable)
560+
{
561+
IAbstractSyntaxTreeNode id = visitable.Destination;
562+
var idType = id.Accept(This);
563+
if (!idType.Equals("string"))
564+
throw new UnsupportedOperation(visitable.Segment, idType, "<<<");
565+
return "undefined";
566+
}
556567
}
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
namespace HydraScript.Domain.BackEnd;
22

3-
public interface IOutputWriter
3+
public interface IConsole
44
{
55
public void WriteLine(object? obj);
66

77
public void WriteError(Exception e, string message);
8+
9+
public string ReadLine();
810
}

src/Domain/HydraScript.Domain.BackEnd/IExecuteParams.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ public interface IExecuteParams
66

77
public Queue<object?> Arguments { get; }
88

9-
public IOutputWriter Writer { get; }
9+
public IConsole Console { get; }
1010

1111
public IFrameContext FrameContext { get; }
1212
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
namespace HydraScript.Domain.BackEnd.Impl;
22

33
public class ExecuteParams(
4-
IOutputWriter textWriter,
4+
IConsole console,
55
IFrameContext frameContext) : IExecuteParams
66
{
77
public Stack<Call> CallStack { get; } = [];
88

99
public Queue<object?> Arguments { get; } = [];
1010

11-
public IOutputWriter Writer { get; } = textWriter;
11+
public IConsole Console { get; } = console;
1212

1313
public IFrameContext FrameContext { get; } = frameContext;
1414
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using HydraScript.Domain.BackEnd.Impl.Values;
2+
3+
namespace HydraScript.Domain.BackEnd.Impl.Instructions;
4+
5+
public class Input(Name name) : Instruction
6+
{
7+
public override IAddress? Execute(IExecuteParams executeParams)
8+
{
9+
var input = executeParams.Console.ReadLine();
10+
name.Set(input);
11+
return Address.Next;
12+
}
13+
14+
protected override string ToStringInternal() =>
15+
$"Input {name}";
16+
}

src/Domain/HydraScript.Domain.BackEnd/Impl/Instructions/Print.cs renamed to src/Domain/HydraScript.Domain.BackEnd/Impl/Instructions/Output.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
namespace HydraScript.Domain.BackEnd.Impl.Instructions;
22

3-
public class Print(IValue value) : Instruction
3+
public class Output(IValue value) : Instruction
44
{
55
public override IAddress? Execute(IExecuteParams executeParams)
66
{
7-
executeParams.Writer.WriteLine(value.Get());
7+
executeParams.Console.WriteLine(value.Get());
88
return Address.Next;
99
}
1010

1111
protected override string ToStringInternal() =>
12-
$"Print {value}";
12+
$"Output {value}";
1313
}

0 commit comments

Comments
 (0)