Ast ternary expr replaced by cond expr
This commit is contained in:
@@ -50,7 +50,7 @@ type
|
||||
function VisitFunctionCall(const Node: IFunctionCallNode): IAstNode; override;
|
||||
function VisitBlockExpression(const Node: IBlockExpressionNode): IAstNode; override;
|
||||
function VisitIfExpression(const Node: IIfExpressionNode): IAstNode; override;
|
||||
function VisitTernaryExpression(const Node: ITernaryExpressionNode): IAstNode; override;
|
||||
function VisitCondExpression(const Node: ICondExpressionNode): IAstNode; override; // Replaced Ternary
|
||||
function VisitMemberAccess(const Node: IMemberAccessNode): IAstNode; override;
|
||||
function VisitIndexer(const Node: IIndexerNode): IAstNode; override;
|
||||
function VisitRecordLiteral(const Node: IRecordLiteralNode): IAstNode; override;
|
||||
@@ -221,7 +221,7 @@ begin
|
||||
for i := 0 to Node.Arguments.Count - 1 do
|
||||
newArgs[i] := Accept(Node.Arguments[i]);
|
||||
|
||||
// FIX: Wrap in List
|
||||
// Wrap in List
|
||||
var argList := TArgumentList.Create(newArgs, Node.Arguments.Identity);
|
||||
Result := TAst.Recur(Node.Identity, argList, TTypes.Void);
|
||||
end;
|
||||
@@ -395,7 +395,7 @@ begin
|
||||
temp.Free;
|
||||
end;
|
||||
|
||||
// FIX: Wrap in List
|
||||
// Wrap in List
|
||||
var paramList := TParameterList.Create(newParams, Node.Parameters.Identity);
|
||||
|
||||
Result :=
|
||||
@@ -493,7 +493,7 @@ begin
|
||||
retType := TTypes.Unknown;
|
||||
end;
|
||||
|
||||
// FIX: Wrap in List
|
||||
// Wrap in List
|
||||
var argList := TArgumentList.Create(newArgs, Node.Arguments.Identity);
|
||||
|
||||
Result := TAst.FunctionCall(Node.Identity, newCallee, argList, retType, Node.IsTailCall, nil, False);
|
||||
@@ -514,7 +514,7 @@ begin
|
||||
else
|
||||
blockType := TTypes.Void;
|
||||
|
||||
// FIX: Wrap in List
|
||||
// Wrap in List
|
||||
var exprList := TExpressionList.Create(newExprs, Node.Expressions.Identity);
|
||||
Result := TAst.Block(Node.Identity, exprList, blockType);
|
||||
end;
|
||||
@@ -553,36 +553,80 @@ begin
|
||||
Result := TAst.IfExpr(Node.Identity, newCond, newThen, newElse, resultType);
|
||||
end;
|
||||
|
||||
function TTypeChecker.VisitTernaryExpression(const Node: ITernaryExpressionNode): IAstNode;
|
||||
function TTypeChecker.VisitCondExpression(const Node: ICondExpressionNode): IAstNode;
|
||||
var
|
||||
conditionType, thenType, elseType, resultType: IStaticType;
|
||||
newCond, newThen, newElse: IAstNode;
|
||||
i: Integer;
|
||||
newPairs: TArray<TCondPair>;
|
||||
newElse: IAstNode;
|
||||
condType, branchType, resultType: IStaticType;
|
||||
begin
|
||||
newCond := Accept(Node.Condition);
|
||||
newThen := Accept(Node.ThenBranch);
|
||||
SetLength(newPairs, Length(Node.Pairs));
|
||||
resultType := nil; // Start with nothing
|
||||
|
||||
for i := 0 to High(Node.Pairs) do
|
||||
begin
|
||||
// 1. Visit Condition
|
||||
var newCond := Accept(Node.Pairs[i].Condition);
|
||||
condType := newCond.AsTypedNode.StaticType;
|
||||
|
||||
if (condType.Kind <> stUnknown)
|
||||
and not TTypeRules.CanAssign(TTypes.Ordinal, condType)
|
||||
and not TTypeRules.CanAssign(TTypes.Boolean, condType) then
|
||||
begin
|
||||
if Assigned(FLog) then
|
||||
FLog.AddError(Format('Cond condition must be Boolean or Ordinal, but got %s', [condType.ToString]), Node);
|
||||
end;
|
||||
|
||||
// 2. Visit Branch
|
||||
var newBranch := Accept(Node.Pairs[i].Branch);
|
||||
branchType := newBranch.AsTypedNode.StaticType;
|
||||
|
||||
newPairs[i] := TCondPair.Create(newCond, newBranch);
|
||||
|
||||
// 3. Promote Result Type
|
||||
if resultType = nil then
|
||||
resultType := branchType
|
||||
else
|
||||
begin
|
||||
var promoted := TTypeRules.Promote(resultType, branchType);
|
||||
if promoted = nil then
|
||||
begin
|
||||
if Assigned(FLog) then
|
||||
FLog.AddError(
|
||||
Format('Incompatible types in Cond branches: %s and %s', [resultType.ToString, branchType.ToString]),
|
||||
Node
|
||||
);
|
||||
resultType := TTypes.Unknown;
|
||||
end
|
||||
else
|
||||
resultType := promoted;
|
||||
end;
|
||||
end;
|
||||
|
||||
// 4. Visit Else
|
||||
newElse := Accept(Node.ElseBranch);
|
||||
// Else branch is mandatory in our new AST structure (can be Nop/Void, but is present)
|
||||
var elseType := newElse.AsTypedNode.StaticType;
|
||||
|
||||
conditionType := newCond.AsTypedNode.StaticType;
|
||||
if (conditionType.Kind <> stUnknown)
|
||||
and not TTypeRules.CanAssign(TTypes.Ordinal, conditionType)
|
||||
and not TTypeRules.CanAssign(TTypes.Boolean, conditionType) then
|
||||
begin
|
||||
if Assigned(FLog) then
|
||||
FLog.AddError(Format('Ternary condition must be Boolean or Ordinal, but got %s', [conditionType.ToString]), Node);
|
||||
end;
|
||||
|
||||
thenType := newThen.AsTypedNode.StaticType;
|
||||
elseType := newElse.AsTypedNode.StaticType;
|
||||
|
||||
resultType := TTypeRules.Promote(thenType, elseType);
|
||||
if resultType = nil then
|
||||
resultType := elseType
|
||||
else
|
||||
begin
|
||||
if Assigned(FLog) then
|
||||
FLog.AddError(Format('Cannot promote types %s and %s in Ternary-Expression', [thenType.ToString, elseType.ToString]), Node);
|
||||
resultType := TTypes.Unknown;
|
||||
var promoted := TTypeRules.Promote(resultType, elseType);
|
||||
if promoted = nil then
|
||||
begin
|
||||
if Assigned(FLog) then
|
||||
FLog.AddError(
|
||||
Format('Incompatible types in Cond branches (Else): %s and %s', [resultType.ToString, elseType.ToString]),
|
||||
Node
|
||||
);
|
||||
resultType := TTypes.Unknown;
|
||||
end
|
||||
else
|
||||
resultType := promoted;
|
||||
end;
|
||||
|
||||
Result := TAst.TernaryExpr(Node.Identity, newCond, newThen, newElse, resultType);
|
||||
Result := TAst.CondExpr(Node.Identity, newPairs, newElse, resultType);
|
||||
end;
|
||||
|
||||
function TTypeChecker.VisitMemberAccess(const Node: IMemberAccessNode): IAstNode;
|
||||
@@ -726,7 +770,7 @@ begin
|
||||
scalarDefFields[i] := TScalarRecordField.Create(newFields[i].Key.Value, scalarKind);
|
||||
end;
|
||||
|
||||
// FIX: Wrap in List
|
||||
// Wrap in List
|
||||
var fieldList := TRecordFieldList.Create(newFields, Node.Fields.Identity);
|
||||
|
||||
if allScalar then
|
||||
|
||||
Reference in New Issue
Block a user