Files
MycLib/Src/AST/TestAst.pas
T
Michael Schimmel 284fb95985 AST
2025-08-27 15:16:13 +02:00

103 lines
2.8 KiB
ObjectPascal

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.