AST
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
unit TestAst;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Myc.Ast,
|
||||
DUnitX.TestFramework;
|
||||
|
||||
type
|
||||
[TestFixture]
|
||||
TTestAst = class
|
||||
private
|
||||
FScope: TExecutionScope;
|
||||
FVisitor: IAstVisitor;
|
||||
public
|
||||
[Setup]
|
||||
procedure Setup;
|
||||
[TearDown]
|
||||
procedure TearDown;
|
||||
|
||||
[Test]
|
||||
procedure TestHelloWorld;
|
||||
[Test]
|
||||
procedure TestVariableDeclarationAndUsage;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
System.Generics.Collections,
|
||||
Myc.Data.Types;
|
||||
|
||||
{ TTestAst }
|
||||
|
||||
procedure TTestAst.Setup;
|
||||
begin
|
||||
// Create scope and visitor once for each test
|
||||
FScope := TExecutionScope.Create;
|
||||
FVisitor := TEvaluatorVisitor.Create(FScope);
|
||||
end;
|
||||
|
||||
procedure TTestAst.TearDown;
|
||||
begin
|
||||
FVisitor := nil;
|
||||
FScope.Free;
|
||||
end;
|
||||
|
||||
procedure TTestAst.TestHelloWorld;
|
||||
var
|
||||
ast: IExpressionNode;
|
||||
resultValue: IDataValue;
|
||||
textValue: IDataTextValue;
|
||||
begin
|
||||
// 1. Build the AST for the expression: "hello " + "world"
|
||||
ast := TAst.BinaryExpr(TAst.Constant(TDataType.Text.CreateValue('hello ')), boAdd, TAst.Constant(TDataType.Text.CreateValue('world')));
|
||||
|
||||
// 2. Execute (evaluate) the AST
|
||||
resultValue := ast.Accept(FVisitor);
|
||||
|
||||
// 3. Assert the result
|
||||
Assert.IsNotNull(resultValue, 'The evaluation must return a value.');
|
||||
Assert.AreEqual(dkText, resultValue.DataType.Kind, 'The result must be of text kind.');
|
||||
|
||||
textValue := TDataType.TValue(resultValue).AsText;
|
||||
Assert.AreEqual('hello world', textValue.Value, 'The string concatenation result is wrong.');
|
||||
end;
|
||||
|
||||
procedure TTestAst.TestVariableDeclarationAndUsage;
|
||||
var
|
||||
varDeclStmt: IStatementNode;
|
||||
blockStmt: IStatementNode;
|
||||
identifierExpr: IExpressionNode;
|
||||
resultValue: IDataValue;
|
||||
ordinalValue: IDataOrdinalValue;
|
||||
begin
|
||||
// 1. Build the AST for the statement: let myVar = 42;
|
||||
varDeclStmt := TAst.VarDecl(TAst.Identifier('myVar'), TAst.Constant(TDataType.Ordinal.CreateValue(42)));
|
||||
|
||||
// It's good practice to wrap statements in a block
|
||||
blockStmt := TAst.Block([varDeclStmt]);
|
||||
|
||||
// 2. Build the AST for the expression that uses the variable: myVar
|
||||
identifierExpr := TAst.Identifier('myVar');
|
||||
|
||||
// 3. Execute the statement to declare and assign the variable
|
||||
blockStmt.Accept(FVisitor);
|
||||
|
||||
// 4. Execute the expression to retrieve the variable's value
|
||||
resultValue := identifierExpr.Accept(FVisitor);
|
||||
|
||||
// 5. Assert the result
|
||||
Assert.IsNotNull(resultValue, 'The evaluation must return a value.');
|
||||
Assert.AreEqual(dkOrdinal, resultValue.DataType.Kind, 'The result must be of ordinal kind.');
|
||||
|
||||
ordinalValue := TDataType.TValue(resultValue).AsOrdinal;
|
||||
Assert.AreEqual(Int64(42), ordinalValue.Value, 'The variable value is wrong.');
|
||||
end;
|
||||
|
||||
initialization
|
||||
TDUnitX.RegisterTestFixture(TTestAst);
|
||||
|
||||
end.
|
||||
Reference in New Issue
Block a user