mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-04 06:10:16 +02:00
fcl-passrc: resolver: concat(string1,string2,...)
git-svn-id: trunk@40596 -
This commit is contained in:
parent
36f3508614
commit
ee61fc2102
@ -698,6 +698,8 @@ type
|
||||
procedure PredValue(Value: TResEvalValue; ErrorEl: TPasElement); virtual;
|
||||
procedure SuccValue(Value: TResEvalValue; ErrorEl: TPasElement); virtual;
|
||||
function EvalStrFunc(Params: TParamsExpr; Flags: TResEvalFlags): TResEvalValue; virtual;
|
||||
function EvalStringAddExpr(Expr, LeftExpr, RightExpr: TPasExpr;
|
||||
LeftValue, RightValue: TResEvalValue): TResEvalValue; virtual;
|
||||
function EnumTypeCast(EnumType: TPasEnumType; Expr: TPasExpr;
|
||||
Flags: TResEvalFlags): TResEvalEnum; virtual;
|
||||
{$ifdef FPC_HAS_CPSTRING}
|
||||
@ -1535,9 +1537,6 @@ var
|
||||
UInt: TMaxPrecUInt;
|
||||
Flo: TMaxPrecFloat;
|
||||
aCurrency: TMaxPrecCurrency;
|
||||
{$ifdef FPC_HAS_CPSTRING}
|
||||
LeftCP, RightCP: TSystemCodePage;
|
||||
{$endif}
|
||||
LeftSet, RightSet: TResEvalSet;
|
||||
i: Integer;
|
||||
begin
|
||||
@ -1635,58 +1634,10 @@ begin
|
||||
end;
|
||||
end;
|
||||
{$ifdef FPC_HAS_CPSTRING}
|
||||
revkString:
|
||||
case RightValue.Kind of
|
||||
revkString:
|
||||
begin
|
||||
LeftCP:=GetCodePage(TResEvalString(LeftValue).S);
|
||||
RightCP:=GetCodePage(TResEvalString(RightValue).S);
|
||||
if (LeftCP=RightCP) then
|
||||
begin
|
||||
Result:=TResEvalString.Create;
|
||||
TResEvalString(Result).S:=TResEvalString(LeftValue).S+TResEvalString(RightValue).S;
|
||||
end
|
||||
else
|
||||
begin
|
||||
Result:=TResEvalUTF16.Create;
|
||||
TResEvalUTF16(Result).S:=GetUnicodeStr(TResEvalString(LeftValue).S,Expr.left)
|
||||
+GetUnicodeStr(TResEvalString(RightValue).S,Expr.right);
|
||||
end;
|
||||
end;
|
||||
revkUnicodeString:
|
||||
begin
|
||||
Result:=TResEvalUTF16.Create;
|
||||
TResEvalUTF16(Result).S:=GetUnicodeStr(TResEvalString(LeftValue).S,Expr.left)
|
||||
+TResEvalUTF16(RightValue).S;
|
||||
end;
|
||||
else
|
||||
{$IFDEF VerbosePasResolver}
|
||||
writeln('TResExprEvaluator.EvalBinaryAddExpr string+? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
|
||||
{$ENDIF}
|
||||
RaiseNotYetImplemented(20170601141834,Expr);
|
||||
end;
|
||||
revkString,
|
||||
{$endif}
|
||||
revkUnicodeString:
|
||||
case RightValue.Kind of
|
||||
{$ifdef FPC_HAS_CPSTRING}
|
||||
revkString:
|
||||
begin
|
||||
Result:=TResEvalUTF16.Create;
|
||||
TResEvalUTF16(Result).S:=TResEvalUTF16(LeftValue).S
|
||||
+GetUnicodeStr(TResEvalString(RightValue).S,Expr.right);
|
||||
end;
|
||||
{$endif}
|
||||
revkUnicodeString:
|
||||
begin
|
||||
Result:=TResEvalUTF16.Create;
|
||||
TResEvalUTF16(Result).S:=TResEvalUTF16(LeftValue).S+TResEvalUTF16(RightValue).S;
|
||||
end;
|
||||
else
|
||||
{$IFDEF VerbosePasResolver}
|
||||
writeln('TResExprEvaluator.EvalBinaryAddExpr utf16+? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
|
||||
{$ENDIF}
|
||||
RaiseNotYetImplemented(20170601141811,Expr);
|
||||
end;
|
||||
Result:=EvalStringAddExpr(Expr,Expr.left,Expr.right,LeftValue,RightValue);
|
||||
revkSetOfInt:
|
||||
case RightValue.Kind of
|
||||
revkSetOfInt:
|
||||
@ -4793,6 +4744,72 @@ begin
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
function TResExprEvaluator.EvalStringAddExpr(Expr, LeftExpr,
|
||||
RightExpr: TPasExpr; LeftValue, RightValue: TResEvalValue): TResEvalValue;
|
||||
{$ifdef FPC_HAS_CPSTRING}
|
||||
var
|
||||
LeftCP, RightCP: TSystemCodePage;
|
||||
{$endif}
|
||||
begin
|
||||
case LeftValue.Kind of
|
||||
{$ifdef FPC_HAS_CPSTRING}
|
||||
revkString:
|
||||
case RightValue.Kind of
|
||||
revkString:
|
||||
begin
|
||||
LeftCP:=GetCodePage(TResEvalString(LeftValue).S);
|
||||
RightCP:=GetCodePage(TResEvalString(RightValue).S);
|
||||
if (LeftCP=RightCP) then
|
||||
begin
|
||||
Result:=TResEvalString.Create;
|
||||
TResEvalString(Result).S:=TResEvalString(LeftValue).S+TResEvalString(RightValue).S;
|
||||
end
|
||||
else
|
||||
begin
|
||||
Result:=TResEvalUTF16.Create;
|
||||
TResEvalUTF16(Result).S:=GetUnicodeStr(TResEvalString(LeftValue).S,LeftExpr)
|
||||
+GetUnicodeStr(TResEvalString(RightValue).S,RightExpr);
|
||||
end;
|
||||
end;
|
||||
revkUnicodeString:
|
||||
begin
|
||||
Result:=TResEvalUTF16.Create;
|
||||
TResEvalUTF16(Result).S:=GetUnicodeStr(TResEvalString(LeftValue).S,LeftExpr)
|
||||
+TResEvalUTF16(RightValue).S;
|
||||
end;
|
||||
else
|
||||
{$IFDEF VerbosePasResolver}
|
||||
writeln('TResExprEvaluator.EvalBinaryAddExpr string+? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
|
||||
{$ENDIF}
|
||||
RaiseNotYetImplemented(20170601141834,Expr);
|
||||
end;
|
||||
{$endif}
|
||||
revkUnicodeString:
|
||||
case RightValue.Kind of
|
||||
{$ifdef FPC_HAS_CPSTRING}
|
||||
revkString:
|
||||
begin
|
||||
Result:=TResEvalUTF16.Create;
|
||||
TResEvalUTF16(Result).S:=TResEvalUTF16(LeftValue).S
|
||||
+GetUnicodeStr(TResEvalString(RightValue).S,RightExpr);
|
||||
end;
|
||||
{$endif}
|
||||
revkUnicodeString:
|
||||
begin
|
||||
Result:=TResEvalUTF16.Create;
|
||||
TResEvalUTF16(Result).S:=TResEvalUTF16(LeftValue).S+TResEvalUTF16(RightValue).S;
|
||||
end;
|
||||
else
|
||||
{$IFDEF VerbosePasResolver}
|
||||
writeln('TResExprEvaluator.EvalBinaryAddExpr utf16+? Left=',LeftValue.AsDebugString,' Right=',RightValue.AsDebugString);
|
||||
{$ENDIF}
|
||||
RaiseNotYetImplemented(20170601141811,Expr);
|
||||
end;
|
||||
else
|
||||
RaiseNotYetImplemented(20181219233139,Expr);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TResExprEvaluator.EnumTypeCast(EnumType: TPasEnumType; Expr: TPasExpr;
|
||||
Flags: TResEvalFlags): TResEvalEnum;
|
||||
var
|
||||
|
@ -538,6 +538,7 @@ type
|
||||
bfWriteStr,
|
||||
bfVal,
|
||||
bfConcatArray,
|
||||
bfConcatString,
|
||||
bfCopyArray,
|
||||
bfInsertArray,
|
||||
bfDeleteArray,
|
||||
@ -572,6 +573,7 @@ const
|
||||
'WriteStr',
|
||||
'Val',
|
||||
'Concat',
|
||||
'Concat',
|
||||
'Copy',
|
||||
'Insert',
|
||||
'Delete',
|
||||
@ -1464,6 +1466,9 @@ type
|
||||
procedure ComputeBinaryExprRes(Bin: TBinaryExpr;
|
||||
out ResolvedEl: TPasResolverResult; Flags: TPasResolverComputeFlags;
|
||||
var LeftResolved, RightResolved: TPasResolverResult); virtual;
|
||||
function ComputeAddStringRes(
|
||||
const LeftResolved, RightResolved: TPasResolverResult; ExprEl: TPasExpr;
|
||||
out ResolvedEl: TPasResolverResult): boolean; virtual;
|
||||
procedure ComputeArrayParams(Params: TParamsExpr;
|
||||
out ResolvedEl: TPasResolverResult; Flags: TPasResolverComputeFlags;
|
||||
StartEl: TPasElement);
|
||||
@ -1617,6 +1622,12 @@ type
|
||||
Expr: TPasExpr; RaiseOnError: boolean): integer; virtual;
|
||||
procedure BI_ConcatArray_OnGetCallResult({%H-}Proc: TResElDataBuiltInProc;
|
||||
{%H-}Params: TParamsExpr; out ResolvedEl: TPasResolverResult); virtual;
|
||||
function BI_ConcatString_OnGetCallCompatibility(Proc: TResElDataBuiltInProc;
|
||||
Expr: TPasExpr; RaiseOnError: boolean): integer; virtual;
|
||||
procedure BI_ConcatString_OnGetCallResult({%H-}Proc: TResElDataBuiltInProc;
|
||||
{%H-}Params: TParamsExpr; out ResolvedEl: TPasResolverResult); virtual;
|
||||
procedure BI_ConcatString_OnEval({%H-}Proc: TResElDataBuiltInProc;
|
||||
Params: TParamsExpr; Flags: TResEvalFlags; out Evaluated: TResEvalValue); virtual;
|
||||
function BI_CopyArray_OnGetCallCompatibility(Proc: TResElDataBuiltInProc;
|
||||
Expr: TPasExpr; RaiseOnError: boolean): integer; virtual;
|
||||
procedure BI_CopyArray_OnGetCallResult({%H-}Proc: TResElDataBuiltInProc;
|
||||
@ -9776,90 +9787,9 @@ begin
|
||||
exit;
|
||||
end;
|
||||
eopAdd:
|
||||
case LeftResolved.BaseType of
|
||||
btChar:
|
||||
begin
|
||||
case RightResolved.BaseType of
|
||||
btChar: SetBaseType(btString);
|
||||
{$ifdef FPC_HAS_CPSTRING}
|
||||
btAnsiChar:
|
||||
if BaseTypeChar=btAnsiChar then
|
||||
SetBaseType(btString)
|
||||
else
|
||||
SetBaseType(btUnicodeString);
|
||||
{$endif}
|
||||
btWideChar:
|
||||
if BaseTypeChar=btWideChar then
|
||||
SetBaseType(btString)
|
||||
else
|
||||
SetBaseType(btUnicodeString);
|
||||
else
|
||||
// use right type for result
|
||||
SetRightValueExpr([rrfReadable]);
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
{$ifdef FPC_HAS_CPSTRING}
|
||||
btAnsiChar:
|
||||
begin
|
||||
case RightResolved.BaseType of
|
||||
btChar:
|
||||
if BaseTypeChar=btAnsiChar then
|
||||
SetBaseType(btString)
|
||||
else
|
||||
SetBaseType(btUnicodeString);
|
||||
btAnsiChar:
|
||||
if BaseTypeChar=btAnsiChar then
|
||||
SetBaseType(btString)
|
||||
else
|
||||
SetBaseType(btAnsiString);
|
||||
btWideChar:
|
||||
if BaseTypeChar=btWideChar then
|
||||
SetBaseType(btString)
|
||||
else
|
||||
SetBaseType(btUnicodeString);
|
||||
else
|
||||
// use right type for result
|
||||
SetRightValueExpr([rrfReadable]);
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
{$endif}
|
||||
btWideChar:
|
||||
begin
|
||||
case RightResolved.BaseType of
|
||||
btChar,{$ifdef FPC_HAS_CPSTRING}btAnsiChar,{$endif}btWideChar:
|
||||
if BaseTypeChar=btWideChar then
|
||||
SetBaseType(btString)
|
||||
else
|
||||
SetBaseType(btUnicodeString);
|
||||
else
|
||||
// use right type for result
|
||||
SetRightValueExpr([rrfReadable]);
|
||||
end;
|
||||
if RightResolved.BaseType in btAllStringAndChars then
|
||||
if ComputeAddStringRes(LeftResolved,RightResolved,Bin,ResolvedEl) then
|
||||
exit;
|
||||
end;
|
||||
{$ifdef FPC_HAS_CPSTRING}
|
||||
btShortString:
|
||||
begin
|
||||
case RightResolved.BaseType of
|
||||
btChar,btAnsiChar,btShortString,btWideChar:
|
||||
// use left type for result
|
||||
SetLeftValueExpr([rrfReadable]);
|
||||
else
|
||||
// shortstring + string => string
|
||||
SetRightValueExpr([rrfReadable]);
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
{$endif}
|
||||
btString,{$ifdef FPC_HAS_CPSTRING}btAnsiString,{$endif}btUnicodeString:
|
||||
begin
|
||||
// string + x => string
|
||||
SetLeftValueExpr([rrfReadable]);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
eopLessThan,
|
||||
eopGreaterThan,
|
||||
eopLessthanEqual,
|
||||
@ -10348,6 +10278,117 @@ begin
|
||||
if Flags=[] then ;
|
||||
end;
|
||||
|
||||
function TPasResolver.ComputeAddStringRes(const LeftResolved,
|
||||
RightResolved: TPasResolverResult; ExprEl: TPasExpr; out
|
||||
ResolvedEl: TPasResolverResult): boolean;
|
||||
|
||||
procedure SetBaseType(BaseType: TResolverBaseType);
|
||||
begin
|
||||
SetResolverValueExpr(ResolvedEl,BaseType,FBaseTypes[BaseType],FBaseTypes[BaseType],
|
||||
ExprEl,[rrfReadable]);
|
||||
end;
|
||||
|
||||
procedure SetLeftValueExpr(Flags: TPasResolverResultFlags);
|
||||
begin
|
||||
SetResolverValueExpr(ResolvedEl,LeftResolved.BaseType,
|
||||
LeftResolved.LoTypeEl,LeftResolved.HiTypeEl,ExprEl,Flags);
|
||||
end;
|
||||
|
||||
procedure SetRightValueExpr(Flags: TPasResolverResultFlags);
|
||||
begin
|
||||
SetResolverValueExpr(ResolvedEl,RightResolved.BaseType,
|
||||
RightResolved.LoTypeEl,RightResolved.HiTypeEl,ExprEl,Flags);
|
||||
end;
|
||||
|
||||
begin
|
||||
Result:=true;
|
||||
case LeftResolved.BaseType of
|
||||
btChar:
|
||||
begin
|
||||
case RightResolved.BaseType of
|
||||
btChar: SetBaseType(btString);
|
||||
{$ifdef FPC_HAS_CPSTRING}
|
||||
btAnsiChar:
|
||||
if BaseTypeChar=btAnsiChar then
|
||||
SetBaseType(btString)
|
||||
else
|
||||
SetBaseType(btUnicodeString);
|
||||
{$endif}
|
||||
btWideChar:
|
||||
if BaseTypeChar=btWideChar then
|
||||
SetBaseType(btString)
|
||||
else
|
||||
SetBaseType(btUnicodeString);
|
||||
else
|
||||
// use right type for result
|
||||
SetRightValueExpr([rrfReadable]);
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
{$ifdef FPC_HAS_CPSTRING}
|
||||
btAnsiChar:
|
||||
begin
|
||||
case RightResolved.BaseType of
|
||||
btChar:
|
||||
if BaseTypeChar=btAnsiChar then
|
||||
SetBaseType(btString)
|
||||
else
|
||||
SetBaseType(btUnicodeString);
|
||||
btAnsiChar:
|
||||
if BaseTypeChar=btAnsiChar then
|
||||
SetBaseType(btString)
|
||||
else
|
||||
SetBaseType(btAnsiString);
|
||||
btWideChar:
|
||||
if BaseTypeChar=btWideChar then
|
||||
SetBaseType(btString)
|
||||
else
|
||||
SetBaseType(btUnicodeString);
|
||||
else
|
||||
// use right type for result
|
||||
SetRightValueExpr([rrfReadable]);
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
{$endif}
|
||||
btWideChar:
|
||||
begin
|
||||
case RightResolved.BaseType of
|
||||
btChar,{$ifdef FPC_HAS_CPSTRING}btAnsiChar,{$endif}btWideChar:
|
||||
if BaseTypeChar=btWideChar then
|
||||
SetBaseType(btString)
|
||||
else
|
||||
SetBaseType(btUnicodeString);
|
||||
else
|
||||
// use right type for result
|
||||
SetRightValueExpr([rrfReadable]);
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
{$ifdef FPC_HAS_CPSTRING}
|
||||
btShortString:
|
||||
begin
|
||||
case RightResolved.BaseType of
|
||||
btChar,btAnsiChar,btShortString,btWideChar:
|
||||
// use left type for result
|
||||
SetLeftValueExpr([rrfReadable]);
|
||||
else
|
||||
// shortstring + string => string
|
||||
SetRightValueExpr([rrfReadable]);
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
{$endif}
|
||||
btString,{$ifdef FPC_HAS_CPSTRING}btAnsiString,{$endif}btUnicodeString:
|
||||
begin
|
||||
// string + x => string
|
||||
SetLeftValueExpr([rrfReadable]);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
Result:=false;
|
||||
end;
|
||||
|
||||
procedure TPasResolver.ComputeArrayParams(Params: TParamsExpr; out
|
||||
ResolvedEl: TPasResolverResult; Flags: TPasResolverComputeFlags;
|
||||
StartEl: TPasElement);
|
||||
@ -11906,24 +11947,20 @@ begin
|
||||
{$IFDEF VerbosePasResEval}
|
||||
writeln('TPasResolver.OnExprEvalParams Calling BuiltInProc ',Decl.Name,' ',ResolverBuiltInProcNames[BuiltInProc.BuiltIn]);
|
||||
{$ENDIF}
|
||||
case BuiltInProc.BuiltIn of
|
||||
bfLength: BI_Length_OnEval(BuiltInProc,Params,Flags,Result);
|
||||
bfAssigned: Result:=nil;
|
||||
bfChr: BI_Chr_OnEval(BuiltInProc,Params,Flags,Result);
|
||||
bfOrd: BI_Ord_OnEval(BuiltInProc,Params,Flags,Result);
|
||||
bfLow,bfHigh: BI_LowHigh_OnEval(BuiltInProc,Params,Flags,Result);
|
||||
bfPred,bfSucc: BI_PredSucc_OnEval(BuiltInProc,Params,Flags,Result);
|
||||
bfStrFunc: BI_StrFunc_OnEval(BuiltInProc,Params,Flags,Result);
|
||||
bfConcatArray: Result:=nil;
|
||||
bfCopyArray: Result:=nil;
|
||||
bfTypeInfo: Result:=nil;
|
||||
bfDefault: BI_Default_OnEval(BuiltInProc,Params,Flags,Result);
|
||||
if BuiltInProc.Eval<>nil then
|
||||
BuiltInProc.Eval(BuiltInProc,Params,Flags,Result)
|
||||
else
|
||||
{$IFDEF VerbosePasResEval}
|
||||
writeln('TPasResolver.OnExprEvalParams Unhandled BuiltInProc ',Decl.Name,' ',ResolverBuiltInProcNames[BuiltInProc.BuiltIn]);
|
||||
{$ENDIF}
|
||||
RaiseNotYetImplemented(20170624192324,Params);
|
||||
end;
|
||||
case BuiltInProc.BuiltIn of
|
||||
bfAssigned: Result:=nil;
|
||||
bfConcatArray: Result:=nil;
|
||||
bfCopyArray: Result:=nil;
|
||||
bfTypeInfo: Result:=nil;
|
||||
else
|
||||
{$IFDEF VerbosePasResEval}
|
||||
writeln('TPasResolver.OnExprEvalParams Unhandled BuiltInProc ',Decl.Name,' ',ResolverBuiltInProcNames[BuiltInProc.BuiltIn]);
|
||||
{$ENDIF}
|
||||
RaiseNotYetImplemented(20170624192324,Params);
|
||||
end;
|
||||
{$IFDEF VerbosePasResEval}
|
||||
{AllowWriteln}
|
||||
if Result<>nil then
|
||||
@ -13563,6 +13600,95 @@ begin
|
||||
ResolvedEl.BaseType:=btArrayLit;
|
||||
end;
|
||||
|
||||
function TPasResolver.BI_ConcatString_OnGetCallCompatibility(
|
||||
Proc: TResElDataBuiltInProc; Expr: TPasExpr; RaiseOnError: boolean): integer;
|
||||
var
|
||||
Params: TParamsExpr;
|
||||
i: Integer;
|
||||
Param: TPasExpr;
|
||||
ParamResolved: TPasResolverResult;
|
||||
begin
|
||||
Result:=cIncompatible;
|
||||
if not CheckBuiltInMinParamCount(Proc,Expr,1,RaiseOnError) then
|
||||
exit;
|
||||
Params:=TParamsExpr(Expr);
|
||||
|
||||
for i:=0 to length(Params.Params)-1 do
|
||||
begin
|
||||
// all params: char or string
|
||||
Param:=Params.Params[i];
|
||||
ComputeElement(Param,ParamResolved,[]);
|
||||
if not (rrfReadable in ParamResolved.Flags)
|
||||
or not (ParamResolved.BaseType in btAllStringAndChars) then
|
||||
exit(CheckRaiseTypeArgNo(20181219230329,i+1,Param,ParamResolved,'string',RaiseOnError));
|
||||
end;
|
||||
Result:=cExact;
|
||||
end;
|
||||
|
||||
procedure TPasResolver.BI_ConcatString_OnGetCallResult(
|
||||
Proc: TResElDataBuiltInProc; Params: TParamsExpr; out
|
||||
ResolvedEl: TPasResolverResult);
|
||||
var
|
||||
i: Integer;
|
||||
Param: TPasExpr;
|
||||
ParamResolved, CombinedResolved: TPasResolverResult;
|
||||
begin
|
||||
for i:=0 to length(Params.Params)-1 do
|
||||
begin
|
||||
// all params: char or string
|
||||
Param:=Params.Params[i];
|
||||
ComputeElement(Param,ParamResolved,[]);
|
||||
if i=0 then
|
||||
ResolvedEl:=ParamResolved
|
||||
else
|
||||
begin
|
||||
ComputeAddStringRes(ResolvedEl,ParamResolved,Params,CombinedResolved);
|
||||
ResolvedEl:=CombinedResolved;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TPasResolver.BI_ConcatString_OnEval(Proc: TResElDataBuiltInProc;
|
||||
Params: TParamsExpr; Flags: TResEvalFlags; out Evaluated: TResEvalValue);
|
||||
var
|
||||
i: Integer;
|
||||
Param: TPasExpr;
|
||||
Value, NewValue: TResEvalValue;
|
||||
ok: Boolean;
|
||||
begin
|
||||
Value:=nil;
|
||||
Evaluated:=nil;
|
||||
ok:=false;
|
||||
try
|
||||
for i:=0 to length(Params.Params)-1 do
|
||||
begin
|
||||
// all params: char or string
|
||||
Param:=Params.Params[i];
|
||||
Value:=Eval(Param,Flags);
|
||||
if Value=nil then
|
||||
exit;
|
||||
if i=0 then
|
||||
begin
|
||||
Evaluated:=Value;
|
||||
Value:=nil;
|
||||
end
|
||||
else
|
||||
begin
|
||||
NewValue:=ExprEvaluator.EvalStringAddExpr(Param,Params.Params[i-1],Param,
|
||||
Evaluated,Value);
|
||||
ReleaseEvalValue(Evaluated);
|
||||
Evaluated:=NewValue;
|
||||
ReleaseEvalValue(Value);
|
||||
end;
|
||||
end;
|
||||
ok:=true;
|
||||
finally
|
||||
ReleaseEvalValue(Value);
|
||||
if not ok then
|
||||
ReleaseEvalValue(Evaluated);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TPasResolver.BI_CopyArray_OnGetCallCompatibility(
|
||||
Proc: TResElDataBuiltInProc; Expr: TPasExpr; RaiseOnError: boolean): integer;
|
||||
var
|
||||
@ -15248,7 +15374,8 @@ begin
|
||||
nil,@BI_Assigned_OnFinishParamsExpr,bfAssigned);
|
||||
if bfChr in TheBaseProcs then
|
||||
AddBuiltInProc('Chr','function Chr(const Integer): char',
|
||||
@BI_Chr_OnGetCallCompatibility,@BI_Chr_OnGetCallResult,nil,nil,bfChr);
|
||||
@BI_Chr_OnGetCallCompatibility,@BI_Chr_OnGetCallResult,
|
||||
@BI_Chr_OnEval,nil,bfChr);
|
||||
if bfOrd in TheBaseProcs then
|
||||
AddBuiltInProc('Ord','function Ord(const Enum or Char): integer',
|
||||
@BI_Ord_OnGetCallCompatibility,@BI_Ord_OnGetCallResult,
|
||||
@ -15289,6 +15416,10 @@ begin
|
||||
AddBuiltInProc('Concat','function Concat(const Array1, Array2, ...): Array',
|
||||
@BI_ConcatArray_OnGetCallCompatibility,@BI_ConcatArray_OnGetCallResult,
|
||||
nil,nil,bfConcatArray);
|
||||
if bfConcatString in TheBaseProcs then
|
||||
AddBuiltInProc('Concat','function Concat(const String1, String2, ...): String',
|
||||
@BI_ConcatString_OnGetCallCompatibility,@BI_ConcatString_OnGetCallResult,
|
||||
@BI_ConcatString_OnEval,nil,bfConcatString);
|
||||
if bfCopyArray in TheBaseProcs then
|
||||
AddBuiltInProc('Copy','function Copy(const Array; Start: integer = 0; Count: integer = all): Array',
|
||||
@BI_CopyArray_OnGetCallCompatibility,@BI_CopyArray_OnGetCallResult,
|
||||
|
@ -239,7 +239,7 @@ type
|
||||
|
||||
// strings
|
||||
Procedure TestChar_BuiltInProcs;
|
||||
Procedure TestString_SetLength;
|
||||
Procedure TestString_BuiltInProcs;
|
||||
Procedure TestString_Element;
|
||||
Procedure TestStringElement_MissingArgFail;
|
||||
Procedure TestStringElement_IndexNonIntFail;
|
||||
@ -3220,14 +3220,17 @@ begin
|
||||
ParseProgram;
|
||||
end;
|
||||
|
||||
procedure TTestResolver.TestString_SetLength;
|
||||
procedure TTestResolver.TestString_BuiltInProcs;
|
||||
begin
|
||||
StartProgram(false);
|
||||
Add('var');
|
||||
Add(' s: string;');
|
||||
Add('begin');
|
||||
Add(' SetLength({#a_var}s,3);');
|
||||
Add(' SetLength({#b_var}s,length({#c_read}s));');
|
||||
Add([
|
||||
'var',
|
||||
' s: string;',
|
||||
'begin',
|
||||
' SetLength({#a_var}s,3);',
|
||||
' SetLength({#b_var}s,length({#c_read}s));',
|
||||
' s:=concat(''a'',s);',
|
||||
'']);
|
||||
ParseProgram;
|
||||
CheckAccessMarkers;
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user