Compiler exceptions

This commit is contained in:
Michael Schimmel
2025-11-25 15:51:04 +01:00
parent 4e508d90a5
commit 0a1df4e9fe
9 changed files with 194 additions and 303 deletions
+21 -10
View File
@@ -185,12 +185,21 @@ begin
if node.Kind = akUnquoteSplicing then
begin
var spliceExpr := node.AsUnquoteSplicing.Expression;
var evaluatedSpliceValue := FMacroEvaluator(FMacroScope, spliceExpr);
var evaluatedSpliceValue: TDataValue;
// GUARDED EVALUATION
try
evaluatedSpliceValue := FMacroEvaluator(FMacroScope, spliceExpr);
except
on E: EAstException do
raise;
on E: Exception do
raise EMacroException.Create('Error during macro splice evaluation: ' + E.Message);
end;
if (not evaluatedSpliceValue.IsVoid) and (evaluatedSpliceValue.Kind = vkInterface) then
begin
nodeToSplice := evaluatedSpliceValue.AsIntf<IAstNode>;
// If the result is a block, flatten it into the current list
if nodeToSplice.Kind = akBlockExpression then
newList.AddRange(nodeToSplice.AsBlockExpression.Expressions)
else
@@ -198,7 +207,6 @@ begin
end
else if (not evaluatedSpliceValue.IsVoid) then
begin
// Treat scalar values as constants in the AST
newList.Add(TAst.Constant(evaluatedSpliceValue));
end;
end
@@ -278,12 +286,9 @@ var
begin
expr := Node.Expression;
// Optimization: If unquoting a simple identifier that exists in the macro scope,
// try to resolve it directly to avoid unnecessary evaluation overhead.
if expr.Kind = akIdentifier then
begin
addr := FMacroScope.Resolve(expr.AsIdentifier.Name);
if (addr.Kind = akLocalOrParent) and (addr.ScopeDepth = 0) then
begin
var argValue := FMacroScope.Values[addr];
@@ -295,17 +300,23 @@ begin
end;
end;
// Evaluate the expression at compile time
value := FMacroEvaluator(FMacroScope, expr);
// Evaluate the expression at compile time.
// This executes user code! It must be guarded.
try
value := FMacroEvaluator(FMacroScope, expr);
except
on E: EAstException do
raise;
on E: Exception do
raise EMacroException.Create('Error during macro evaluation: ' + E.Message);
end;
if value.Kind = vkInterface then
begin
// It returned an AST node -> Inject it
Result := value.AsIntf<IAstNode>;
exit;
end;
// It returned a value -> Wrap as Constant
if value.Kind in [vkScalar, vkText, vkVoid] then
Result := TAst.Constant(value)
else