const ACTION: STR_APPEND is action "STR_APPEND";
const ACTION: STR_CAT is action "STR_CAT";
const ACTION: STR_CHIPOS is action "STR_CHIPOS";
const ACTION: STR_CHPOS is action "STR_CHPOS";
const ACTION: STR_CHSPLIT is action "STR_CHSPLIT";
const ACTION: STR_CLIT is action "STR_CLIT";
const ACTION: STR_CMP is action "STR_CMP";
const ACTION: STR_CPY is action "STR_CPY";
const ACTION: STR_ELEMCPY is action "STR_ELEMCPY";
const ACTION: STR_EQ is action "STR_EQ";
const ACTION: STR_FOR is action "STR_FOR";
const ACTION: STR_FOR_KEY is action "STR_FOR_KEY";
const ACTION: STR_FOR_VAR_KEY is action "STR_FOR_VAR_KEY";
const ACTION: STR_FROM_UTF8 is action "STR_FROM_UTF8";
const ACTION: STR_GE is action "STR_GE";
const ACTION: STR_GT is action "STR_GT";
const ACTION: STR_HASHCODE is action "STR_HASHCODE";
const ACTION: STR_HEAD is action "STR_HEAD";
const ACTION: STR_IDX is action "STR_IDX";
const ACTION: STR_IPOS is action "STR_IPOS";
const ACTION: STR_LE is action "STR_LE";
const ACTION: STR_LIT is action "STR_LIT";
const ACTION: STR_LNG is action "STR_LNG";
const ACTION: STR_LOW is action "STR_LOW";
const ACTION: STR_LPAD is action "STR_LPAD";
const ACTION: STR_LPAD0 is action "STR_LPAD0";
const ACTION: STR_LT is action "STR_LT";
const ACTION: STR_LTRIM is action "STR_LTRIM";
const ACTION: STR_MULT is action "STR_MULT";
const ACTION: STR_NE is action "STR_NE";
const ACTION: STR_POS is action "STR_POS";
const ACTION: STR_POSCPY is action "STR_POSCPY";
const ACTION: STR_PUSH is action "STR_PUSH";
const ACTION: STR_RANGE is action "STR_RANGE";
const ACTION: STR_RCHIPOS is action "STR_RCHIPOS";
const ACTION: STR_RCHPOS is action "STR_RCHPOS";
const ACTION: STR_REPL is action "STR_REPL";
const ACTION: STR_RIPOS is action "STR_RIPOS";
const ACTION: STR_RPAD is action "STR_RPAD";
const ACTION: STR_RPOS is action "STR_RPOS";
const ACTION: STR_RTRIM is action "STR_RTRIM";
const ACTION: STR_SPLIT is action "STR_SPLIT";
const ACTION: STR_STR is action "STR_STR";
const ACTION: STR_SUBSTR is action "STR_SUBSTR";
const ACTION: STR_SUBSTR_FIXLEN is action "STR_SUBSTR_FIXLEN";
const ACTION: STR_TAIL is action "STR_TAIL";
const ACTION: STR_TO_UTF8 is action "STR_TO_UTF8";
const ACTION: STR_TRIM is action "STR_TRIM";
const ACTION: STR_UP is action "STR_UP";
const ACTION: STR_VALUE is action "STR_VALUE";
const proc: str_prototypes (inout file: c_prog) is func
begin
declareExtern(c_prog, "void strAppend (striType *const, const_striType);");
declareExtern(c_prog, "void strAppendN (striType *const, const const_striType[], memSizeType);");
declareExtern(c_prog, "void strAppendTemp (striType *const, const striType);");
declareExtern(c_prog, "striType strChChRepl (const const_striType, const charType, const charType);");
declareExtern(c_prog, "intType strChIPos (const const_striType, const charType, const intType);");
declareExtern(c_prog, "striType strChMult (const charType, const intType);");
declareExtern(c_prog, "intType strChPos (const const_striType, const charType);");
declareExtern(c_prog, "striType strChRepl (const const_striType, const charType, const const_striType);");
declareExtern(c_prog, "arrayType strChSplit (const const_striType, const charType);");
declareExtern(c_prog, "intType strCmpGeneric (const genericType, const genericType);");
declareExtern(c_prog, "intType strCompare (const const_striType, const const_striType);");
declareExtern(c_prog, "striType strConcat (const const_striType, const const_striType);");
declareExtern(c_prog, "striType strConcatChar (const const_striType, const charType);");
declareExtern(c_prog, "striType strConcatCharTemp (striType, const charType);");
declareExtern(c_prog, "striType strConcatN (const const_striType[], memSizeType);");
declareExtern(c_prog, "striType strConcatTemp (striType, const const_striType);");
declareExtern(c_prog, "striType strCLit (const const_striType);");
declareExtern(c_prog, "void strCopy (striType *const, const const_striType);");
declareExtern(c_prog, "void strCpyGeneric (genericType *const, const genericType);");
declareExtern(c_prog, "striType strCreate (const const_striType);");
declareExtern(c_prog, "genericType strCreateGeneric (const genericType);");
declareExtern(c_prog, "void strDestr (const const_striType);");
declareExtern(c_prog, "void strDestrGeneric (const genericType);");
declareExtern(c_prog, "striType strEmpty(void);");
declareExtern(c_prog, "striType strFromUtf8 (const const_striType);");
declareExtern(c_prog, "boolType strGe (const const_striType, const const_striType);");
declareExtern(c_prog, "boolType strGt (const const_striType, const const_striType);");
declareExtern(c_prog, "intType strHashCode (const const_striType);");
declareExtern(c_prog, "intType strHashCodeGeneric (const genericType);");
declareExtern(c_prog, "striType strHead (const_striType, intType);");
declareExtern(c_prog, "void strHeadSlice (const const_striType, const intType, striType);");
declareExtern(c_prog, "striType strHeadAssign (const striType, const intType);");
declareExtern(c_prog, "striType strHeadTemp (const striType, const intType);");
declareExtern(c_prog, "intType strIPos (const const_striType, const const_striType, const intType);");
declareExtern(c_prog, "boolType strLe (const const_striType, const const_striType);");
declareExtern(c_prog, "striType strLit (const const_striType);");
declareExtern(c_prog, "striType strLow (const const_striType);");
declareExtern(c_prog, "striType strLowTemp (const striType);");
declareExtern(c_prog, "striType strLpad (const const_striType, const intType);");
declareExtern(c_prog, "striType strLpadTemp (const striType, const intType);");
declareExtern(c_prog, "striType strLpad0 (const const_striType, const intType);");
declareExtern(c_prog, "striType strLpad0Temp (const striType, const intType);");
declareExtern(c_prog, "boolType strLt (const const_striType, const const_striType);");
declareExtern(c_prog, "striType strLtrim (const const_striType);");
declareExtern(c_prog, "striType strMult (const const_striType, const intType);");
declareExtern(c_prog, "intType strPos (const const_striType, const const_striType);");
declareExtern(c_prog, "void strPush (striType *const, const charType);");
declareExtern(c_prog, "striType strRange (const_striType, intType, intType);");
declareExtern(c_prog, "void strRangeSlice (const const_striType, intType, intType, striType);");
declareExtern(c_prog, "intType strRChIPos (const const_striType, const charType, const intType);");
declareExtern(c_prog, "intType strRChPos (const const_striType, const charType);");
declareExtern(c_prog, "striType strRepl (const const_striType, const const_striType, const const_striType);");
declareExtern(c_prog, "intType strRIPos (const const_striType, const const_striType, const intType);");
declareExtern(c_prog, "striType strRpad (const const_striType, const intType);");
declareExtern(c_prog, "intType strRPos (const const_striType, const const_striType);");
declareExtern(c_prog, "striType strRtrim (const const_striType);");
declareExtern(c_prog, "arrayType strSplit (const const_striType, const const_striType);");
declareExtern(c_prog, "striType strSubstr (const_striType, intType, intType);");
declareExtern(c_prog, "void strSubstrSlice (const const_striType, intType, intType, striType);");
declareExtern(c_prog, "striType strSubstrFixLen (const const_striType, intType, intType);");
declareExtern(c_prog, "void strSubstrFixLenSlice (const const_striType, intType, intType, striType);");
declareExtern(c_prog, "striType strTail (const_striType, intType);");
declareExtern(c_prog, "void strTailSlice (const const_striType, intType, striType);");
declareExtern(c_prog, "striType strTailAssign (const striType, intType);");
declareExtern(c_prog, "striType strToUtf8 (const const_striType);");
declareExtern(c_prog, "striType strTrim (const const_striType);");
declareExtern(c_prog, "striType strUp (const const_striType);");
declareExtern(c_prog, "striType strUpTemp (const striType);");
declareExtern(c_prog, "striType strValue (const const_objRefType);");
declareExtern(c_prog, "const_striType strValueRef (const const_objRefType);");
declareExtern(c_prog, "striType strZero (const intType);");
end func;
const func array reference: getConcatNParamList (in ref_list: params) is func
result
var array reference: concatNParamList is 0 times NIL;
local
var reference: leftParam is NIL;
var reference: rightParam is NIL;
var boolean: concatFound is FALSE;
var ref_list: subExprParams is ref_list.EMPTY;
var ref_list: rightParamList is ref_list.EMPTY;
begin
leftParam := params[1];
rightParam := params[3];
if isActionExpression(rightParam, "STR_CAT") then
rightParamList := getValue(rightParam, ref_list)[2 ..];
concatNParamList := getConcatNParamList(rightParamList);
else
concatNParamList := [] (rightParam);
end if;
repeat
concatFound := FALSE;
if category(leftParam) = CALLOBJECT then
subExprParams := getValue(leftParam, ref_list);
if category(subExprParams[1]) = ACTOBJECT then
if str(getValue(subExprParams[1], ACTION)) = "STR_CAT" then
leftParam := subExprParams[2];
rightParam := subExprParams[4];
if isActionExpression(rightParam, "STR_CAT") then
rightParamList := getValue(rightParam, ref_list)[2 ..];
concatNParamList := getConcatNParamList(rightParamList) & concatNParamList;
else
concatNParamList := [] (rightParam) & concatNParamList;
end if;
concatFound := TRUE;
end if;
end if;
end if;
until not concatFound;
concatNParamList := [] (leftParam) & concatNParamList;
end func;
const func array reference: getAppendExtensions (in reference: extension) is func
result
var array reference: appendNParamList is 0 times NIL;
local
var ref_list: params is ref_list.EMPTY;
begin
if category(extension) = CALLOBJECT then
params := getValue(extension, ref_list);
if category(params[1]) = ACTOBJECT and
str(getValue(params[1], ACTION)) = "STR_CAT" then
appendNParamList := getConcatNParamList(params[2 ..]);
else
appendNParamList := [] (extension);
end if;
else
appendNParamList := [] (extension);
end if;
end func;
const proc: concatConstants (inout array reference: concatNParamList) is func
local
var integer: index is 1;
var reference: evaluatedParam is NIL;
var string: paramValue is "";
begin
while index <= length(concatNParamList) do
if getConstant(concatNParamList[index], STRIOBJECT, evaluatedParam) then
paramValue := getValue(evaluatedParam, string);
if paramValue = "" then
incr(countOptimizations);
ignore(remove(concatNParamList, index));
elsif succ(index) <= length(concatNParamList) and
getConstant(concatNParamList[succ(index)], STRIOBJECT, evaluatedParam) then
incr(countOptimizations);
concatNParamList[index] := alloc(FALSE, getType(concatNParamList[index]),
paramValue & getValue(evaluatedParam, string));
ignore(remove(concatNParamList, succ(index)));
else
incr(index);
end if;
else
incr(index);
end if;
end while;
end func;
const proc: process_const_inline_str_push (in reference: stri, in char: ch,
inout expr_type: c_expr) is func
local
var expr_type: statement is expr_type.value;
var string: stri_name is "";
begin
if isNormalVariable(stri) then
stri_name := normalVariable(stri, statement);
else
incr(statement.temp_num);
stri_name := "tmp_" & str(statement.temp_num);
statement.temp_decls &:= "striType *";
statement.temp_decls &:= stri_name;
statement.temp_decls &:= ";\n";
statement.expr &:= stri_name;
statement.expr &:= "=&(";
process_expr(stri, statement);
statement.expr &:= ");\n";
stri_name := "*" & stri_name;
end if;
statement.expr &:= "if ((";
statement.expr &:= stri_name;
statement.expr &:= ")->size == (";
statement.expr &:= stri_name;
statement.expr &:= ")->capacity) {\n";
statement.expr &:= "strPush(&(";
statement.expr &:= stri_name;
statement.expr &:= "), ";
statement.expr &:= charLiteral(ch);
statement.expr &:= ");\n";
statement.expr &:= "} else {\n";
statement.expr &:= "(";
statement.expr &:= stri_name;
statement.expr &:= ")->mem[(";
statement.expr &:= stri_name;
statement.expr &:= ")->size]=";
statement.expr &:= charLiteral(ch);
statement.expr &:= ";\n";
statement.expr &:= "(";
statement.expr &:= stri_name;
statement.expr &:= ")->size++;\n";
statement.expr &:= "}\n";
doLocalDeclsOfStatement(statement, c_expr);
end func;
const proc: process_const_str_push (in reference: stri, in char: ch,
inout expr_type: c_expr) is func
begin
if inlineFunctions and ccConf.WITH_STRI_CAPACITY then
incr(countInlinedFunctions);
process_const_inline_str_push(stri, ch, c_expr);
else
c_expr.expr &:= "strPush(&(";
process_expr(stri, c_expr);
c_expr.expr &:= "), ";
c_expr.expr &:= charLiteral(ch);
c_expr.expr &:= ");\n";
end if;
end func;
const proc: process_inline_str_push (in reference: stri,
in reference: extension, inout expr_type: c_expr) is func
local
var expr_type: statement is expr_type.value;
var string: stri_name is "";
var string: char_name is "";
begin
if isNormalVariable(stri) then
stri_name := normalVariable(stri, statement);
else
incr(statement.temp_num);
stri_name := "tmp_" & str(statement.temp_num);
statement.temp_decls &:= "striType *";
statement.temp_decls &:= stri_name;
statement.temp_decls &:= ";\n";
statement.expr &:= stri_name;
statement.expr &:= "=&(";
process_expr(stri, statement);
statement.expr &:= ");\n";
stri_name := "*" & stri_name;
end if;
if isNormalVariable(extension) then
char_name := normalVariable(extension, statement);
else
incr(statement.temp_num);
char_name := "tmp_" & str(statement.temp_num);
statement.temp_decls &:= "charType ";
statement.temp_decls &:= char_name;
statement.temp_decls &:= ";\n";
statement.expr &:= char_name;
statement.expr &:= "=";
process_expr(extension, statement);
statement.expr &:= ";\n";
end if;
statement.expr &:= "if ((";
statement.expr &:= stri_name;
statement.expr &:= ")->size == (";
statement.expr &:= stri_name;
statement.expr &:= ")->capacity) {\n";
statement.expr &:= "strPush(&(";
statement.expr &:= stri_name;
statement.expr &:= "), ";
statement.expr &:= char_name;
statement.expr &:= ");\n";
statement.expr &:= "} else {\n";
statement.expr &:= "(";
statement.expr &:= stri_name;
statement.expr &:= ")->mem[(";
statement.expr &:= stri_name;
statement.expr &:= ")->size]=";
statement.expr &:= char_name;
statement.expr &:= ";\n";
statement.expr &:= "(";
statement.expr &:= stri_name;
statement.expr &:= ")->size++;\n";
statement.expr &:= "}\n";
doLocalDeclsOfStatement(statement, c_expr);
end func;
const proc: process_str_push (in reference: stri,
in reference: extension, inout expr_type: c_expr) is func
local
var expr_type: statement is expr_type.value;
begin
if inlineFunctions and ccConf.WITH_STRI_CAPACITY then
incr(countInlinedFunctions);
process_inline_str_push(stri, extension, c_expr);
else
statement.expr := "strPush(&(";
process_expr(stri, statement);
statement.expr &:= "), ";
process_expr(extension, statement);
statement.expr &:= ");\n";
doLocalDeclsOfStatement(statement, c_expr);
end if;
end func;
const proc: process_const_str_append (in reference: param1, in string: stri,
inout expr_type: c_expr) is func
begin
setDiagnosticLine(c_expr);
if stri = "" then
incr(countOptimizations);
c_expr.expr &:= "/* Append empty string */\n";
elsif length(stri) = 1 then
incr(countOptimizations);
process_const_str_push(param1, stri[1], c_expr);
else
c_expr.expr &:= "strAppend(&(";
process_expr(param1, c_expr);
c_expr.expr &:= "), ";
c_expr.expr &:= stringLiteral(stri);
c_expr.expr &:= ");\n";
end if;
end func;
const proc: optimize_str_append (in reference: dest, in reference: extension,
inout expr_type: c_expr) is func
local
var expr_type: statement is expr_type.value;
var array reference: appendExtensions is 0 times NIL;
var string: concatNParamName is "";
var integer: index is 1;
var reference: evaluatedParam is NIL;
var expr_type: c_extension is expr_type.value;
begin
appendExtensions := getAppendExtensions(extension);
concatConstants(appendExtensions);
if length(appendExtensions) >= 2 then
incr(countOptimizations);
incr(statement.temp_num);
concatNParamName := "tmp_" & str(statement.temp_num);
statement.temp_decls &:= "const_striType ";
statement.temp_decls &:= concatNParamName;
statement.temp_decls &:= "[";
statement.temp_decls &:= str(length(appendExtensions));
statement.temp_decls &:= "];\n";
for key index range appendExtensions do
statement.expr &:= concatNParamName;
statement.expr &:= "[";
statement.expr &:= str(pred(index));
statement.expr &:= "] = ";
getAnyParamToExpr(appendExtensions[index], statement);
statement.expr &:= ";\n";
end for;
statement.expr &:= "strAppendN(&(";
process_expr(dest, statement);
statement.expr &:= "), ";
statement.expr &:= concatNParamName;
statement.expr &:= ", ";
statement.expr &:= str(length(appendExtensions));
statement.expr &:= ");\n";
elsif length(appendExtensions) = 1 then
if getConstant(appendExtensions[1], STRIOBJECT, evaluatedParam) then
process_const_str_append(dest, getValue(evaluatedParam, string), c_expr);
else
if isActionExpression(appendExtensions[1], "CHR_STR") then
incr(countOptimizations);
process_str_push(dest, getActionParameter(appendExtensions[1], 1),
statement);
else
prepareAnyParamTemporarys(appendExtensions[1], c_extension, statement);
if c_extension.result_expr <> "" then
statement.expr := "strAppendTemp(&(";
process_expr(dest, statement);
statement.expr &:= "), ";
statement.expr &:= c_extension.result_expr;
else
statement.expr := "strAppend(&(";
process_expr(dest, statement);
statement.expr &:= "), ";
statement.expr &:= c_extension.expr;
end if;
statement.expr &:= ");\n";
end if;
end if;
else
incr(countOptimizations);
statement.expr &:= "/* Append empty string */\n";
end if;
doLocalDeclsOfStatement(statement, c_expr);
end func;
const proc: process_str_append (in reference: param1, in reference: param3,
inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var expr_type: statement is expr_type.value;
var expr_type: c_param1 is expr_type.value;
var expr_type: c_param3 is expr_type.value;
begin
if optimizeStringFunctions then
optimize_str_append(param1, param3, c_expr);
elsif getConstant(param3, STRIOBJECT, evaluatedParam) then
process_const_str_append(param1, getValue(evaluatedParam, string), c_expr);
else
statement.temp_num := c_expr.temp_num;
prepareAnyParamTemporarys(param1, c_param1, statement);
if useSpecialCaseFunctions and
isActionExpression(param3, "CHR_STR") then
incr(countOptimizations);
statement.expr &:= "strPush(&(";
statement.expr &:= c_param1.expr;
statement.expr &:= "), ";
process_expr(getActionParameter(param3, 1), statement);
else
prepareAnyParamTemporarys(param3, c_param3, statement);
if c_param3.expr <> "" then
statement.expr &:= "strAppend(&(";
statement.expr &:= c_param1.expr;
statement.expr &:= "), ";
statement.expr &:= c_param3.expr;
else
statement.expr &:= "strAppendTemp(&(";
statement.expr &:= c_param1.expr;
statement.expr &:= "), ";
statement.expr &:= c_param3.result_expr;
end if;
end if;
statement.expr &:= ");\n";
doLocalDeclsOfStatement(statement, c_expr);
end if;
end func;
const proc: process (STR_APPEND, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
process_str_append(params[1], params[3], c_expr);
end func;
const proc: optimize_str_cat (in ref_list: params, inout expr_type: c_expr) is func
local
var array reference: concatNParamList is 0 times NIL;
var string: concatNParamName is "";
var integer: index is 1;
var reference: evaluatedParam is NIL;
var expr_type: c_param1 is expr_type.value;
begin
concatNParamList := getConcatNParamList(params);
concatConstants(concatNParamList);
if length(concatNParamList) >= 3 then
incr(countOptimizations);
prepare_stri_result(c_expr);
incr(c_expr.temp_num);
concatNParamName := "tmp_" & str(c_expr.temp_num);
c_expr.temp_decls &:= "const_striType ";
c_expr.temp_decls &:= concatNParamName;
c_expr.temp_decls &:= "[";
c_expr.temp_decls &:= str(length(concatNParamList));
c_expr.temp_decls &:= "];\n";
c_expr.result_expr := "(";
for key index range concatNParamList do
if getConstant(concatNParamList[index], STRIOBJECT, evaluatedParam) then
c_expr.temp_assigns &:= concatNParamName;
c_expr.temp_assigns &:= "[";
c_expr.temp_assigns &:= str(pred(index));
c_expr.temp_assigns &:= "] = ";
c_expr.temp_assigns &:= stringLiteral(getValue(evaluatedParam, string));
c_expr.temp_assigns &:= ";\n";
else
c_expr.result_expr &:= concatNParamName;
c_expr.result_expr &:= "[";
c_expr.result_expr &:= str(pred(index));
c_expr.result_expr &:= "] = ";
getAnyParamToResultExpr(concatNParamList[index], c_expr);
c_expr.result_expr &:= ", ";
end if;
end for;
c_expr.result_expr &:= "strConcatN(";
c_expr.result_expr &:= concatNParamName;
c_expr.result_expr &:= ", ";
c_expr.result_expr &:= str(length(concatNParamList));
c_expr.result_expr &:= "))";
elsif length(concatNParamList) = 2 then
prepare_stri_result(c_expr);
prepareAnyParamTemporarys(concatNParamList[1], c_param1, c_expr);
if isActionExpression(concatNParamList[2], "CHR_STR") then
incr(countOptimizations);
if c_param1.expr <> "" then
c_expr.result_expr := "strConcatChar(";
c_expr.result_expr &:= c_param1.expr;
else
c_expr.result_expr := "strConcatCharTemp(";
c_expr.result_expr &:= c_param1.result_expr;
end if;
c_expr.result_expr &:= ", ";
getAnyParamToResultExpr(getActionParameter(concatNParamList[2], 1), c_expr);
else
if c_param1.expr <> "" then
c_expr.result_expr := "strConcat(";
c_expr.result_expr &:= c_param1.expr;
else
c_expr.result_expr := "strConcatTemp(";
c_expr.result_expr &:= c_param1.result_expr;
end if;
c_expr.result_expr &:= ", ";
getAnyParamToResultExpr(concatNParamList[2], c_expr);
end if;
c_expr.result_expr &:= ")";
elsif length(concatNParamList) = 1 then
incr(countOptimizations);
process_expr(concatNParamList[1], c_expr);
else
incr(countOptimizations);
if c_expr.demand >= ASSIGN_RESULT then
c_expr.result_expr := "strEmpty()";
else
c_expr.expr &:= stringLiteral("");
end if;
end if;
end func;
const proc: process (STR_CAT, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var expr_type: c_param1 is expr_type.value;
begin
if optimizeStringFunctions then
optimize_str_cat(params, c_expr);
else
prepare_stri_result(c_expr);
prepareAnyParamTemporarys(params[1], c_param1, c_expr);
if c_param1.result_expr <> "" then
c_expr.result_expr := "strConcatTemp(";
c_expr.result_expr &:= c_param1.result_expr;
else
c_expr.result_expr := "strConcat(";
c_expr.result_expr &:= c_param1.expr;
end if;
c_expr.result_expr &:= ", ";
getAnyParamToResultExpr(params[3], c_expr);
c_expr.result_expr &:= ")";
end if;
end func;
const proc: process (STR_CHIPOS, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
c_expr.expr &:= "strChIPos(";
getAnyParamToExpr(params[1], c_expr);
c_expr.expr &:= ", ";
process_expr(params[2], c_expr);
c_expr.expr &:= ", ";
process_expr(params[3], c_expr);
c_expr.expr &:= ")";
end func;
const func integer: lengthToSearch (in string: mainStri) is func
result
var integer: length is 0;
begin
for length range length(mainStri) downto 1
until pos(mainStri[.. pred(length)], mainStri[length]) = 0 do
noop;
end for;
end func;
const func string: reduceMainStriLengthForCharSearch (in string: mainStri) is
return mainStri[.. lengthToSearch(mainStri)];
const proc: process_const_str_chpos (in string: mainStri, in reference: searched,
inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var string: searchedName is "";
var integer: index is 0;
var string: memchrResultName is "";
begin
if getConstant(searched, CHAROBJECT, evaluatedParam) then
incr(countOptimizations);
c_expr.expr &:= "/* pos(";
c_expr.expr &:= replace(literal(mainStri), "*/", "*\\/");
c_expr.expr &:= ",";
c_expr.expr &:= literal(getValue(evaluatedParam, char));
c_expr.expr &:= ") */ ";
c_expr.expr &:= integerLiteral(pos(mainStri, getValue(evaluatedParam, char)));
elsif length(mainStri) = 0 then
incr(countOptimizations);
c_expr.expr &:= "/* pos(\"\", *) */ ";
c_expr.expr &:= integerLiteral(0);
elsif length(mainStri) = 1 then
incr(countOptimizations);
c_expr.expr &:= "/* pos(";
c_expr.expr &:= replace(literal(mainStri), "*/", "*\\/");
c_expr.expr &:= ", *) */ ";
c_expr.expr &:= charLiteral(mainStri[1]);
c_expr.expr &:= "==(";
process_expr(searched, c_expr);
c_expr.expr &:= ")?";
c_expr.expr &:= integerLiteral(1);
c_expr.expr &:= ":";
c_expr.expr &:= integerLiteral(0);
elsif length(mainStri) <= 2 then
incr(countOptimizations);
c_expr.expr &:= "(";
searchedName := getParameterAsVariable("charType", "searched_", searched, c_expr);
for key index range mainStri do
if pos(mainStri[.. pred(index)], mainStri[index]) = 0 then
c_expr.expr &:= searchedName;
c_expr.expr &:= "==";
c_expr.expr &:= charLiteral(mainStri[index]);
c_expr.expr &:= "?";
c_expr.expr &:= integerLiteral(index);
c_expr.expr &:= ":";
end if;
end for;
c_expr.expr &:= integerLiteral(0);
c_expr.expr &:= ")";
elsif inlineFunctions and isByteString(mainStri) then
incr(countOptimizations);
c_expr.expr &:= "(";
searchedName := getParameterAsVariable("charType", "searched_", searched, c_expr);
memchrResultName := getTempVariable("unsigned char *", "ptr_", "", c_expr);
c_expr.expr &:= searchedName;
c_expr.expr &:= ">255?0:(";
c_expr.expr &:= memchrResultName;
c_expr.expr &:= "=memchr(";
c_expr.expr &:= bstriLiteral(bstring(mainStri));
c_expr.expr &:= ".mem[0],(unsigned char)";
c_expr.expr &:= searchedName;
c_expr.expr &:= ",";
c_expr.expr &:= integerLiteral(length(mainStri));
c_expr.expr &:= "),";
c_expr.expr &:= memchrResultName;
c_expr.expr &:= "==NULL?0:(intType)(";
c_expr.expr &:= memchrResultName;
c_expr.expr &:= "-bst[";
c_expr.expr &:= str(bstri_const_table[bstring(mainStri)]);
c_expr.expr &:= "].mem+1)))";
else
c_expr.expr &:= "strChPos(";
c_expr.expr &:= stringLiteral(mainStri);
c_expr.expr &:= ", ";
process_expr(searched, c_expr);
c_expr.expr &:= ")";
end if;
end func;
const proc: process (STR_CHPOS, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
begin
if getConstant(params[1], STRIOBJECT, evaluatedParam) then
process_const_str_chpos(
reduceMainStriLengthForCharSearch(getValue(evaluatedParam, string)),
params[2], c_expr);
else
c_expr.expr &:= "strChPos(";
getAnyParamToExpr(params[1], c_expr);
c_expr.expr &:= ", ";
process_expr(params[2], c_expr);
c_expr.expr &:= ")";
end if;
end func;
const proc: process (STR_CHSPLIT, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
prepare_typed_result(array_type[getExprResultType(params[1])], c_expr);
c_expr.result_expr := "strChSplit(";
getAnyParamToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(params[2], c_expr);
c_expr.result_expr &:= ")";
end func;
const proc: process (STR_CLIT, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
prepare_stri_result(c_expr);
c_expr.result_expr := "strCLit(";
getAnyParamToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ")";
end func;
const proc: process (STR_CMP, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
c_expr.expr &:= "strCompare(";
getAnyParamToExpr(params[1], c_expr);
c_expr.expr &:= ", ";
getAnyParamToExpr(params[2], c_expr);
c_expr.expr &:= ")";
end func;
const proc: process (STR_CPY, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var expr_type: statement is expr_type.value;
var expr_type: c_param1 is expr_type.value;
var expr_type: c_param3 is expr_type.value;
var boolean: codeGenerated is FALSE;
begin
if useSpecialCaseFunctions and
isActionExpression(params[3], "STR_CAT") and
getActionParameter(params[3], 1) = params[1] then
incr(countOptimizations);
process_str_append(params[1], getActionParameter(params[3], 3), c_expr);
else
statement.temp_num := c_expr.temp_num;
prepareAnyParamTemporarys(params[1], c_param1, statement);
if useSpecialCaseFunctions then
if isActionExpression(params[3], "STR_HEAD") and
getActionParameter(params[3], 1) = params[1] then
incr(countOptimizations);
statement.expr &:= c_param1.expr;
statement.expr &:= "=strHeadAssign(";
statement.expr &:= c_param1.expr;
statement.expr &:= ", ";
process_expr(getActionParameter(params[3], 4), statement);
statement.expr &:= ");\n";
codeGenerated := TRUE;
elsif isActionExpression(params[3], "STR_TAIL") and
getActionParameter(params[3], 1) = params[1] then
incr(countOptimizations);
statement.expr &:= c_param1.expr;
statement.expr &:= "=strTailAssign(";
statement.expr &:= c_param1.expr;
statement.expr &:= ", ";
process_expr(getActionParameter(params[3], 3), statement);
statement.expr &:= ");\n";
codeGenerated := TRUE;
elsif isActionExpression(params[3], "STR_LOW") and
getActionParameter(params[3], 1) = params[1] then
incr(countOptimizations);
statement.expr &:= c_param1.expr;
statement.expr &:= "=strLowTemp(";
statement.expr &:= c_param1.expr;
statement.expr &:= ");\n";
codeGenerated := TRUE;
elsif isActionExpression(params[3], "STR_UP") and
getActionParameter(params[3], 1) = params[1] then
incr(countOptimizations);
statement.expr &:= c_param1.expr;
statement.expr &:= "=strUpTemp(";
statement.expr &:= c_param1.expr;
statement.expr &:= ");\n";
codeGenerated := TRUE;
end if;
end if;
if not codeGenerated then
c_param3.demand := ASSIGN_RESULT;
prepareAnyParamTemporarys(params[3], c_param3, statement);
if c_param3.result_expr <> "" then
statement.temp_decls &:= "striType new_stri;\n";
statement.expr &:= "new_stri=";
statement.expr &:= c_param3.result_expr;
statement.expr &:= ";\n";
if isNormalVariable(params[1]) then
statement.expr &:= "strDestr(";
statement.expr &:= c_param1.expr;
statement.expr &:= ");\n";
statement.expr &:= c_param1.expr;
statement.expr &:= "=new_stri;\n";
else
statement.temp_decls &:= "striType *stri_ptr=&(";
statement.temp_decls &:= c_param1.expr;
statement.temp_decls &:= ");\n";
statement.expr &:= "strDestr(*stri_ptr);\n";
statement.expr &:= "*stri_ptr=new_stri;\n";
end if;
else
statement.expr &:= "strCopy(&(";
statement.expr &:= c_param1.expr;
statement.expr &:= "), ";
statement.expr &:= c_param3.expr;
statement.expr &:= ");\n";
end if;
end if;
doLocalDeclsOfStatement(statement, c_expr);
end if;
end func;
const proc: process_const_str_elemcpy (in reference: destStri,
in integer: position, in char: aChar, inout expr_type: c_expr) is func
local
var expr_type: statement is expr_type.value;
var string: destStriName is "";
begin
incr(countOptimizations);
if position < 1 then
c_expr.expr &:= "/* 'string @:= [n] char' with n < 1 */\n";
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= raiseError("INDEX_ERROR");
else
if string_index_check then
incr(countIndexChecks);
if isNormalVariable(destStri) then
destStriName := normalVariable(destStri, statement);
else
incr(statement.temp_num);
destStriName := "tmp_" & str(statement.temp_num);
statement.temp_decls &:= "striType *";
statement.temp_decls &:= destStriName;
statement.temp_decls &:= ";\n";
statement.expr &:= destStriName;
statement.expr &:= "=&(";
process_expr(destStri, statement);
statement.expr &:= ");\n";
destStriName := "*" & destStriName;
end if;
statement.expr &:= "if (idxChk((";
statement.expr &:= destStriName;
statement.expr &:= ")->size<=";
statement.expr &:= integerLiteral(pred(position));
statement.expr &:= ")) {\n";
statement.expr &:= " ";
statement.expr &:= raiseError("INDEX_ERROR");
statement.expr &:= "} else {\n";
statement.expr &:= " (";
statement.expr &:= destStriName;
statement.expr &:= ")->mem[";
statement.expr &:= integerLiteral(pred(position));
statement.expr &:= "] = (strElemType)(";
statement.expr &:= c_literal(aChar);
statement.expr &:= ");\n";
statement.expr &:= "}\n";
else
incr(countSuppressedIndexChecks);
statement.expr &:= "(";
process_expr(destStri, statement);
statement.expr &:= ")->mem[";
statement.expr &:= integerLiteral(pred(position));
statement.expr &:= "] = (strElemType)(";
statement.expr &:= c_literal(aChar);
statement.expr &:= ");\n";
end if;
doLocalDeclsOfStatement(statement, c_expr);
end if;
end func;
const proc: process_const_str_elemcpy (in reference: destStri,
in integer: position, in reference: aChar, inout expr_type: c_expr) is func
local
var expr_type: statement is expr_type.value;
var string: destStriName is "";
begin
incr(countOptimizations);
if position < 1 then
c_expr.expr &:= "/* 'string @:= [n] char' with n < 1 */\n";
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= raiseError("INDEX_ERROR");
else
if string_index_check then
incr(countIndexChecks);
if isNormalVariable(destStri) then
destStriName := normalVariable(destStri, statement);
else
incr(statement.temp_num);
destStriName := "tmp_" & str(statement.temp_num);
statement.temp_decls &:= "striType *";
statement.temp_decls &:= destStriName;
statement.temp_decls &:= ";\n";
statement.expr &:= destStriName;
statement.expr &:= "=&(";
process_expr(destStri, statement);
statement.expr &:= ");\n";
destStriName := "*" & destStriName;
end if;
statement.expr &:= "if (idxChk((";
statement.expr &:= destStriName;
statement.expr &:= ")->size<=";
statement.expr &:= integerLiteral(pred(position));
statement.expr &:= ")) {\n";
statement.expr &:= " ";
statement.expr &:= raiseError("INDEX_ERROR");
statement.expr &:= "} else {\n";
statement.expr &:= " (";
statement.expr &:= destStriName;
statement.expr &:= ")->mem[";
statement.expr &:= integerLiteral(pred(position));
statement.expr &:= "] = (strElemType)(";
process_expr(aChar, statement);
statement.expr &:= ");\n";
statement.expr &:= "}\n";
else
incr(countSuppressedIndexChecks);
statement.expr &:= "(";
process_expr(destStri, statement);
statement.expr &:= ")->mem[";
statement.expr &:= integerLiteral(pred(position));
statement.expr &:= "] = (strElemType)(";
process_expr(aChar, statement);
statement.expr &:= ");\n";
end if;
doLocalDeclsOfStatement(statement, c_expr);
end if;
end func;
const proc: process_const_str_elemcpy (in reference: destStri,
in reference: position, in char: aChar, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var expr_type: statement is expr_type.value;
var string: destStriName is "";
var string: positionName is "";
begin
if getConstant(position, INTOBJECT, evaluatedParam) then
process_const_str_elemcpy(destStri, getValue(evaluatedParam, integer), aChar, c_expr);
else
incr(countOptimizations);
if string_index_check then
incr(countIndexChecks);
if isNormalVariable(destStri) then
destStriName := normalVariable(destStri, statement);
else
incr(statement.temp_num);
destStriName := "tmp_" & str(statement.temp_num);
statement.temp_decls &:= "striType *";
statement.temp_decls &:= destStriName;
statement.temp_decls &:= ";\n";
statement.expr &:= destStriName;
statement.expr &:= "=&(";
process_expr(destStri, statement);
statement.expr &:= ");\n";
destStriName := "*" & destStriName;
end if;
incr(statement.temp_num);
positionName := "pos_" & str(statement.temp_num);
if ccConf.TWOS_COMPLEMENT_INTTYPE then
statement.temp_decls &:= "uintType ";
else
statement.temp_decls &:= "intType ";
end if;
statement.temp_decls &:= positionName;
statement.temp_decls &:= ";\n";
statement.expr &:= positionName;
statement.expr &:= "=";
if ccConf.TWOS_COMPLEMENT_INTTYPE then
statement.expr &:= "(uintType)(";
process_expr(position, statement);
statement.expr &:= ")-1;\n";
statement.expr &:= "if (idxChk(";
statement.expr &:= positionName;
statement.expr &:= ">=";
else
process_expr(position, statement);
statement.expr &:= ";\n";
statement.expr &:= "if (idxChk(";
statement.expr &:= positionName;
statement.expr &:= "<=0 || ";
statement.expr &:= positionName;
statement.expr &:= ">";
end if;
statement.expr &:= "(";
statement.expr &:= destStriName;
statement.expr &:= ")->size)) {\n";
statement.expr &:= " ";
statement.expr &:= raiseError("INDEX_ERROR");
statement.expr &:= "} else {\n";
statement.expr &:= " (";
statement.expr &:= destStriName;
statement.expr &:= ")->mem[";
statement.expr &:= positionName;
if ccConf.TWOS_COMPLEMENT_INTTYPE then
statement.expr &:= "] = (strElemType)(";
else
statement.expr &:= "-1] = (strElemType)(";
end if;
statement.expr &:= c_literal(aChar);
statement.expr &:= ");\n";
statement.expr &:= "}\n";
else
incr(countSuppressedIndexChecks);
statement.expr &:= "(";
process_expr(destStri, statement);
statement.expr &:= ")->mem[(";
process_expr(position, statement);
statement.expr &:= ")-1] = (strElemType)(";
statement.expr &:= c_literal(aChar);
statement.expr &:= ");\n";
end if;
doLocalDeclsOfStatement(statement, c_expr);
end if;
end func;
const proc: process_str_elemcpy_last_char (in reference: destStri,
in reference: aChar, inout expr_type: c_expr) is func
local
var expr_type: statement is expr_type.value;
var string: destStriName is "";
begin
statement.expr &:= "/* stri @:= [length[stri)] ch; */\n";
if isNormalVariable(destStri) then
destStriName := normalVariable(destStri, statement);
else
incr(statement.temp_num);
destStriName := "tmp_" & str(statement.temp_num);
statement.temp_decls &:= "striType *";
statement.temp_decls &:= destStriName;
statement.temp_decls &:= ";\n";
statement.expr &:= destStriName;
statement.expr &:= "=&(";
process_expr(destStri, statement);
statement.expr &:= ");\n";
destStriName := "*" & destStriName;
end if;
if string_index_check then
statement.expr &:= "if (idxChk(";
statement.expr &:= destStriName;
statement.expr &:= "->size==0)) {\n";
statement.expr &:= raiseError("INDEX_ERROR");
statement.expr &:= "} else {\n";
end if;
statement.expr &:= destStriName;
statement.expr &:= "->mem[";
statement.expr &:= destStriName;
statement.expr &:= "->size-1] = (";
process_expr(aChar, statement);
statement.expr &:= ");\n";
if string_index_check then
statement.expr &:= "}\n";
end if;
doLocalDeclsOfStatement(statement, c_expr);
end func;
const proc: process (STR_ELEMCPY, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var expr_type: statement is expr_type.value;
var string: destStriName is "";
var string: positionName is "";
begin
if optimizeStringFunctions and
isActionExpression(params[4], "STR_LNG") and
getActionParameter(params[4], 1) = params[1] then
process_str_elemcpy_last_char(params[1], params[6], c_expr);
elsif getConstant(params[6], CHAROBJECT, evaluatedParam) then
process_const_str_elemcpy(params[1], params[4], getValue(evaluatedParam, char), c_expr);
elsif getConstant(params[4], INTOBJECT, evaluatedParam) then
process_const_str_elemcpy(params[1], getValue(evaluatedParam, integer), params[6], c_expr);
else
if string_index_check then
incr(countIndexChecks);
if isNormalVariable(params[1]) then
destStriName := normalVariable(params[1], statement);
else
incr(statement.temp_num);
destStriName := "tmp_" & str(statement.temp_num);
statement.temp_decls &:= "striType *";
statement.temp_decls &:= destStriName;
statement.temp_decls &:= ";\n";
statement.expr &:= destStriName;
statement.expr &:= "=&(";
process_expr(params[1], statement);
statement.expr &:= ");\n";
destStriName := "*" & destStriName;
end if;
incr(statement.temp_num);
positionName := "pos_" & str(statement.temp_num);
if ccConf.TWOS_COMPLEMENT_INTTYPE then
statement.temp_decls &:= "uintType ";
else
statement.temp_decls &:= "intType ";
end if;
statement.temp_decls &:= positionName;
statement.temp_decls &:= ";\n";
statement.expr &:= positionName;
statement.expr &:= "=";
if ccConf.TWOS_COMPLEMENT_INTTYPE then
statement.expr &:= "(uintType)(";
process_expr(params[4], statement);
statement.expr &:= ")-1;\n";
statement.expr &:= "if (idxChk(";
statement.expr &:= positionName;
statement.expr &:= ">=";
else
process_expr(params[4], statement);
statement.expr &:= ";\n";
statement.expr &:= "if (idxChk(";
statement.expr &:= positionName;
statement.expr &:= "<=0 || ";
statement.expr &:= positionName;
statement.expr &:= ">";
end if;
statement.expr &:= "(";
statement.expr &:= destStriName;
statement.expr &:= ")->size)) {\n";
statement.expr &:= " ";
statement.expr &:= raiseError("INDEX_ERROR");
statement.expr &:= "} else {\n";
statement.expr &:= " (";
statement.expr &:= destStriName;
statement.expr &:= ")->mem[";
statement.expr &:= positionName;
if ccConf.TWOS_COMPLEMENT_INTTYPE then
statement.expr &:= "] = (strElemType)(";
else
statement.expr &:= "-1] = (strElemType)(";
end if;
process_expr(params[6], statement);
statement.expr &:= ");\n";
statement.expr &:= "}\n";
else
incr(countSuppressedIndexChecks);
statement.expr &:= "(";
process_expr(params[1], statement);
statement.expr &:= ")->mem[(";
process_expr(params[4], statement);
statement.expr &:= ")-1] = (strElemType)(";
process_expr(params[6], statement);
statement.expr &:= ");\n";
end if;
doLocalDeclsOfStatement(statement, c_expr);
end if;
end func;
const func boolean: optimize_str_eq_of_substr_fixlen (in reference: stri1,
in reference: start1, in reference: length1, in reference: stri2,
in reference: start2, in reference: length2, inout expr_type: c_expr) is func
result
var boolean: optimizationDone is FALSE;
local
var reference: evaluatedParam is NIL;
var string: stri1_name is "";
var string: stri1_size is "";
var string: stri2_name is "";
var string: stri2_size is "";
var boolean: start1_is_variable is TRUE;
var string: start1_name is "";
var integer: start1_value is 0;
var intRange: start1_range is intRange.value;
var boolean: start2_is_variable is TRUE;
var string: start2_name is "";
var integer: start2_value is 0;
var intRange: start2_range is intRange.value;
var string: length_name is "";
var integer: length_value is 0;
var boolean: length_is_variable is TRUE;
var intRange: length_range is intRange.value;
var boolean: raisesIndexError is FALSE;
begin
if isPureExpression(stri1) and isPureExpression(start1) and
isPureExpression(length1) and isPureExpression(stri2) and
isPureExpression(start2) and isPureExpression(length2) and
equalExpressions(length1, length2) then
optimizationDone := TRUE;
c_expr.expr &:= "(";
stri1_name := getParameterAsVariable("const_striType", "stri1_", stri1, c_expr);
if getConstant(stri1, STRIOBJECT, evaluatedParam) then
stri1_size := integerLiteral(length(getValue(evaluatedParam, string)));
else
stri1_size := stri1_name & "->size";
end if;
stri2_name := getParameterAsVariable("const_striType", "stri2_", stri2, c_expr);
if getConstant(stri2, STRIOBJECT, evaluatedParam) then
stri2_size := integerLiteral(length(getValue(evaluatedParam, string)));
else
stri2_size := stri2_name & "->size";
end if;
if getConstant(start1, INTOBJECT, evaluatedParam) then
start1_is_variable := FALSE;
start1_value := getValue(evaluatedParam, integer);
if start1_value < 1 then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
raisesIndexError := TRUE;
else
start1_name := integerLiteral(start1_value);
end if;
else
start1_name := getTempVariable("intType", "start1_", start1, c_expr);
end if;
if not raisesIndexError then
if getConstant(start2, INTOBJECT, evaluatedParam) then
start2_is_variable := FALSE;
start2_value := getValue(evaluatedParam, integer);
if start2_value < 1 then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
raisesIndexError := TRUE;
else
start2_name := integerLiteral(start2_value);
end if;
else
start2_name := getTempVariable("intType", "start2_", start2, c_expr);
end if;
end if;
if not raisesIndexError then
if getConstant(length1, INTOBJECT, evaluatedParam) then
length_is_variable := FALSE;
length_value := getValue(evaluatedParam, integer);
if length_value < 0 then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
raisesIndexError := TRUE;
else
length_name := integerLiteral(length_value);
end if;
else
length_name := getParameterAsVariable("intType", "length_", length1, c_expr);
end if;
end if;
if not raisesIndexError then
if string_index_check then
start1_range := getIntRange(start1);
start2_range := getIntRange(start2);
length_range := getIntRange(length1);
incr(countIndexChecks);
c_expr.expr &:= "idxChk(";
if start1_is_variable then
if start1_range.minValue < 1 then
c_expr.expr &:= start1_name;
c_expr.expr &:= "<1||";
end if;
end if;
if start2_is_variable then
if start2_range.minValue < 1 then
c_expr.expr &:= start2_name;
c_expr.expr &:= "<1||";
end if;
end if;
if length_is_variable then
if length_range.minValue <= 0 then
c_expr.expr &:= "(unlikely(";
c_expr.expr &:= length_name;
c_expr.expr &:= "==0)?";
c_expr.expr &:= "(uintType)";
c_expr.expr &:= start1_name;
c_expr.expr &:= ">";
c_expr.expr &:= stri1_size;
c_expr.expr &:= "||";
c_expr.expr &:= "(uintType)";
c_expr.expr &:= start2_name;
c_expr.expr &:= ">";
c_expr.expr &:= stri2_size;
c_expr.expr &:= ":(";
end if;
if length_range.minValue < 0 then
c_expr.expr &:= length_name;
c_expr.expr &:= "<0||";
end if;
end if;
if start1_is_variable then
c_expr.expr &:= "(uintType)";
c_expr.expr &:= start1_name;
if length_is_variable then
c_expr.expr &:= "+(uintType)";
c_expr.expr &:= length_name;
c_expr.expr &:= "-1>";
c_expr.expr &:= stri1_size;
else
if length_value > 1 then
c_expr.expr &:= "+";
c_expr.expr &:= memSizeLiteral(pred(length_value));
end if;
c_expr.expr &:= ">";
c_expr.expr &:= stri1_size;
end if;
else
if length_is_variable then
c_expr.expr &:= "(uintType)";
c_expr.expr &:= length_name;
if start1_value > 1 then
c_expr.expr &:= "+";
c_expr.expr &:= memSizeLiteral(pred(start1_value));
end if;
c_expr.expr &:= ">";
c_expr.expr &:= stri1_size;
else
if length_value > 0 then
c_expr.expr &:= memSizeLiteral(pred(bigInteger(start1_value) +
bigInteger(length_value)));
else
c_expr.expr &:= "(uintType)";
c_expr.expr &:= start1_name;
end if;
c_expr.expr &:= ">";
c_expr.expr &:= stri1_size;
end if;
end if;
c_expr.expr &:= "||";
if start2_is_variable then
c_expr.expr &:= "(uintType)";
c_expr.expr &:= start2_name;
if length_is_variable then
c_expr.expr &:= "+(uintType)";
c_expr.expr &:= length_name;
c_expr.expr &:= "-1>";
c_expr.expr &:= stri2_size;
else
if length_value > 1 then
c_expr.expr &:= "+";
c_expr.expr &:= memSizeLiteral(pred(length_value));
end if;
c_expr.expr &:= ">";
c_expr.expr &:= stri2_size;
end if;
else
if length_is_variable then
c_expr.expr &:= "(uintType)";
c_expr.expr &:= length_name;
if start2_value > 1 then
c_expr.expr &:= "+";
c_expr.expr &:= memSizeLiteral(pred(start2_value));
end if;
c_expr.expr &:= ">";
c_expr.expr &:= stri2_size;
else
if length_value > 0 then
c_expr.expr &:= memSizeLiteral(pred(bigInteger(start2_value) +
bigInteger(length_value)));
else
c_expr.expr &:= "(uintType)";
c_expr.expr &:= start2_name;
end if;
c_expr.expr &:= ">";
c_expr.expr &:= stri2_size;
end if;
end if;
if length_is_variable and length_range.minValue <= 0 then
c_expr.expr &:= "))";
end if;
c_expr.expr &:= ")?";
c_expr.expr &:= intRaiseError("INDEX_ERROR");
c_expr.expr &:= ":";
else
incr(countSuppressedIndexChecks);
end if;
c_expr.expr &:= "memcmp(&";
c_expr.expr &:= stri1_name;
c_expr.expr &:= "->mem[";
if start1_is_variable then
c_expr.expr &:= start1_name;
c_expr.expr &:= "-1"
else
c_expr.expr &:= memSizeLiteral(pred(start1_value));
end if;
c_expr.expr &:= "],&";
c_expr.expr &:= stri2_name;
c_expr.expr &:= "->mem[";
if start2_is_variable then
c_expr.expr &:= start2_name;
c_expr.expr &:= "-1";
else
c_expr.expr &:= memSizeLiteral(pred(start2_value));
end if;
c_expr.expr &:= "],";
c_expr.expr &:= length_name;
c_expr.expr &:= "*sizeof(strElemType))==0)";
end if;
end if;
end func;
const proc: process_const_str_eq (in reference: param1, in string: stri_b,
inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var string: stri_a_name is "";
begin
incr(countOptimizations);
if getConstant(param1, STRIOBJECT, evaluatedParam) then
c_expr.expr &:= "/* ";
c_expr.expr &:= replace(literal(getValue(evaluatedParam, string)), "*/", "*\\/");
c_expr.expr &:= " == ";
c_expr.expr &:= replace(literal(stri_b), "*/", "*\\/");
c_expr.expr &:= " */ ";
if getValue(evaluatedParam, string) = stri_b then
c_expr.expr &:= "1";
else
c_expr.expr &:= "0";
end if;
elsif stri_b = "" then
c_expr.expr &:= "((";
getAnyParamToExpr(param1, c_expr);
c_expr.expr &:= ")->size==0 /* \"\" */)";
else
c_expr.expr &:= "(";
stri_a_name := getParameterAsVariable("const_striType", "tmp_", param1, c_expr);
if length(stri_b) = 1 then
c_expr.expr &:= stri_a_name;
c_expr.expr &:= "->size==1&&";
c_expr.expr &:= stri_a_name;
c_expr.expr &:= "->mem[0]==(strElemType)(";
c_expr.expr &:= c_literal(stri_b[1]);
c_expr.expr &:= ") /* ";
c_expr.expr &:= literal(stri_b);
c_expr.expr &:= " */)";
else
c_expr.expr &:= stri_a_name;
c_expr.expr &:= "->size==";
c_expr.expr &:= str(length(stri_b));
c_expr.expr &:= "&&memcmp(";
c_expr.expr &:= stri_a_name;
c_expr.expr &:= "->mem,(";
c_expr.expr &:= stringLiteral(stri_b);
c_expr.expr &:= ")->mem,";
c_expr.expr &:= str(length(stri_b));
c_expr.expr &:= "*sizeof(strElemType))==0)";
end if;
end if;
end func;
const proc: process (STR_EQ, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var boolean: optimizationDone is FALSE;
var string: stri_a_name is "";
var string: stri_b_name is "";
begin
if getConstant(params[3], STRIOBJECT, evaluatedParam) then
process_const_str_eq(params[1], getValue(evaluatedParam, string), c_expr);
optimizationDone := TRUE;
elsif getConstant(params[1], STRIOBJECT, evaluatedParam) then
process_const_str_eq(params[3], getValue(evaluatedParam, string), c_expr);
optimizationDone := TRUE;
elsif optimizeStringFunctions and
isActionExpression(params[1], "STR_SUBSTR_FIXLEN") and
isActionExpression(params[3], "STR_SUBSTR_FIXLEN") then
optimizationDone := optimize_str_eq_of_substr_fixlen(
getActionParameter(params[1], 1), getActionParameter(params[1], 3),
getActionParameter(params[1], 5), getActionParameter(params[3], 1),
getActionParameter(params[3], 3), getActionParameter(params[3], 5), c_expr);
end if;
if not optimizationDone then
c_expr.expr &:= "(";
stri_a_name := getParameterAsVariable("const_striType", "tmp_a_", params[1], c_expr);
stri_b_name := getParameterAsVariable("const_striType", "tmp_b_", params[3], c_expr);
c_expr.expr &:= stri_a_name;
c_expr.expr &:= "->size==";
c_expr.expr &:= stri_b_name;
c_expr.expr &:= "->size&&memcmp(";
c_expr.expr &:= stri_a_name;
c_expr.expr &:= "->mem,";
c_expr.expr &:= stri_b_name;
c_expr.expr &:= "->mem,";
c_expr.expr &:= stri_a_name;
c_expr.expr &:= "->size*sizeof(strElemType))==0)";
end if;
end func;
const proc: process (STR_FOR, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var string: size_name is "";
var string: index_name is "";
var string: stri_name is "";
var expr_type: statement is expr_type.value;
begin
size_name := defineTempVariable("memSizeType", "size_", statement);
index_name := defineTempVariable("memSizeType", "index_", statement);
statement.expr &:= "for (";
stri_name := getParameterAsVariable("const_striType", "stri_", params[4], statement);
statement.expr &:= size_name;
statement.expr &:= "=";
statement.expr &:= stri_name;
statement.expr &:= "->size,";
statement.expr &:= index_name;
statement.expr &:= "=0; ";
statement.expr &:= index_name;
statement.expr &:= "<";
statement.expr &:= size_name;
statement.expr &:= "; (";
statement.expr &:= index_name;
statement.expr &:= ")++) {\n";
process_expr(params[2], statement);
statement.expr &:= "=";
statement.expr &:= stri_name;
statement.expr &:= "->mem[";
statement.expr &:= index_name;
statement.expr &:= "];\n";
process_call_by_name_expr(params[6], statement);
statement.expr &:= "}\n";
doLocalDeclsOfStatement(statement, c_expr);
end func;
const proc: process (STR_FOR_KEY, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var string: size_name is "";
var string: index_name is "";
var string: stri_name is "";
var expr_type: statement is expr_type.value;
begin
size_name := defineTempVariable("memSizeType", "size_", statement);
index_name := defineTempVariable("memSizeType", "index_", statement);
statement.expr &:= "for (";
stri_name := getParameterAsVariable("const_striType", "stri_", params[5], statement);
statement.expr &:= size_name;
statement.expr &:= "=";
statement.expr &:= stri_name;
statement.expr &:= "->size,";
statement.expr &:= index_name;
statement.expr &:= "=0; ";
statement.expr &:= index_name;
statement.expr &:= "<";
statement.expr &:= size_name;
statement.expr &:= "; (";
statement.expr &:= index_name;
statement.expr &:= ")++) {\n";
process_expr(params[3], statement);
statement.expr &:= "= (intType)(";
statement.expr &:= index_name;
statement.expr &:= " + 1);\n";
process_call_by_name_expr(params[7], statement);
statement.expr &:= "}\n";
doLocalDeclsOfStatement(statement, c_expr);
end func;
const proc: process (STR_FOR_VAR_KEY, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var string: size_name is "";
var string: index_name is "";
var string: stri_name is "";
var expr_type: statement is expr_type.value;
begin
size_name := defineTempVariable("memSizeType", "size_", statement);
index_name := defineTempVariable("memSizeType", "index_", statement);
statement.expr &:= "for (";
stri_name := getParameterAsVariable("const_striType", "stri_", params[6], statement);
statement.expr &:= size_name;
statement.expr &:= "=";
statement.expr &:= stri_name;
statement.expr &:= "->size,";
statement.expr &:= index_name;
statement.expr &:= "=0; ";
statement.expr &:= index_name;
statement.expr &:= "<";
statement.expr &:= size_name;
statement.expr &:= "; (";
statement.expr &:= index_name;
statement.expr &:= ")++) {\n";
process_expr(params[2], statement);
statement.expr &:= "=";
statement.expr &:= stri_name;
statement.expr &:= "->mem[";
statement.expr &:= index_name;
statement.expr &:= "];\n";
process_expr(params[4], statement);
statement.expr &:= "= (intType)(";
statement.expr &:= index_name;
statement.expr &:= " + 1);\n";
process_call_by_name_expr(params[8], statement);
statement.expr &:= "}\n";
doLocalDeclsOfStatement(statement, c_expr);
end func;
const proc: process (STR_FROM_UTF8, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
prepare_stri_result(c_expr);
c_expr.result_expr := "strFromUtf8(";
getAnyParamToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ")";
end func;
const proc: process_const_str_le (in string: stri1, in reference: stri2,
inout expr_type: c_expr) is forward;
const proc: process_const_str_ge (in string: stri1, in reference: stri2,
inout expr_type: c_expr) is func
local
var string: stri2_name is "";
begin
if stri1 = "" then
c_expr.expr &:= "(";
getAnyParamToExpr(stri2, c_expr);
c_expr.expr &:= ")->size==0";
elsif length(stri1) = 1 then
c_expr.expr &:= "(";
stri2_name := getParameterAsVariable("const_striType", "stri2_", stri2, c_expr);
c_expr.expr &:= stri2_name;
c_expr.expr &:= "->size==0||";
c_expr.expr &:= stri2_name;
c_expr.expr &:= "->size==1&&";
c_expr.expr &:= stri2_name;
c_expr.expr &:= "->mem[0]<=(strElemType)(";
c_expr.expr &:= c_literal(stri1[1]);
c_expr.expr &:= ") /* ";
c_expr.expr &:= literal(stri1);
c_expr.expr &:= " */||";
c_expr.expr &:= stri2_name;
c_expr.expr &:= "->mem[0]<(strElemType)(";
c_expr.expr &:= c_literal(stri1[1]);
c_expr.expr &:= ") /* ";
c_expr.expr &:= literal(stri1);
c_expr.expr &:= " */)";
else
c_expr.expr &:= "strGe(";
c_expr.expr &:= stringLiteral(stri1);
c_expr.expr &:= ", ";
getAnyParamToExpr(stri2, c_expr);
c_expr.expr &:= ")";
end if;
end func;
const proc: process (STR_GE, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
begin
if getConstant(params[1], STRIOBJECT, evaluatedParam) then
process_const_str_ge(getValue(evaluatedParam, string), params[3], c_expr);
elsif getConstant(params[3], STRIOBJECT, evaluatedParam) then
process_const_str_le(getValue(evaluatedParam, string), params[1], c_expr);
else
c_expr.expr &:= "strGe(";
getAnyParamToExpr(params[1], c_expr);
c_expr.expr &:= ", ";
getAnyParamToExpr(params[3], c_expr);
c_expr.expr &:= ")";
end if;
end func;
const proc: process_const_str_lt (in string: stri1, in reference: stri2,
inout expr_type: c_expr) is forward;
const proc: process_const_str_gt (in string: stri1, in reference: stri2,
inout expr_type: c_expr) is func
local
var string: stri2_name is "";
begin
if stri1 = "" then
c_expr.expr &:= "0";
elsif length(stri1) = 1 then
c_expr.expr &:= "(";
stri2_name := getParameterAsVariable("const_striType", "stri2_", stri2, c_expr);
c_expr.expr &:= stri2_name;
c_expr.expr &:= "->size==0||";
c_expr.expr &:= stri2_name;
c_expr.expr &:= "->mem[0]<(strElemType)(";
c_expr.expr &:= c_literal(stri1[1]);
c_expr.expr &:= ") /* ";
c_expr.expr &:= literal(stri1);
c_expr.expr &:= " */)";
else
c_expr.expr &:= "strGt(";
c_expr.expr &:= stringLiteral(stri1);
c_expr.expr &:= ", ";
getAnyParamToExpr(stri2, c_expr);
c_expr.expr &:= ")";
end if;
end func;
const proc: process (STR_GT, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
begin
if getConstant(params[1], STRIOBJECT, evaluatedParam) then
process_const_str_gt(getValue(evaluatedParam, string), params[3], c_expr);
elsif getConstant(params[3], STRIOBJECT, evaluatedParam) then
process_const_str_lt(getValue(evaluatedParam, string), params[1], c_expr);
else
c_expr.expr &:= "strGt(";
getAnyParamToExpr(params[1], c_expr);
c_expr.expr &:= ", ";
getAnyParamToExpr(params[3], c_expr);
c_expr.expr &:= ")";
end if;
end func;
const proc: process (STR_HASHCODE, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var string: stri_name is "";
begin
if getConstant(params[1], STRIOBJECT, evaluatedParam) then
incr(countOptimizations);
c_expr.expr &:= integerLiteral(hashCode(getValue(evaluatedParam, string)));
elsif inlineFunctions then
incr(countInlinedFunctions);
c_expr.expr &:= "(";
stri_name := getParameterAsVariable("const_striType", "tmp_", params[1], c_expr);
c_expr.expr &:= stri_name;
c_expr.expr &:= "->size==0 ? 0 : (";
c_expr.expr &:= stri_name;
c_expr.expr &:= "->mem[0]<<5 ^ ";
c_expr.expr &:= stri_name;
c_expr.expr &:= "->mem[";
c_expr.expr &:= stri_name;
c_expr.expr &:= "->size>>1]<<3 ^ ";
c_expr.expr &:= stri_name;
c_expr.expr &:= "->mem[";
c_expr.expr &:= stri_name;
c_expr.expr &:= "->size-1]<<1 ^ ";
c_expr.expr &:= stri_name;
c_expr.expr &:= "->size))";
else
c_expr.expr &:= "strHashCode(";
getAnyParamToExpr(params[1], c_expr);
c_expr.expr &:= ")";
end if;
end func;
const proc: process_const_str_head (in string: stri, in reference: length,
inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var integer: length_value is 0;
var string: length_name is "";
var intRange: length_range is intRange.value;
var string: slice_name is "";
begin
if getConstant(length, INTOBJECT, evaluatedParam) then
incr(countOptimizations);
length_value := getValue(evaluatedParam, integer);
if length_value < 0 then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
else
c_expr.expr &:= stringLiteral(stri[.. length_value]);
end if;
elsif stri = "" then
incr(countOptimizations);
c_expr.expr &:= "/* \"\"[ .. n] */ (";
if string_index_check then
length_range := getIntRange(length);
if length_range.minValue < 0 then
incr(countIndexChecks);
c_expr.expr &:= "idxChk(";
process_expr(length, c_expr);
c_expr.expr &:= "<0)?";
c_expr.expr &:= strRaiseError("INDEX_ERROR");
c_expr.expr &:= ":";
else
countIndexOptimizations(c_expr);
end if;
else
incr(countSuppressedIndexChecks);
end if;
c_expr.expr &:= stringLiteral("");
c_expr.expr &:= ")";
elsif length(stri) = 1 then
incr(countOptimizations);
c_expr.expr &:= "(";
length_name := getParameterAsVariable("intType", "length_", length, c_expr);
if string_index_check then
length_range := getIntRange(length);
if length_range.minValue < 0 then
incr(countIndexChecks);
c_expr.expr &:= "idxChk(";
c_expr.expr &:= length_name;
c_expr.expr &:= "<0)?";
c_expr.expr &:= strRaiseError("INDEX_ERROR");
c_expr.expr &:= ":";
else
countIndexOptimizations(c_expr);
end if;
else
incr(countSuppressedIndexChecks);
end if;
c_expr.expr &:= length_name;
c_expr.expr &:= ">=1?";
c_expr.expr &:= stringLiteral(stri);
c_expr.expr &:= ":";
c_expr.expr &:= stringLiteral("");
c_expr.expr &:= ")";
elsif ccConf.ALLOW_STRITYPE_SLICES and c_expr.demand < REQUIRE_RESULT then
c_expr.expr &:= "(";
incr(c_expr.temp_num);
slice_name := "slice_" & str(c_expr.temp_num);
c_expr.temp_decls &:= "struct striStruct ";
c_expr.temp_decls &:= slice_name;
c_expr.temp_decls &:= ";\n";
if inlineFunctions then
incr(countInlinedFunctions);
length_name := getParameterAsVariable("intType", "length_", length, c_expr);
if string_index_check then
length_range := getIntRange(length);
if length_range.minValue < 0 then
c_expr.expr &:= "idxChk(";
c_expr.expr &:= length_name;
c_expr.expr &:= "<0)?";
c_expr.expr &:= strRaiseError("INDEX_ERROR");
c_expr.expr &:= ":";
else
countIndexOptimizations(c_expr);
end if;
else
incr(countSuppressedIndexChecks);
end if;
c_expr.expr &:= "(";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".mem = (";
c_expr.expr &:= stringLiteral(stri);
c_expr.expr &:= ")->mem, ";
c_expr.expr &:= memSizeLiteral(length(stri));
c_expr.expr &:= "<=(uintType)";
c_expr.expr &:= length_name;
c_expr.expr &:= " ? ";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".size = ";
c_expr.expr &:= memSizeLiteral(length(stri));
c_expr.expr &:= " : (";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".size = (memSizeType)";
c_expr.expr &:= length_name;
c_expr.expr &:= "), &";
c_expr.expr &:= slice_name;
c_expr.expr &:= ")";
else
c_expr.expr &:= "strHeadSlice(";
c_expr.expr &:= stringLiteral(stri);
c_expr.expr &:= ", ";
process_expr(length, c_expr);
c_expr.expr &:= ", &";
c_expr.expr &:= slice_name;
c_expr.expr &:= "), &";
c_expr.expr &:= slice_name;
end if;
c_expr.expr &:= ")";
else
prepare_stri_result(c_expr);
c_expr.result_expr := "strHead(";
c_expr.result_expr &:= stringLiteral(stri);
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(length, c_expr);
c_expr.result_expr &:= ")";
end if;
end func;
const proc: process_const_str_head1 (in reference: param1,
inout expr_type: c_expr) is func
local
var string: temp_name is "";
var string: stri1_name is "";
var expr_type: c_param1 is expr_type.value;
begin
if c_expr.demand < REQUIRE_RESULT then
incr(countOptimizations);
c_expr.expr &:= "(";
temp_name := getParameterAsVariable("const_striType", "tmp_", param1, c_expr);
incr(c_expr.temp_num);
stri1_name := "stri1_" & str(c_expr.temp_num);
c_expr.temp_decls &:= "struct striStruct ";
c_expr.temp_decls &:= stri1_name;
c_expr.temp_decls &:= ";\n";
c_expr.expr &:= temp_name;
c_expr.expr &:= "->size>=1?chrStrMacro(";
c_expr.expr &:= temp_name;
c_expr.expr &:= "->mem[0],";
c_expr.expr &:= stri1_name;
c_expr.expr &:= "):";
c_expr.expr &:= stringLiteral("");
c_expr.expr &:= ")";
else
prepareAnyParamTemporarys(param1, c_param1, c_expr);
prepare_stri_result(c_expr);
if c_param1.result_expr <> "" then
c_expr.result_expr := "strHeadTemp(";
c_expr.result_expr &:= c_param1.result_expr;
else
c_expr.result_expr := "strHead(";
c_expr.result_expr &:= c_param1.expr;
end if;
c_expr.result_expr &:= ", 1)";
end if;
end func;
const proc: process_inline_str_head (in reference: stri, in reference: length,
in string: slice_name, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var string: stri_name is "";
var string: stri_value is "";
var string: stri_size is "";
var string: length_name is "";
var integer: length_value is 0;
var boolean: length_is_variable is TRUE;
var intRange: length_range is intRange.value;
var boolean: raisesIndexError is FALSE;
begin
stri_name := getParameterAsVariable("const_striType", "stri_", stri, c_expr);
stri_size := stri_name & "->size";
if getConstant(length, INTOBJECT, evaluatedParam) then
length_is_variable := FALSE;
length_value := getValue(evaluatedParam, integer);
if length_value < 0 then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
raisesIndexError := TRUE;
else
length_name := integerLiteral(length_value);
end if;
else
length_name := getParameterAsVariable("intType", "length_", length, c_expr);
end if;
if not raisesIndexError then
if length_is_variable then
if string_index_check then
length_range := getIntRange(length);
if length_range.minValue < 0 then
incr(countIndexChecks);
c_expr.expr &:= "idxChk(";
c_expr.expr &:= length_name;
c_expr.expr &:= "<0";
c_expr.expr &:= ")?";
c_expr.expr &:= intRaiseError("INDEX_ERROR");
c_expr.expr &:= ":0, ";
else
countIndexOptimizations(c_expr);
end if;
else
incr(countSuppressedIndexChecks);
end if;
end if;
if not length_is_variable and length_value = 0 then
c_expr.expr &:= slice_name;
c_expr.expr &:= ".mem = NULL, ";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".size = 0";
else
c_expr.expr &:= slice_name;
c_expr.expr &:= ".mem = ";
c_expr.expr &:= stri_name;
c_expr.expr &:= "->mem,";
c_expr.expr &:= stri_size;
c_expr.expr &:= " <= (uintType)";
c_expr.expr &:= length_name;
c_expr.expr &:= " ? ";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".size = ";
c_expr.expr &:= stri_size;
c_expr.expr &:= " : (";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".size = (memSizeType)";
c_expr.expr &:= length_name;
c_expr.expr &:= ")";
end if;
end if;
end func;
const proc: process_str_head (in reference: stri, in reference: length,
inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var expr_type: c_stri is expr_type.value;
var string: slice_name is "";
begin
if getConstant(stri, STRIOBJECT, evaluatedParam) then
process_const_str_head(getValue(evaluatedParam, string), length, c_expr);
elsif getConstant(length, INTOBJECT, evaluatedParam) and
getValue(evaluatedParam, integer) = 1 then
process_const_str_head1(stri, c_expr);
else
prepareAnyParamTemporarys(stri, c_stri, c_expr);
if c_stri.result_expr <> "" then
prepare_stri_result(c_expr);
c_expr.result_expr := "strHeadTemp(";
c_expr.result_expr &:= c_stri.result_expr;
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(length, c_expr);
c_expr.result_expr &:= ")";
elsif ccConf.ALLOW_STRITYPE_SLICES and c_expr.demand < REQUIRE_RESULT then
c_expr.expr &:= "(";
incr(c_expr.temp_num);
slice_name := "slice_" & str(c_expr.temp_num);
c_expr.temp_decls &:= "struct striStruct ";
c_expr.temp_decls &:= slice_name;
c_expr.temp_decls &:= ";\n";
if inlineFunctions then
incr(countInlinedFunctions);
process_inline_str_head(stri, length, slice_name, c_expr);
else
c_expr.expr &:= "strHeadSlice(";
c_expr.expr &:= c_stri.expr;
c_expr.expr &:= ", ";
process_expr(length, c_expr);
c_expr.expr &:= ", &";
c_expr.expr &:= slice_name;
c_expr.expr &:= ")";
end if;
c_expr.expr &:= ", &";
c_expr.expr &:= slice_name;
c_expr.expr &:= ")";
else
prepare_stri_result(c_expr);
c_expr.result_expr := "strHead(";
c_expr.result_expr &:= c_stri.expr;
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(length, c_expr);
c_expr.result_expr &:= ")";
end if;
end if;
end func;
const proc: process (STR_HEAD, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
process_str_head(params[1], params[4], c_expr);
end func;
const proc: process_const_str_idx (in string: stri,
in reference: index, inout expr_type: c_expr) is func
local
var intRange: indexRange is intRange.value;
var string: index_name is "";
begin
incr(countOptimizations);
if string_index_check then
indexRange := getIntRange(index);
if indexRange.maxValue < 1 or
indexRange.minValue > length(stri) then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= intRaiseError("INDEX_ERROR");
else
c_expr.expr &:= "(";
c_expr.expr &:= stringLiteral(stri);
c_expr.expr &:= ")->mem[";
if indexRange.minValue < 1 or
indexRange.maxValue > length(stri) then
incr(countIndexChecks);
incr(c_expr.temp_num);
index_name := "idx_" & str(c_expr.temp_num);
if ccConf.TWOS_COMPLEMENT_INTTYPE then
c_expr.temp_decls &:= "uintType ";
else
c_expr.temp_decls &:= "intType ";
end if;
c_expr.temp_decls &:= index_name;
c_expr.temp_decls &:= ";\n";
c_expr.expr &:= "(";
c_expr.expr &:= index_name;
c_expr.expr &:= "=";
if ccConf.TWOS_COMPLEMENT_INTTYPE then
c_expr.expr &:= "(uintType)(";
process_expr(index, c_expr);
c_expr.expr &:= ")-1, idxChk(";
c_expr.expr &:= index_name;
c_expr.expr &:= ">=";
else
process_expr(index, c_expr);
c_expr.expr &:= ", idxChk(";
c_expr.expr &:= index_name;
c_expr.expr &:= "<=0 || ";
c_expr.expr &:= index_name;
c_expr.expr &:= ">";
end if;
c_expr.expr &:= str(length(stri));
c_expr.expr &:= ") ? ";
c_expr.expr &:= intRaiseError("INDEX_ERROR");
c_expr.expr &:= " : ";
c_expr.expr &:= index_name;
if ccConf.TWOS_COMPLEMENT_INTTYPE then
c_expr.expr &:= ")";
else
c_expr.expr &:= "-1)";
end if;
else
countIndexOptimizations(c_expr);
c_expr.expr &:= "(";
process_expr(index, c_expr);
c_expr.expr &:= ")-1";
end if;
c_expr.expr &:= "]";
end if;
else
incr(countSuppressedIndexChecks);
c_expr.expr &:= "(";
c_expr.expr &:= stringLiteral(stri);
c_expr.expr &:= ")->mem[(";
process_expr(index, c_expr);
c_expr.expr &:= ")-1]";
end if;
end func;
const proc: process_const_str_idx (in reference: stri,
in integer: index, inout expr_type: c_expr) is func
local
var intRange: lengthRange is intRange.value;
var string: stri_name is "";
begin
incr(countOptimizations);
if index < 1 then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= intRaiseError("INDEX_ERROR");
elsif string_index_check then
lengthRange := getStrLenRange(stri);
if index > lengthRange.maxValue then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= intRaiseError("INDEX_ERROR");
elsif index > lengthRange.minValue then
incr(countIndexChecks);
c_expr.expr &:= "(";
stri_name := getParameterAsVariable("const_striType", "tmp_", stri, c_expr);
c_expr.expr &:= stri_name;
c_expr.expr &:= "->mem[(idxChk(";
c_expr.expr &:= stri_name;
c_expr.expr &:= "->size<";
c_expr.expr &:= integerLiteral(index);
c_expr.expr &:= ") ? ";
c_expr.expr &:= intRaiseError("INDEX_ERROR");
c_expr.expr &:= " : ";
c_expr.expr &:= integerLiteral(pred(index));
c_expr.expr &:= ")])";
else
countIndexOptimizations(c_expr);
c_expr.expr &:= "(";
getAnyParamToExpr(stri, c_expr);
c_expr.expr &:= ")->mem[";
c_expr.expr &:= integerLiteral(pred(index));
c_expr.expr &:= "]";
end if;
else
incr(countSuppressedIndexChecks);
c_expr.expr &:= "(";
getAnyParamToExpr(stri, c_expr);
c_expr.expr &:= ")->mem[";
c_expr.expr &:= integerLiteral(pred(index));
c_expr.expr &:= "]";
end if;
end func;
const proc: process_str_idx_last_char (in reference: stri,
inout expr_type: c_expr) is func
local
var string: stri_name is "";
begin
incr(countOptimizations);
c_expr.expr &:= "/* stri[length[stri)] */ (";
stri_name := getParameterAsVariable("const_striType", "stri_", stri, c_expr);
if string_index_check then
c_expr.expr &:= "idxChk(";
c_expr.expr &:= stri_name;
c_expr.expr &:= "->size==0) ? ";
c_expr.expr &:= intRaiseError("INDEX_ERROR");
c_expr.expr &:= " : ";
end if;
c_expr.expr &:= stri_name;
c_expr.expr &:= "->mem[";
c_expr.expr &:= stri_name;
c_expr.expr &:= "->size-1])";
end func;
const proc: process_str_idx (in reference: stri,
in reference: index, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var intRange: lengthRange is intRange.value;
var intRange: indexRange is intRange.value;
var string: stri_name is "";
var string: index_name is "";
begin
if getConstant(stri, STRIOBJECT, evaluatedParam) then
process_const_str_idx(getValue(evaluatedParam, string), index, c_expr);
elsif getConstant(index, INTOBJECT, evaluatedParam) then
process_const_str_idx(stri, getValue(evaluatedParam, integer), c_expr);
elsif optimizeStringFunctions and
isActionExpression(index, "STR_LNG") and
getActionParameter(index, 1) = stri then
process_str_idx_last_char(stri, c_expr);
elsif string_index_check then
lengthRange := getStrLenRange(stri);
indexRange := getIntRange(index);
if indexRange.maxValue < 1 or
indexRange.minValue > lengthRange.maxValue then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= intRaiseError("INDEX_ERROR");
elsif indexRange.minValue < 1 or
indexRange.maxValue > lengthRange.minValue then
incr(countIndexChecks);
incr(c_expr.temp_num);
index_name := "idx_" & str(c_expr.temp_num);
if ccConf.TWOS_COMPLEMENT_INTTYPE then
c_expr.temp_decls &:= "uintType ";
else
c_expr.temp_decls &:= "intType ";
end if;
c_expr.temp_decls &:= index_name;
c_expr.temp_decls &:= ";\n";
c_expr.expr &:= "(";
stri_name := getParameterAsVariable("const_striType", "stri_", stri, c_expr);
c_expr.expr &:= stri_name;
c_expr.expr &:= "->mem[(";
c_expr.expr &:= index_name;
c_expr.expr &:= "=";
if ccConf.TWOS_COMPLEMENT_INTTYPE then
c_expr.expr &:= "(uintType)(";
process_expr(index, c_expr);
c_expr.expr &:= ")-1, idxChk(";
c_expr.expr &:= index_name;
c_expr.expr &:= ">=";
else
process_expr(index, c_expr);
c_expr.expr &:= ", idxChk(";
c_expr.expr &:= index_name;
c_expr.expr &:= "<=0 || ";
c_expr.expr &:= index_name;
c_expr.expr &:= ">";
end if;
c_expr.expr &:= stri_name;
c_expr.expr &:= "->size) ? ";
c_expr.expr &:= intRaiseError("INDEX_ERROR");
c_expr.expr &:= " : ";
c_expr.expr &:= index_name;
if ccConf.TWOS_COMPLEMENT_INTTYPE then
c_expr.expr &:= ")])";
else
c_expr.expr &:= "-1)])";
end if;
else
countIndexOptimizations(c_expr);
c_expr.expr &:= "(";
getAnyParamToExpr(stri, c_expr);
c_expr.expr &:= ")->mem[(";
process_expr(index, c_expr);
c_expr.expr &:= ")-1]";
end if;
else
incr(countSuppressedIndexChecks);
c_expr.expr &:= "(";
getAnyParamToExpr(stri, c_expr);
c_expr.expr &:= ")->mem[(";
process_expr(index, c_expr);
c_expr.expr &:= ")-1]";
end if;
end func;
const proc: process (STR_IDX, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
process_str_idx(params[1], params[3], c_expr);
end func;
const proc: process (STR_IPOS, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
begin
if getConstant(params[2], STRIOBJECT, evaluatedParam) and
length(getValue(evaluatedParam, string)) = 1 then
incr(countOptimizations);
c_expr.expr &:= "strChIPos(";
getAnyParamToExpr(params[1], c_expr);
c_expr.expr &:= ", ";
c_expr.expr &:= charLiteral(getValue(evaluatedParam, string)[1]);
c_expr.expr &:= ", ";
process_expr(params[3], c_expr);
c_expr.expr &:= ")";
else
c_expr.expr &:= "strIPos(";
getAnyParamToExpr(params[1], c_expr);
c_expr.expr &:= ", ";
getAnyParamToExpr(params[2], c_expr);
c_expr.expr &:= ", ";
process_expr(params[3], c_expr);
c_expr.expr &:= ")";
end if;
end func;
const proc: process_const_str_le (in string: stri1, in reference: stri2,
inout expr_type: c_expr) is func
local
var string: stri2_name is "";
begin
if stri1 = "" then
c_expr.expr &:= "1";
elsif length(stri1) = 1 then
c_expr.expr &:= "(";
stri2_name := getParameterAsVariable("const_striType", "stri2_", stri2, c_expr);
c_expr.expr &:= stri2_name;
c_expr.expr &:= "->size>=1&&";
c_expr.expr &:= stri2_name;
c_expr.expr &:= "->mem[0]>=(strElemType)(";
c_expr.expr &:= c_literal(stri1[1]);
c_expr.expr &:= ") /* ";
c_expr.expr &:= literal(stri1);
c_expr.expr &:= " */)";
else
c_expr.expr &:= "strLe(";
c_expr.expr &:= stringLiteral(stri1);
c_expr.expr &:= ", ";
getAnyParamToExpr(stri2, c_expr);
c_expr.expr &:= ")";
end if;
end func;
const proc: process (STR_LE, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
begin
if getConstant(params[1], STRIOBJECT, evaluatedParam) then
process_const_str_le(getValue(evaluatedParam, string), params[3], c_expr);
elsif getConstant(params[3], STRIOBJECT, evaluatedParam) then
process_const_str_ge(getValue(evaluatedParam, string), params[1], c_expr);
else
c_expr.expr &:= "strLe(";
getAnyParamToExpr(params[1], c_expr);
c_expr.expr &:= ", ";
getAnyParamToExpr(params[3], c_expr);
c_expr.expr &:= ")";
end if;
end func;
const proc: process (STR_LIT, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
prepare_stri_result(c_expr);
c_expr.result_expr := "strLit(";
getAnyParamToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ")";
end func;
const func integer: sumLengthOfConstants (inout array reference: concatNParamList) is func
result
var integer: lengthOfConstants is 0;
local
var integer: index is 1;
var reference: evaluatedParam is NIL;
var string: paramValue is "";
begin
while index <= length(concatNParamList) do
if getConstant(concatNParamList[index], STRIOBJECT, evaluatedParam) then
lengthOfConstants +:= length(getValue(evaluatedParam, string));
ignore(remove(concatNParamList, index));
else
incr(index);
end if;
end while;
end func;
const proc: optimize_str_lng (in reference: lengthParam,
inout expr_type: c_expr) is forward;
const proc: optimize_str_lng (STR_CAT, in ref_list: params,
inout expr_type: c_expr) is func
local
var array reference: concatNParamList is 0 times NIL;
var integer: lengthOfConstants is 0;
var reference: striObj is NIL;
begin
concatNParamList := getConcatNParamList(params);
lengthOfConstants := sumLengthOfConstants(concatNParamList);
for striObj range concatNParamList do
optimize_str_lng(striObj, c_expr);
c_expr.expr &:= " + ";
end for;
c_expr.expr &:= integerLiteral(lengthOfConstants);
end func;
const proc: optimize_str_lng (in reference: lengthParam,
inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var string: stri is "";
var ref_list: params is ref_list.value;
var intRange: lengthRange is intRange.value;
begin
if getConstant(lengthParam, STRIOBJECT, evaluatedParam) then
incr(countOptimizations);
stri := getValue(evaluatedParam, string);
c_expr.expr &:= integerLiteral(length(stri));
c_expr.expr &:= " /* length(";
c_expr.expr &:= replace(literal(stri), "*/", "*\\/");
c_expr.expr &:= ") */";
elsif isActionExpression(lengthParam, "STR_CAT") then
params := getValue(lengthParam, ref_list)[2 ..];
optimize_str_lng(STR_CAT, params, c_expr);
elsif isActionExpression(lengthParam, "STR_SUBSTR_FIXLEN") then
incr(countOptimizations);
if getConstant(getActionParameter(lengthParam, 5), INTOBJECT, evaluatedParam) then
c_expr.expr &:= integerLiteral(getValue(evaluatedParam, integer));
else
c_expr.expr &:= "(";
process_expr(getActionParameter(lengthParam, 5), c_expr);
c_expr.expr &:= ")";
end if;
c_expr.expr &:= " /* length of fixlLen substring */";
else
lengthRange := getStrLenRange(lengthParam);
if not lengthRange.mayRaiseException and
lengthRange.minValue = lengthRange.maxValue then
c_expr.expr &:= integerLiteral(lengthRange.minValue);
c_expr.expr &:= " /* length of string does not change */";
else
c_expr.expr &:= "(intType)((";
getAnyParamToExpr(lengthParam, c_expr);
c_expr.expr &:= ")->size)";
end if;
end if;
end func;
const proc: process (STR_LNG, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
if optimizeStringFunctions then
optimize_str_lng(params[1], c_expr);
else
c_expr.expr &:= "(intType)((";
getAnyParamToExpr(params[1], c_expr);
c_expr.expr &:= ")->size)";
end if;
end func;
const proc: process (STR_LOW, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var expr_type: c_param1 is expr_type.value;
begin
prepare_stri_result(c_expr);
prepareAnyParamTemporarys(params[1], c_param1, c_expr);
if c_param1.result_expr <> "" then
c_expr.result_expr := "strLowTemp(";
c_expr.result_expr &:= c_param1.result_expr;
else
c_expr.result_expr := "strLow(";
c_expr.result_expr &:= c_param1.expr;
end if;
c_expr.result_expr &:= ")";
end func;
const proc: process (STR_LPAD, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var expr_type: c_param1 is expr_type.value;
begin
prepare_stri_result(c_expr);
prepareAnyParamTemporarys(params[1], c_param1, c_expr);
if c_param1.result_expr <> "" then
c_expr.result_expr := "strLpadTemp(";
c_expr.result_expr &:= c_param1.result_expr;
else
c_expr.result_expr := "strLpad(";
c_expr.result_expr &:= c_param1.expr;
end if;
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(params[3], c_expr);
c_expr.result_expr &:= ")";
end func;
const proc: process (STR_LPAD0, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var expr_type: c_param1 is expr_type.value;
begin
prepare_stri_result(c_expr);
prepareAnyParamTemporarys(params[1], c_param1, c_expr);
if c_param1.result_expr <> "" then
c_expr.result_expr := "strLpad0Temp(";
c_expr.result_expr &:= c_param1.result_expr;
else
c_expr.result_expr := "strLpad0(";
c_expr.result_expr &:= c_param1.expr;
end if;
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(params[3], c_expr);
c_expr.result_expr &:= ")";
end func;
const proc: process_const_str_lt (in string: stri1, in reference: stri2,
inout expr_type: c_expr) is func
local
var string: stri2_name is "";
begin
if stri1 = "" then
c_expr.expr &:= "(";
getAnyParamToExpr(stri2, c_expr);
c_expr.expr &:= ")->size!=0";
elsif length(stri1) = 1 then
c_expr.expr &:= "(";
stri2_name := getParameterAsVariable("const_striType", "stri2_", stri2, c_expr);
c_expr.expr &:= stri2_name;
c_expr.expr &:= "->size>1&&";
c_expr.expr &:= stri2_name;
c_expr.expr &:= "->mem[0]>=(strElemType)(";
c_expr.expr &:= c_literal(stri1[1]);
c_expr.expr &:= ") /* ";
c_expr.expr &:= literal(stri1);
c_expr.expr &:= " */)||";
c_expr.expr &:= stri2_name;
c_expr.expr &:= "->size==1&&";
c_expr.expr &:= stri2_name;
c_expr.expr &:= "->mem[0]>(strElemType)(";
c_expr.expr &:= c_literal(stri1[1]);
c_expr.expr &:= ") /* ";
c_expr.expr &:= literal(stri1);
c_expr.expr &:= " */";
else
c_expr.expr &:= "strLt(";
c_expr.expr &:= stringLiteral(stri1);
c_expr.expr &:= ", ";
getAnyParamToExpr(stri2, c_expr);
c_expr.expr &:= ")";
end if;
end func;
const proc: process (STR_LT, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
begin
if getConstant(params[1], STRIOBJECT, evaluatedParam) then
process_const_str_lt(getValue(evaluatedParam, string), params[3], c_expr);
elsif getConstant(params[3], STRIOBJECT, evaluatedParam) then
process_const_str_gt(getValue(evaluatedParam, string), params[1], c_expr);
else
c_expr.expr &:= "strLt(";
getAnyParamToExpr(params[1], c_expr);
c_expr.expr &:= ", ";
getAnyParamToExpr(params[3], c_expr);
c_expr.expr &:= ")";
end if;
end func;
const proc: process (STR_LTRIM, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
prepare_stri_result(c_expr);
c_expr.result_expr := "strLtrim(";
getAnyParamToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ")";
end func;
const proc: process_const_str_mult (in string: stri, in reference: factor,
inout expr_type: c_expr) is func
local
var char: ch is ' ';
var intRange: factorRange is intRange.value;
begin
if stri = "" then
incr(countOptimizations);
if function_range_check then
factorRange := getIntRange(factor);
if factorRange.minValue >= 0 then
countRangeOptimizations(c_expr);
c_expr.expr &:= stringLiteral("");
else
incr(countRangeChecks);
c_expr.expr &:= "(rngChk((";
process_expr(factor, c_expr);
c_expr.expr &:= ")<0)?";
c_expr.expr &:= strRaiseError("RANGE_ERROR");
c_expr.expr &:= ":";
c_expr.expr &:= stringLiteral("");
c_expr.expr &:= ")";
end if;
else
incr(countNoRangeChecks);
c_expr.expr &:= stringLiteral("");
end if;
else
prepare_stri_result(c_expr);
if length(stri) = 1 then
incr(countOptimizations);
ch := stri[1];
if ch = '\0;' then
c_expr.result_expr := "strZero(";
else
c_expr.result_expr := "strChMult(";
c_expr.result_expr &:= charLiteral(ch);
c_expr.result_expr &:= ", ";
end if;
else
c_expr.result_expr := "strMult(";
c_expr.result_expr &:= stringLiteral(stri);
c_expr.result_expr &:= ", ";
end if;
getStdParamToResultExpr(factor, c_expr);
c_expr.result_expr &:= ")";
end if;
end func;
const proc: process_const_str_mult (in reference: stri, in integer: factor,
inout expr_type: c_expr) is func
local
var expr_type: c_stri is expr_type.value;
begin
if factor < 0 then
incr(countOptimizations);
warning(DOES_RAISE, "RANGE_ERROR", c_expr);
c_expr.expr &:= strRaiseError("RANGE_ERROR");
elsif factor = 0 then
incr(countOptimizations);
c_expr.expr &:= stringLiteral("");
elsif factor = 1 then
incr(countOptimizations);
process_expr(stri, c_expr);
elsif useSpecialCaseFunctions and
isActionExpression(stri, "CHR_STR") then
incr(countOptimizations);
prepare_stri_result(c_expr);
c_expr.result_expr := "strChMult(";
getAnyParamToResultExpr(getActionParameter(stri, 1), c_expr);
c_expr.result_expr &:= ", ";
c_expr.result_expr &:= integerLiteral(factor);
c_expr.result_expr &:= ")";
else
prepare_stri_result(c_expr);
c_expr.result_expr := "strMult(";
getAnyParamToResultExpr(stri, c_expr);
c_expr.result_expr &:= ", ";
c_expr.result_expr &:= integerLiteral(factor);
c_expr.result_expr &:= ")";
end if;
end func;
const proc: process (STR_MULT, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
begin
if getConstant(params[1], STRIOBJECT, evaluatedParam) then
process_const_str_mult(getValue(evaluatedParam, string), params[3], c_expr);
elsif getConstant(params[3], INTOBJECT, evaluatedParam) then
process_const_str_mult(params[1], getValue(evaluatedParam, integer), c_expr);
elsif useSpecialCaseFunctions and
isActionExpression(params[1], "CHR_STR") then
incr(countOptimizations);
prepare_stri_result(c_expr);
c_expr.result_expr := "strChMult(";
getAnyParamToResultExpr(getActionParameter(params[1], 1), c_expr);
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(params[3], c_expr);
c_expr.result_expr &:= ")";
else
prepare_stri_result(c_expr);
c_expr.result_expr := "strMult(";
getAnyParamToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(params[3], c_expr);
c_expr.result_expr &:= ")";
end if;
end func;
const proc: process_const_str_ne (in reference: param1, in string: stri_b,
inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var string: stri_a_name is "";
begin
incr(countOptimizations);
if getConstant(param1, STRIOBJECT, evaluatedParam) then
c_expr.expr &:= "/* ";
c_expr.expr &:= replace(literal(getValue(evaluatedParam, string)), "*/", "*\\/");
c_expr.expr &:= " != ";
c_expr.expr &:= replace(literal(stri_b), "*/", "*\\/");
c_expr.expr &:= " */ ";
if getValue(evaluatedParam, string) <> stri_b then
c_expr.expr &:= "1";
else
c_expr.expr &:= "0";
end if;
elsif stri_b = "" then
c_expr.expr &:= "((";
getAnyParamToExpr(param1, c_expr);
c_expr.expr &:= ")->size!=0 /* \"\" */)";
else
c_expr.expr &:= "(";
stri_a_name := getParameterAsVariable("const_striType", "tmp_", param1, c_expr);
if length(stri_b) = 1 then
c_expr.expr &:= stri_a_name;
c_expr.expr &:= "->size!=1||";
c_expr.expr &:= stri_a_name;
c_expr.expr &:= "->mem[0]!=(strElemType)(";
c_expr.expr &:= c_literal(stri_b[1]);
c_expr.expr &:= ") /* ";
c_expr.expr &:= literal(stri_b);
c_expr.expr &:= " */)";
else
c_expr.expr &:= stri_a_name;
c_expr.expr &:= "->size!=";
c_expr.expr &:= str(length(stri_b));
c_expr.expr &:= "||memcmp(";
c_expr.expr &:= stri_a_name;
c_expr.expr &:= "->mem,(";
c_expr.expr &:= stringLiteral(stri_b);
c_expr.expr &:= ")->mem,";
c_expr.expr &:= str(length(stri_b));
c_expr.expr &:= "*sizeof(strElemType))!=0)";
end if;
end if;
end func;
const proc: process (STR_NE, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var string: stri_a_name is "";
var string: stri_b_name is "";
begin
if getConstant(params[3], STRIOBJECT, evaluatedParam) then
process_const_str_ne(params[1], getValue(evaluatedParam, string), c_expr);
elsif getConstant(params[1], STRIOBJECT, evaluatedParam) then
process_const_str_ne(params[3], getValue(evaluatedParam, string), c_expr);
else
c_expr.expr &:= "(";
stri_a_name := getParameterAsVariable("const_striType", "tmp_a_", params[1], c_expr);
stri_b_name := getParameterAsVariable("const_striType", "tmp_b_", params[3], c_expr);
c_expr.expr &:= stri_a_name;
c_expr.expr &:= "->size!=";
c_expr.expr &:= stri_b_name;
c_expr.expr &:= "->size||memcmp(";
c_expr.expr &:= stri_a_name;
c_expr.expr &:= "->mem,";
c_expr.expr &:= stri_b_name;
c_expr.expr &:= "->mem,";
c_expr.expr &:= stri_a_name;
c_expr.expr &:= "->size*sizeof(strElemType))!=0)";
end if;
end func;
const proc: process_const_str_pos (in string: mainStri, in reference: searched,
inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var string: searchedName is "";
begin
if getConstant(searched, STRIOBJECT, evaluatedParam) then
incr(countOptimizations);
c_expr.expr &:= "/* pos(";
c_expr.expr &:= replace(literal(mainStri), "*/", "*\\/");
c_expr.expr &:= ",";
c_expr.expr &:= replace(literal(getValue(evaluatedParam, string)), "*/", "*\\/");
c_expr.expr &:= ") */ ";
c_expr.expr &:= integerLiteral(pos(mainStri, getValue(evaluatedParam, string)));
elsif length(mainStri) = 0 then
incr(countOptimizations);
c_expr.expr &:= "/* pos(\"\", *) */ ";
c_expr.expr &:= integerLiteral(0);
elsif length(mainStri) = 1 then
incr(countOptimizations);
c_expr.expr &:= "(";
searchedName := getParameterAsVariable("const_striType", "searched_", searched, c_expr);
c_expr.expr &:= searchedName;
c_expr.expr &:= "->size==1&&";
c_expr.expr &:= searchedName;
c_expr.expr &:= "->mem[0]==";
c_expr.expr &:= charLiteral(mainStri[1]);
c_expr.expr &:= "?1:0";
c_expr.expr &:= ")";
elsif isActionExpression(searched, "CHR_STR") then
process_const_str_chpos(reduceMainStriLengthForCharSearch(mainStri),
getActionParameter(searched, 1), c_expr);
elsif isActionExpression(searched, "STR_SUBSTR_FIXLEN") and
getConstant(getActionParameter(searched, 5), INTOBJECT, evaluatedParam) and
getValue(evaluatedParam, integer) = 1 then
c_expr.expr &:= "strChPos(";
c_expr.expr &:= stringLiteral(reduceMainStriLengthForCharSearch(mainStri));
c_expr.expr &:= ", ";
process_str_idx(getActionParameter(searched, 1),
getActionParameter(searched, 3), c_expr);
c_expr.expr &:= ")";
else
c_expr.expr &:= "strPos(";
c_expr.expr &:= stringLiteral(mainStri);
c_expr.expr &:= ", ";
getAnyParamToExpr(searched, c_expr);
c_expr.expr &:= ")";
end if;
end func;
const proc: process_const_str_pos (in reference: mainStri, in string: searched,
inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
begin
if length(searched) = 0 then
incr(countOptimizations);
c_expr.expr &:= "/* pos(*, \"\") */ ";
c_expr.expr &:= integerLiteral(0);
elsif length(searched) = 1 then
incr(countOptimizations);
c_expr.expr &:= "strChPos(";
getAnyParamToExpr(mainStri, c_expr);
c_expr.expr &:= ", ";
c_expr.expr &:= charLiteral(searched[1]);
c_expr.expr &:= ")";
else
c_expr.expr &:= "strPos(";
getAnyParamToExpr(mainStri, c_expr);
c_expr.expr &:= ", ";
c_expr.expr &:= stringLiteral(searched);
c_expr.expr &:= ")";
end if;
end func;
const proc: process (STR_POS, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
begin
if getConstant(params[1], STRIOBJECT, evaluatedParam) then
process_const_str_pos(getValue(evaluatedParam, string), params[2], c_expr);
elsif getConstant(params[2], STRIOBJECT, evaluatedParam) then
process_const_str_pos(params[1], getValue(evaluatedParam, string), c_expr);
elsif isActionExpression(params[2], "CHR_STR") then
c_expr.expr &:= "strChPos(";
getAnyParamToExpr(params[1], c_expr);
c_expr.expr &:= ", ";
process_expr(getActionParameter(params[2], 1), c_expr);
c_expr.expr &:= ")";
elsif isActionExpression(params[2], "STR_SUBSTR_FIXLEN") and
getConstant(getActionParameter(params[2], 5), INTOBJECT, evaluatedParam) and
getValue(evaluatedParam, integer) = 1 then
c_expr.expr &:= "strChPos(";
getAnyParamToExpr(params[1], c_expr);
c_expr.expr &:= ", ";
process_str_idx(getActionParameter(params[2], 1),
getActionParameter(params[2], 3), c_expr);
c_expr.expr &:= ")";
else
c_expr.expr &:= "strPos(";
getAnyParamToExpr(params[1], c_expr);
c_expr.expr &:= ", ";
getAnyParamToExpr(params[2], c_expr);
c_expr.expr &:= ")";
end if;
end func;
const proc: process_const_str_poscpy (in reference: destStri,
in integer: position, in string: aStri, inout expr_type: c_expr) is func
local
var expr_type: c_destStri is expr_type.value;
begin
incr(countOptimizations);
if position < 1 then
c_expr.expr &:= "/* 'string @:= [n] string' with n < 1 */\n";
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= raiseError("INDEX_ERROR");
else
incr(countOptimizations);
process_expr(destStri, c_destStri);
c_expr.expr &:= "{\n";
if c_destStri.temp_num <> 0 then
appendWithDiagnostic(c_destStri.temp_decls, c_expr);
appendWithDiagnostic(c_destStri.temp_assigns, c_expr);
end if;
if string_index_check then
incr(countIndexChecks);
c_expr.expr &:= "striType destStri=";
c_expr.expr &:= c_destStri.expr;
c_expr.expr &:= ";\n";
c_expr.expr &:= "if (idxChk(";
c_expr.expr &:= "destStri->size<";
c_expr.expr &:= integerLiteral(length(aStri));
c_expr.expr &:= " || (uintType)";
c_expr.expr &:= integerLiteral(pred(position));
c_expr.expr &:= ">destStri->size-";
c_expr.expr &:= integerLiteral(length(aStri));
c_expr.expr &:= ")) {\n";
c_expr.expr &:= " ";
c_expr.expr &:= raiseError("INDEX_ERROR");
c_expr.expr &:= "} else {\n";
setDiagnosticLine(c_expr);
c_expr.expr &:= " memcpy(&destStri->mem[";
c_expr.expr &:= integerLiteral(pred(position));
c_expr.expr &:= "], (";
c_expr.expr &:= stringLiteral(aStri);
c_expr.expr &:= ")->mem, ";
c_expr.expr &:= integerLiteral(length(aStri));
c_expr.expr &:= "*sizeof(strElemType));\n";
c_expr.expr &:= "}\n";
else
incr(countSuppressedIndexChecks);
setDiagnosticLine(c_expr);
c_expr.expr &:= "memcpy(&(";
c_expr.expr &:= c_destStri.expr;
c_expr.expr &:= ")->mem[";
c_expr.expr &:= integerLiteral(pred(position));
c_expr.expr &:= "], (";
c_expr.expr &:= stringLiteral(aStri);
c_expr.expr &:= ")->mem, ";
c_expr.expr &:= integerLiteral(length(aStri));
c_expr.expr &:= "*sizeof(strElemType));\n";
end if;
if c_destStri.temp_num <> 0 then
appendWithDiagnostic(c_destStri.temp_frees, c_expr);
end if;
c_expr.expr &:= "}\n";
end if;
end func;
const proc: process_const_str_poscpy (in reference: destStri,
in integer: position, in reference: aStri, inout expr_type: c_expr) is func
local
var expr_type: c_destStri is expr_type.value;
var expr_type: c_aStri is expr_type.value;
begin
incr(countOptimizations);
if position < 1 then
c_expr.expr &:= "/* 'string @:= [n] string' with n < 1 */\n";
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= raiseError("INDEX_ERROR");
else
process_expr(destStri, c_destStri);
c_aStri.temp_num := c_destStri.temp_num;
getAnyParamToExpr(aStri, c_aStri);
c_expr.expr &:= "{\n";
if c_aStri.temp_num <> 0 then
appendWithDiagnostic(c_destStri.temp_decls, c_expr);
appendWithDiagnostic(c_aStri.temp_decls, c_expr);
appendWithDiagnostic(c_destStri.temp_assigns, c_expr);
appendWithDiagnostic(c_aStri.temp_assigns, c_expr);
end if;
if string_index_check then
incr(countIndexChecks);
c_expr.expr &:= "striType destStri=";
c_expr.expr &:= c_destStri.expr;
c_expr.expr &:= ";\n";
c_expr.expr &:= "const_striType aStri=";
c_expr.expr &:= c_aStri.expr;
c_expr.expr &:= ";\n";
c_expr.expr &:= "if (idxChk(destStri->size<aStri->size || (uintType)";
c_expr.expr &:= integerLiteral(pred(position));
c_expr.expr &:= ">destStri->size-aStri->size)) {\n";
c_expr.expr &:= " ";
c_expr.expr &:= raiseError("INDEX_ERROR");
c_expr.expr &:= "} else {\n";
setDiagnosticLine(c_expr);
c_expr.expr &:= " memmove(&destStri->mem[";
c_expr.expr &:= integerLiteral(pred(position));
c_expr.expr &:= "], aStri->mem, aStri->size*sizeof(strElemType));\n";
c_expr.expr &:= "}\n";
else
incr(countSuppressedIndexChecks);
c_expr.expr &:= "const_striType aStri=";
c_expr.expr &:= c_aStri.expr;
c_expr.expr &:= ";\n";
setDiagnosticLine(c_expr);
c_expr.expr &:= "memmove(&(";
c_expr.expr &:= c_destStri.expr;
c_expr.expr &:= ")->mem[";
c_expr.expr &:= integerLiteral(pred(position));
c_expr.expr &:= "], aStri->mem, aStri->size*sizeof(strElemType));\n";
end if;
if c_aStri.temp_num <> 0 then
appendWithDiagnostic(c_destStri.temp_frees, c_expr);
appendWithDiagnostic(c_aStri.temp_frees, c_expr);
end if;
c_expr.expr &:= "}\n";
end if;
end func;
const proc: process_const_str_poscpy (in reference: destStri,
in reference: position, in string: aStri, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var expr_type: c_destStri is expr_type.value;
var expr_type: c_position is expr_type.value;
begin
if getConstant(position, INTOBJECT, evaluatedParam) then
process_const_str_poscpy(destStri, getValue(evaluatedParam, integer), aStri, c_expr);
else
incr(countOptimizations);
process_expr(destStri, c_destStri);
c_position.temp_num := c_destStri.temp_num;
process_expr(position, c_position);
c_expr.expr &:= "{\n";
if c_position.temp_num <> 0 then
appendWithDiagnostic(c_destStri.temp_decls, c_expr);
appendWithDiagnostic(c_position.temp_decls, c_expr);
appendWithDiagnostic(c_destStri.temp_assigns, c_expr);
appendWithDiagnostic(c_position.temp_assigns, c_expr);
end if;
if string_index_check then
incr(countIndexChecks);
c_expr.expr &:= "striType destStri=";
c_expr.expr &:= c_destStri.expr;
c_expr.expr &:= ";\n";
c_expr.expr &:= "intType position=";
c_expr.expr &:= c_position.expr;
c_expr.expr &:= ";\n";
c_expr.expr &:= "if (idxChk(";
c_expr.expr &:= "position<=0 || ";
c_expr.expr &:= "destStri->size<";
c_expr.expr &:= integerLiteral(length(aStri));
c_expr.expr &:= " || (uintType)(position-1)>destStri->size-";
c_expr.expr &:= integerLiteral(length(aStri));
c_expr.expr &:= ")) {\n";
c_expr.expr &:= " ";
c_expr.expr &:= raiseError("INDEX_ERROR");
c_expr.expr &:= "} else {\n";
setDiagnosticLine(c_expr);
c_expr.expr &:= " memcpy(&destStri->mem[position-1], (";
c_expr.expr &:= stringLiteral(aStri);
c_expr.expr &:= ")->mem, ";
c_expr.expr &:= integerLiteral(length(aStri));
c_expr.expr &:= "*sizeof(strElemType));\n";
c_expr.expr &:= "}\n";
else
incr(countSuppressedIndexChecks);
setDiagnosticLine(c_expr);
c_expr.expr &:= "memcpy(&(";
c_expr.expr &:= c_destStri.expr;
c_expr.expr &:= ")->mem[(";
c_expr.expr &:= c_position.expr;
c_expr.expr &:= ")-1], (";
c_expr.expr &:= stringLiteral(aStri);
c_expr.expr &:= ")->mem, ";
c_expr.expr &:= integerLiteral(length(aStri));
c_expr.expr &:= "*sizeof(strElemType));\n";
end if;
if c_position.temp_num <> 0 then
appendWithDiagnostic(c_destStri.temp_frees, c_expr);
appendWithDiagnostic(c_position.temp_frees, c_expr);
end if;
c_expr.expr &:= "}\n";
end if;
end func;
const proc: process (STR_POSCPY, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var string: destStri is "";
var expr_type: c_destStri is expr_type.value;
var expr_type: c_position is expr_type.value;
var expr_type: c_aStri is expr_type.value;
begin
if getConstant(params[6], STRIOBJECT, evaluatedParam) then
destStri := getValue(evaluatedParam, string);
if length(destStri) = 1 then
process_const_str_elemcpy(params[1], params[4], destStri[1], c_expr);
else
process_const_str_poscpy(params[1], params[4], destStri, c_expr);
end if;
elsif getConstant(params[4], INTOBJECT, evaluatedParam) then
process_const_str_poscpy(params[1], getValue(evaluatedParam, integer), params[6], c_expr);
else
process_expr(params[1], c_destStri);
c_position.temp_num := c_destStri.temp_num;
process_expr(params[4], c_position);
c_aStri.temp_num := c_position.temp_num;
getAnyParamToExpr(params[6], c_aStri);
c_expr.expr &:= "{\n";
if c_aStri.temp_num <> 0 then
appendWithDiagnostic(c_destStri.temp_decls, c_expr);
appendWithDiagnostic(c_position.temp_decls, c_expr);
appendWithDiagnostic(c_aStri.temp_decls, c_expr);
appendWithDiagnostic(c_destStri.temp_assigns, c_expr);
appendWithDiagnostic(c_position.temp_assigns, c_expr);
appendWithDiagnostic(c_aStri.temp_assigns, c_expr);
end if;
if string_index_check then
incr(countIndexChecks);
c_expr.expr &:= "striType destStri=";
c_expr.expr &:= c_destStri.expr;
c_expr.expr &:= ";\n";
c_expr.expr &:= "const_striType aStri=";
c_expr.expr &:= c_aStri.expr;
c_expr.expr &:= ";\n";
c_expr.expr &:= "intType position=";
c_expr.expr &:= c_position.expr;
c_expr.expr &:= ";\n";
c_expr.expr &:= "if (idxChk(";
c_expr.expr &:= "position<=0 || ";
c_expr.expr &:= "destStri->size<aStri->size || (uintType)(position-1)>destStri->size-aStri->size)) {\n";
c_expr.expr &:= " ";
c_expr.expr &:= raiseError("INDEX_ERROR");
c_expr.expr &:= "} else {\n";
setDiagnosticLine(c_expr);
c_expr.expr &:= " memmove(&destStri->mem[position-1], aStri->mem, aStri->size*sizeof(strElemType));\n";
c_expr.expr &:= "}\n";
else
incr(countSuppressedIndexChecks);
c_expr.expr &:= "const_striType aStri=";
c_expr.expr &:= c_aStri.expr;
c_expr.expr &:= ";\n";
setDiagnosticLine(c_expr);
c_expr.expr &:= "memmove(&(";
c_expr.expr &:= c_destStri.expr;
c_expr.expr &:= ")->mem[(";
c_expr.expr &:= c_position.expr;
c_expr.expr &:= ")-1], aStri->mem, aStri->size*sizeof(strElemType));\n";
end if;
if c_aStri.temp_num <> 0 then
appendWithDiagnostic(c_destStri.temp_frees, c_expr);
appendWithDiagnostic(c_position.temp_frees, c_expr);
appendWithDiagnostic(c_aStri.temp_frees, c_expr);
end if;
c_expr.expr &:= "}\n";
end if;
end func;
const proc: process (STR_PUSH, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
begin
if getConstant(params[3], CHAROBJECT, evaluatedParam) then
process_const_str_push(params[1], getValue(evaluatedParam, char), c_expr);
else
process_str_push(params[1], params[3], c_expr);
end if;
end func;
const proc: process_inline_str_range (in reference: stri,
in reference: start, in reference: stop, in string: slice_name,
inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var string: stri_name is "";
var string: stri_value is "";
var boolean: stri_is_variable is TRUE;
var string: stri_size is "";
var string: start_name is "";
var integer: start_value is 0;
var boolean: start_is_variable is TRUE;
var intRange: start_range is intRange.value;
var string: stop_name is "";
var integer: stop_value is 0;
var boolean: stop_is_variable is TRUE;
var intRange: stop_range is intRange.value;
var boolean: raisesIndexError is FALSE;
begin
if getConstant(stri, STRIOBJECT, evaluatedParam) then
stri_is_variable := FALSE;
stri_value := getValue(evaluatedParam, string);
stri_name := "(" & stringLiteral(stri_value) & ")";
stri_size := memSizeLiteral(length(stri_value));
else
stri_name := getParameterAsVariable("const_striType", "stri_", stri, c_expr);
stri_size := stri_name & "->size";
end if;
start_range := getIntRange(start);
if getConstant(start, INTOBJECT, evaluatedParam) then
start_is_variable := FALSE;
start_value := getValue(evaluatedParam, integer);
if start_value < 1 then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
raisesIndexError := TRUE;
else
start_name := integerLiteral(start_value);
end if;
elsif start_range.maxValue < 1 then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
raisesIndexError := TRUE;
else
start_name := getTempVariable("intType", "start_", start, c_expr);
if string_index_check then
if start_range.minValue < 1 then
incr(countIndexChecks);
c_expr.expr &:= "idxChk(";
c_expr.expr &:= start_name;
c_expr.expr &:= "<1)?";
c_expr.expr &:= intRaiseError("INDEX_ERROR");
c_expr.expr &:= ":0, ";
else
countIndexOptimizations(c_expr);
end if;
else
incr(countSuppressedIndexChecks);
end if;
end if;
if not raisesIndexError then
stop_range := getIntRange(stop);
if getConstant(stop, INTOBJECT, evaluatedParam) then
stop_is_variable := FALSE;
stop_value := getValue(evaluatedParam, integer);
if stop_value < 0 or
not start_is_variable and stop_value < pred(start_value) then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
raisesIndexError := TRUE;
else
stop_name := integerLiteral(stop_value);
end if;
elsif stop_range.maxValue < 0 or
not start_is_variable and
stop_range.maxValue < pred(start_value) then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
raisesIndexError := TRUE;
else
stop_name := getParameterAsVariable("intType", "stop_", stop, c_expr);
end if;
if not raisesIndexError then
if not stri_is_variable and not start_is_variable and
length(stri_value) < start_value then
if stop_is_variable then
if string_index_check then
if stop_range.minValue < pred(start_value) then
incr(countIndexChecks);
c_expr.expr &:= "idxChk(";
c_expr.expr &:= stop_name;
c_expr.expr &:= "<";
c_expr.expr &:= integerLiteral(pred(start_value));
c_expr.expr &:= ")?";
c_expr.expr &:= intRaiseError("INDEX_ERROR");
c_expr.expr &:= " : ";
else
countIndexOptimizations(c_expr);
end if;
else
incr(countSuppressedIndexChecks);
end if;
end if;
c_expr.expr &:= "(";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".mem = NULL,";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".size = 0)";
else
c_expr.expr &:= stop_name;
c_expr.expr &:= ">=";
c_expr.expr &:= start_name;
if start_is_variable or stri_is_variable then
c_expr.expr &:= " && (uintType)";
c_expr.expr &:= start_name;
c_expr.expr &:= "<=";
c_expr.expr &:= stri_size;
end if;
c_expr.expr &:= " ? (";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".mem = &";
c_expr.expr &:= stri_name;
c_expr.expr &:= "->mem[";
if start_is_variable then
c_expr.expr &:= start_name;
c_expr.expr &:= "-1"
else
c_expr.expr &:= integerLiteral(pred(start_value));
end if;
c_expr.expr &:= "], (uintType)";
c_expr.expr &:= stop_name;
c_expr.expr &:= " > ";
c_expr.expr &:= stri_size;
c_expr.expr &:= " ? ";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".size = ";
c_expr.expr &:= stri_size;
c_expr.expr &:= "-(memSizeType)";
if start_is_variable then
c_expr.expr &:= start_name;
c_expr.expr &:= "+1";
else
c_expr.expr &:= integerLiteral(pred(start_value));
end if;
c_expr.expr &:= " : (";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".size = (memSizeType)";
c_expr.expr &:= stop_name;
c_expr.expr &:= "-(memSizeType)";
if start_is_variable then
c_expr.expr &:= start_name;
c_expr.expr &:= "+1";
else
c_expr.expr &:= integerLiteral(pred(start_value));
end if;
c_expr.expr &:= "))";
if start_is_variable or stop_is_variable then
if string_index_check then
if stop_range.minValue < start_range.maxValue then
incr(countIndexChecks);
c_expr.expr &:= " : idxChk(";
c_expr.expr &:= stop_name;
c_expr.expr &:= "<";
if start_is_variable then
c_expr.expr &:= start_name;
c_expr.expr &:= "-1";
else
c_expr.expr &:= integerLiteral(pred(start_value));
end if;
c_expr.expr &:= ")?";
c_expr.expr &:= intRaiseError("INDEX_ERROR");
else
countIndexOptimizations(c_expr);
end if;
else
incr(countSuppressedIndexChecks);
end if;
end if;
c_expr.expr &:= " : (";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".mem = NULL,";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".size = 0)";
end if;
end if;
end if;
end func;
const proc: process_str_range_of_empty_string (in ref_list: params,
inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var string: start_name is "";
var string: stop_name is "";
var integer: start_value is 0;
var boolean: start_is_variable is TRUE;
var integer: stop_value is 0;
var boolean: stop_is_variable is TRUE;
var boolean: raisesIndexError is FALSE;
begin
incr(countOptimizations);
c_expr.expr &:= "/* \"\"[m .. n] */ (";
if getConstant(params[3], INTOBJECT, evaluatedParam) then
start_is_variable := FALSE;
start_value := getValue(evaluatedParam, integer);
if start_value < 1 then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
raisesIndexError := TRUE;
else
start_name := integerLiteral(start_value);
end if;
else
start_name := getTempVariable("intType", "start_", params[3], c_expr);
end if;
if not raisesIndexError then
if getConstant(params[5], INTOBJECT, evaluatedParam) then
stop_is_variable := FALSE;
stop_value := getValue(evaluatedParam, integer);
if stop_value < 0 or
not start_is_variable and stop_value < pred(start_value) then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
raisesIndexError := TRUE;
else
stop_name := integerLiteral(stop_value);
end if;
else
stop_name := getParameterAsVariable("intType", "stop_", params[5], c_expr);
end if;
if not raisesIndexError then
if start_is_variable or stop_is_variable then
if string_index_check then
incr(countIndexChecks);
c_expr.expr &:= "idxChk(";
if start_is_variable then
c_expr.expr &:= start_name;
c_expr.expr &:= "<1||";
end if;
c_expr.expr &:= stop_name;
c_expr.expr &:= "<";
c_expr.expr &:= start_name;
c_expr.expr &:= "-1)?";
c_expr.expr &:= strRaiseError("INDEX_ERROR");
c_expr.expr &:= ":";
else
incr(countSuppressedIndexChecks);
end if;
end if;
c_expr.expr &:= stringLiteral("");
end if;
end if;
c_expr.expr &:= ")";
end func;
const proc: process (STR_RANGE, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var string: start_name is "";
var string: slice_name is "";
begin
if getConstant(params[1], STRIOBJECT, evaluatedParam) and
getValue(evaluatedParam, string) = "" then
process_str_range_of_empty_string(params, c_expr);
elsif getConstant(params[3], INTOBJECT, evaluatedParam) and
getValue(evaluatedParam, integer) = 1 then
incr(countOptimizations);
process_str_head(params[1], params[5], c_expr);
elsif ccConf.ALLOW_STRITYPE_SLICES and c_expr.demand < REQUIRE_RESULT then
c_expr.expr &:= "(";
incr(c_expr.temp_num);
slice_name := "slice_" & str(c_expr.temp_num);
c_expr.temp_decls &:= "struct striStruct ";
c_expr.temp_decls &:= slice_name;
c_expr.temp_decls &:= ";\n";
if inlineFunctions then
incr(countInlinedFunctions);
process_inline_str_range(params[1], params[3], params[5],
slice_name, c_expr);
else
c_expr.expr &:= "strRangeSlice(";
getAnyParamToExpr(params[1], c_expr);
c_expr.expr &:= ", ";
process_expr(params[3], c_expr);
c_expr.expr &:= ", ";
process_expr(params[5], c_expr);
c_expr.expr &:= ", &";
c_expr.expr &:= slice_name;
c_expr.expr &:= ")";
end if;
c_expr.expr &:= ", &";
c_expr.expr &:= slice_name;
c_expr.expr &:= ")";
else
prepare_stri_result(c_expr);
c_expr.result_expr := "strRange(";
getAnyParamToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(params[3], c_expr);
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(params[5], c_expr);
c_expr.result_expr &:= ")";
end if;
end func;
const proc: process (STR_RCHIPOS, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
c_expr.expr &:= "strRChIPos(";
getAnyParamToExpr(params[1], c_expr);
c_expr.expr &:= ", ";
process_expr(params[2], c_expr);
c_expr.expr &:= ", ";
process_expr(params[3], c_expr);
c_expr.expr &:= ")";
end func;
const proc: process_const_str_rchpos (in string: mainStri, in reference: param2,
inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
begin
if getConstant(param2, CHAROBJECT, evaluatedParam) then
incr(countOptimizations);
c_expr.expr &:= "/* rpos(";
c_expr.expr &:= replace(literal(mainStri), "*/", "*\\/");
c_expr.expr &:= ",";
c_expr.expr &:= literal(getValue(evaluatedParam, char));
c_expr.expr &:= ") */ ";
c_expr.expr &:= integerLiteral(rpos(mainStri, getValue(evaluatedParam, char)));
elsif length(mainStri) = 0 then
incr(countOptimizations);
c_expr.expr &:= "/* rpos(\"\", *) */ ";
c_expr.expr &:= integerLiteral(0);
elsif length(mainStri) = 1 then
incr(countOptimizations);
c_expr.expr &:= "/* rpos(";
c_expr.expr &:= literal(mainStri);
c_expr.expr &:= ", *) */ ";
c_expr.expr &:= charLiteral(mainStri[1]);
c_expr.expr &:= "==(";
getAnyParamToExpr(param2, c_expr);
c_expr.expr &:= ")?";
c_expr.expr &:= integerLiteral(1);
c_expr.expr &:= ":";
c_expr.expr &:= integerLiteral(0);
else
c_expr.expr &:= "strRChPos(";
c_expr.expr &:= stringLiteral(mainStri);
c_expr.expr &:= ", ";
getAnyParamToExpr(param2, c_expr);
c_expr.expr &:= ")";
end if;
end func;
const proc: process (STR_RCHPOS, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
begin
if getConstant(params[1], STRIOBJECT, evaluatedParam) then
process_const_str_rchpos(getValue(evaluatedParam, string), params[2], c_expr);
else
c_expr.expr &:= "strRChPos(";
getAnyParamToExpr(params[1], c_expr);
c_expr.expr &:= ", ";
process_expr(params[2], c_expr);
c_expr.expr &:= ")";
end if;
end func;
const proc: process_const_str_repl (in reference: param1,
in string: searched, in reference: param3, inout expr_type: c_expr) is func
local
var expr_type: c_param1 is expr_type.value;
var reference: evaluatedParam is NIL;
var string: replacement is "";
begin
if searched = "" then
incr(countOptimizations);
prepareAnyParamTemporarys(param1, c_param1, c_expr);
if c_param1.result_expr <> "" then
prepare_stri_result(c_expr);
c_expr.result_expr := "/* strRepl(*, \"\", *) */ ";
c_expr.result_expr &:= c_param1.result_expr;
else
c_expr.expr &:= "/* strRepl(*, \"\", *) */ ";
c_expr.expr &:= c_param1.expr;
end if;
elsif getConstant(param3, STRIOBJECT, evaluatedParam) then
replacement := getValue(evaluatedParam, string);
if searched = replacement then
prepareAnyParamTemporarys(param1, c_param1, c_expr);
if c_param1.result_expr <> "" then
prepare_stri_result(c_expr);
c_expr.result_expr := "/* strRepl(*, ";
c_expr.result_expr &:= replace(literal(searched), "*/", "*\\/");
c_expr.result_expr &:= ", ";
c_expr.result_expr &:= replace(literal(replacement), "*/", "*\\/");
c_expr.result_expr &:= ") */ ";
c_expr.result_expr &:= c_param1.result_expr;
else
c_expr.expr &:= "/* strRepl(*, ";
c_expr.expr &:= replace(literal(searched), "*/", "*\\/");
c_expr.expr &:= ", ";
c_expr.expr &:= replace(literal(replacement), "*/", "*\\/");
c_expr.expr &:= ") */ ";
c_expr.expr &:= c_param1.expr;
end if;
elsif length(searched) = 1 then
if length(replacement) = 1 then
prepare_stri_result(c_expr);
c_expr.result_expr := "strChChRepl(";
getAnyParamToResultExpr(param1, c_expr);
c_expr.result_expr &:= ", ";
c_expr.result_expr &:= charLiteral(searched[1]);
c_expr.result_expr &:= ", ";
c_expr.result_expr &:= charLiteral(replacement[1]);
c_expr.result_expr &:= ")";
else
prepare_stri_result(c_expr);
c_expr.result_expr := "strChRepl(";
getAnyParamToResultExpr(param1, c_expr);
c_expr.result_expr &:= ", ";
c_expr.result_expr &:= charLiteral(searched[1]);
c_expr.result_expr &:= ", ";
c_expr.result_expr &:= stringLiteral(replacement);
c_expr.result_expr &:= ")";
end if;
else
prepare_stri_result(c_expr);
c_expr.result_expr := "strRepl(";
getAnyParamToResultExpr(param1, c_expr);
c_expr.result_expr &:= ", ";
c_expr.result_expr &:= stringLiteral(searched);
c_expr.result_expr &:= ", ";
c_expr.result_expr &:= stringLiteral(replacement);
c_expr.result_expr &:= ")";
end if;
elsif length(searched) = 1 then
incr(countOptimizations);
if isActionExpression(param3, "CHR_STR") then
prepare_stri_result(c_expr);
c_expr.result_expr := "strChChRepl(";
getAnyParamToResultExpr(param1, c_expr);
c_expr.result_expr &:= ", ";
c_expr.result_expr &:= charLiteral(searched[1]);
c_expr.result_expr &:= ", ";
getAnyParamToResultExpr(getActionParameter(param3, 1), c_expr);
c_expr.result_expr &:= ")";
else
prepare_stri_result(c_expr);
c_expr.result_expr := "strChRepl(";
getAnyParamToResultExpr(param1, c_expr);
c_expr.result_expr &:= ", ";
c_expr.result_expr &:= charLiteral(searched[1]);
c_expr.result_expr &:= ", ";
getAnyParamToResultExpr(param3, c_expr);
c_expr.result_expr &:= ")";
end if;
else
prepare_stri_result(c_expr);
c_expr.result_expr := "strRepl(";
getAnyParamToResultExpr(param1, c_expr);
c_expr.result_expr &:= ", ";
c_expr.result_expr &:= stringLiteral(searched);
c_expr.result_expr &:= ", ";
getAnyParamToResultExpr(param3, c_expr);
c_expr.result_expr &:= ")";
end if;
end func;
const proc: process (STR_REPL, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var string: replacement is "";
begin
if getConstant(params[2], STRIOBJECT, evaluatedParam) then
process_const_str_repl(params[1], getValue(evaluatedParam, string), params[3], c_expr);
elsif useSpecialCaseFunctions and
isActionExpression(params[2], "CHR_STR") then
incr(countOptimizations);
prepare_stri_result(c_expr);
if getConstant(params[3], STRIOBJECT, evaluatedParam) then
replacement := getValue(evaluatedParam, string);
if length(replacement) = 1 then
c_expr.result_expr := "strChChRepl(";
getAnyParamToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ", ";
getAnyParamToResultExpr(getActionParameter(params[2], 1), c_expr);
c_expr.result_expr &:= ", ";
c_expr.result_expr &:= charLiteral(replacement[1]);
c_expr.result_expr &:= ")";
else
c_expr.result_expr := "strChRepl(";
getAnyParamToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ", ";
getAnyParamToResultExpr(getActionParameter(params[2], 1), c_expr);
c_expr.result_expr &:= ", ";
c_expr.result_expr &:= stringLiteral(replacement);
c_expr.result_expr &:= ")";
end if;
elsif isActionExpression(params[3], "CHR_STR") then
c_expr.result_expr := "strChChRepl(";
getAnyParamToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ", ";
getAnyParamToResultExpr(getActionParameter(params[2], 1), c_expr);
c_expr.result_expr &:= ", ";
getAnyParamToResultExpr(getActionParameter(params[3], 1), c_expr);
c_expr.result_expr &:= ")";
else
c_expr.result_expr := "strChRepl(";
getAnyParamToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ", ";
getAnyParamToResultExpr(getActionParameter(params[2], 1), c_expr);
c_expr.result_expr &:= ", ";
getAnyParamToResultExpr(params[3], c_expr);
c_expr.result_expr &:= ")";
end if;
else
prepare_stri_result(c_expr);
c_expr.result_expr := "strRepl(";
getAnyParamToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ", ";
getAnyParamToResultExpr(params[2], c_expr);
c_expr.result_expr &:= ", ";
getAnyParamToResultExpr(params[3], c_expr);
c_expr.result_expr &:= ")";
end if;
end func;
const proc: process (STR_RIPOS, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
begin
if getConstant(params[2], STRIOBJECT, evaluatedParam) and
length(getValue(evaluatedParam, string)) = 1 then
incr(countOptimizations);
c_expr.expr &:= "strRChIPos(";
getAnyParamToExpr(params[1], c_expr);
c_expr.expr &:= ", ";
c_expr.expr &:= charLiteral(getValue(evaluatedParam, string)[1]);
c_expr.expr &:= ", ";
process_expr(params[3], c_expr);
c_expr.expr &:= ")";
else
c_expr.expr &:= "strRIPos(";
getAnyParamToExpr(params[1], c_expr);
c_expr.expr &:= ", ";
getAnyParamToExpr(params[2], c_expr);
c_expr.expr &:= ", ";
process_expr(params[3], c_expr);
c_expr.expr &:= ")";
end if;
end func;
const proc: process (STR_RPAD, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
prepare_stri_result(c_expr);
c_expr.result_expr := "strRpad(";
getAnyParamToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(params[3], c_expr);
c_expr.result_expr &:= ")";
end func;
const proc: process_const_str_rpos (in reference: mainStri, in string: searched,
inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
begin
if getConstant(mainStri, STRIOBJECT, evaluatedParam) then
incr(countOptimizations);
c_expr.expr &:= "/* rpos(";
c_expr.expr &:= replace(literal(getValue(evaluatedParam, string)), "*/", "*\\/");
c_expr.expr &:= ",";
c_expr.expr &:= replace(literal(searched), "*/", "*\\/");
c_expr.expr &:= ") */ ";
c_expr.expr &:= integerLiteral(rpos(getValue(evaluatedParam, string), searched));
elsif length(searched) = 0 then
incr(countOptimizations);
c_expr.expr &:= "/* rpos(*, \"\") */ ";
c_expr.expr &:= integerLiteral(0);
elsif length(searched) = 1 then
incr(countOptimizations);
c_expr.expr &:= "strRChPos(";
getAnyParamToExpr(mainStri, c_expr);
c_expr.expr &:= ", ";
c_expr.expr &:= charLiteral(searched[1]);
c_expr.expr &:= ")";
else
c_expr.expr &:= "strRPos(";
getAnyParamToExpr(mainStri, c_expr);
c_expr.expr &:= ", ";
c_expr.expr &:= stringLiteral(searched);
c_expr.expr &:= ")";
end if;
end func;
const proc: process (STR_RPOS, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
begin
if getConstant(params[2], STRIOBJECT, evaluatedParam) then
process_const_str_rpos(params[1], getValue(evaluatedParam, string), c_expr);
elsif getConstant(params[1], STRIOBJECT, evaluatedParam) and
length(getValue(evaluatedParam, string)) = 0 then
incr(countOptimizations);
c_expr.expr &:= "/* rpos(\"\", *) */ ";
c_expr.expr &:= integerLiteral(0);
else
c_expr.expr &:= "strRPos(";
getAnyParamToExpr(params[1], c_expr);
c_expr.expr &:= ", ";
getAnyParamToExpr(params[2], c_expr);
c_expr.expr &:= ")";
end if;
end func;
const proc: process (STR_RTRIM, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
prepare_stri_result(c_expr);
c_expr.result_expr := "strRtrim(";
getAnyParamToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ")";
end func;
const proc: process (STR_SPLIT, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
begin
prepare_typed_result(array_type[getExprResultType(params[1])], c_expr);
if getConstant(params[2], STRIOBJECT, evaluatedParam) and
length(getValue(evaluatedParam, string)) = 1 then
incr(countOptimizations);
c_expr.result_expr := "strChSplit(";
getAnyParamToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ", ";
c_expr.result_expr &:= charLiteral(getValue(evaluatedParam, string)[1]);
c_expr.result_expr &:= ")";
else
c_expr.result_expr := "strSplit(";
getAnyParamToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ", ";
getAnyParamToResultExpr(params[2], c_expr);
c_expr.result_expr &:= ")";
end if;
end func;
const proc: process (STR_STR, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
process_expr(params[1], c_expr);
end func;
const proc: process_str_substr0 (in reference: stri, in reference: start,
inout expr_type: c_expr) is func
local
var intRange: start_range is intRange.value;
begin
incr(countOptimizations);
start_range := getIntRange(start);
if start_range.maxValue < 1 then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
else
c_expr.expr &:= "/* string[m len 0] */ (";
if string_index_check then
if start_range.minValue < 1 then
incr(countIndexChecks);
c_expr.expr &:= "idxChk((";
process_expr(start, c_expr);
c_expr.expr &:= ")<1)?";
c_expr.expr &:= strRaiseError("INDEX_ERROR");
c_expr.expr &:= ":";
else
countIndexOptimizations(c_expr);
end if;
else
incr(countSuppressedIndexChecks);
end if;
c_expr.expr &:= stringLiteral("");
c_expr.expr &:= ")";
end if;
end func;
const proc: process_str_substr1 (in reference: stri, in reference: start,
inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var string: stri_name is "";
var string: stri_value is "";
var string: stri_size is "";
var string: start_name is "";
var intRange: start_range is intRange.value;
var string: striStruct_name is "";
begin
if c_expr.demand < REQUIRE_RESULT then
incr(countOptimizations);
c_expr.expr &:= "(";
if getConstant(stri, STRIOBJECT, evaluatedParam) then
stri_value := getValue(evaluatedParam, string);
stri_name := "(" & stringLiteral(stri_value) & ")";
stri_size := memSizeLiteral(length(stri_value));
else
stri_name := getParameterAsVariable("const_striType", "stri_", stri, c_expr);
stri_size := stri_name & "->size";
end if;
incr(c_expr.temp_num);
start_name := getParameterAsVariable("intType", "start_", start, c_expr);
incr(c_expr.temp_num);
striStruct_name := "stri_" & str(c_expr.temp_num);
c_expr.temp_decls &:= "struct striStruct ";
c_expr.temp_decls &:= striStruct_name;
c_expr.temp_decls &:= ";\n";
if string_index_check then
start_range := getIntRange(start);
if start_range.minValue < 1 then
incr(countIndexChecks);
c_expr.expr &:= "idxChk(";
c_expr.expr &:= start_name;
c_expr.expr &:= "<1)?";
c_expr.expr &:= strRaiseError("INDEX_ERROR");
c_expr.expr &:= ":";
else
countIndexOptimizations(c_expr);
end if;
else
incr(countSuppressedIndexChecks);
end if;
c_expr.expr &:= "(";
c_expr.expr &:= start_name;
c_expr.expr &:= ">";
c_expr.expr &:= stri_size;
c_expr.expr &:= " ? ";
c_expr.expr &:= stringLiteral("");
c_expr.expr &:= " : chrStrMacro(";
c_expr.expr &:= stri_name;
c_expr.expr &:= "->mem[";
c_expr.expr &:= start_name;
c_expr.expr &:= "-1],";
c_expr.expr &:= striStruct_name;
c_expr.expr &:= ")))";
else
prepare_stri_result(c_expr);
c_expr.result_expr := "strSubstr(";
getAnyParamToResultExpr(stri, c_expr);
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(start, c_expr);
c_expr.result_expr &:= ", 1)";
end if;
end func;
const proc: process_inline_str_substr (in reference: stri,
in reference: start, in reference: length, in string: slice_name,
inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var string: stri_name is "";
var string: stri_value is "";
var boolean: stri_is_variable is TRUE;
var string: stri_size is "";
var string: start_name is "";
var integer: start_value is 0;
var boolean: start_is_variable is TRUE;
var intRange: start_range is intRange.value;
var string: length_name is "";
var integer: length_value is 0;
var boolean: length_is_variable is TRUE;
var intRange: length_range is intRange.value;
var boolean: raisesIndexError is FALSE;
begin
if getConstant(stri, STRIOBJECT, evaluatedParam) then
stri_is_variable := FALSE;
stri_value := getValue(evaluatedParam, string);
stri_name := "(" & stringLiteral(stri_value) & ")";
stri_size := memSizeLiteral(length(stri_value));
else
stri_name := getParameterAsVariable("const_striType", "stri_", stri, c_expr);
stri_size := stri_name & "->size";
end if;
if getConstant(start, INTOBJECT, evaluatedParam) then
start_is_variable := FALSE;
start_value := getValue(evaluatedParam, integer);
if start_value < 1 then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
raisesIndexError := TRUE;
else
start_name := integerLiteral(start_value);
end if;
else
start_name := getTempVariable("intType", "start_", start, c_expr);
end if;
if not raisesIndexError then
if getConstant(length, INTOBJECT, evaluatedParam) then
length_is_variable := FALSE;
length_value := getValue(evaluatedParam, integer);
if length_value < 0 then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
raisesIndexError := TRUE;
else
length_name := integerLiteral(length_value);
end if;
else
length_name := getParameterAsVariable("intType", "length_", length, c_expr);
end if;
if not raisesIndexError then
if start_is_variable or length_is_variable then
if string_index_check then
start_range := getIntRange(start);
length_range := getIntRange(length);
if start_range.minValue < 1 or length_range.minValue < 0 then
incr(countIndexChecks);
c_expr.expr &:= "idxChk(";
if start_is_variable and start_range.minValue < 1 then
c_expr.expr &:= start_name;
c_expr.expr &:= "<1";
else
countIndexOptimizations(c_expr);
end if;
if start_is_variable and length_is_variable and
start_range.minValue < 1 and length_range.minValue < 0 then
c_expr.expr &:= "||";
end if;
if length_is_variable and length_range.minValue < 0 then
c_expr.expr &:= length_name;
c_expr.expr &:= "<0";
else
countIndexOptimizations(c_expr);
end if;
c_expr.expr &:= ")?";
c_expr.expr &:= intRaiseError("INDEX_ERROR");
c_expr.expr &:= ":0, ";
else
countIndexOptimizations(c_expr);
end if;
else
incr(countSuppressedIndexChecks);
end if;
end if;
if (not length_is_variable and length_value = 0) or
(not stri_is_variable and not start_is_variable and
length(stri_value) < start_value) then
c_expr.expr &:= slice_name;
c_expr.expr &:= ".mem = NULL, ";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".size = 0";
elsif not start_is_variable and not length_is_variable and
start_value <= integer.last - length_value then
c_expr.expr &:= slice_name;
c_expr.expr &:= ".mem = &";
c_expr.expr &:= stri_name;
c_expr.expr &:= "->mem[";
c_expr.expr &:= integerLiteral(pred(start_value));
c_expr.expr &:= "], ";
c_expr.expr &:= integerLiteral(start_value + length_value - 1);
c_expr.expr &:= "<=";
c_expr.expr &:= stri_size;
c_expr.expr &:= " ? ";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".size = (memSizeType)";
c_expr.expr &:= length_name;
c_expr.expr &:= " : (";
c_expr.expr &:= "(uintType)";
c_expr.expr &:= start_name;
c_expr.expr &:= "<=";
c_expr.expr &:= stri_size;
c_expr.expr &:= " ? ";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".size = ";
c_expr.expr &:= stri_size;
c_expr.expr &:= "-(memSizeType)";
c_expr.expr &:= integerLiteral(pred(start_value));
c_expr.expr &:= " : (";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".size = 0))";
else
if length_is_variable then
c_expr.expr &:= length_name;
c_expr.expr &:= "!=0 && ";
end if;
c_expr.expr &:= "(uintType)";
c_expr.expr &:= start_name;
c_expr.expr &:= "<=";
c_expr.expr &:= stri_size;
c_expr.expr &:= " ? (";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".mem = &";
c_expr.expr &:= stri_name;
c_expr.expr &:= "->mem[";
if start_is_variable then
c_expr.expr &:= start_name;
c_expr.expr &:= "-1";
else
c_expr.expr &:= integerLiteral(pred(start_value));
end if;
c_expr.expr &:= "], (uintType)";
c_expr.expr &:= length_name;
c_expr.expr &:= ">";
c_expr.expr &:= stri_size;
c_expr.expr &:= "-(memSizeType)";
if start_is_variable then
c_expr.expr &:= start_name;
c_expr.expr &:= "+1";
else
c_expr.expr &:= integerLiteral(pred(start_value));
end if;
c_expr.expr &:= " ? ";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".size = ";
c_expr.expr &:= stri_size;
c_expr.expr &:= "-(memSizeType)";
if start_is_variable then
c_expr.expr &:= start_name;
c_expr.expr &:= "+1";
else
c_expr.expr &:= integerLiteral(pred(start_value));
end if;
c_expr.expr &:= " : (";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".size = (memSizeType)";
c_expr.expr &:= length_name;
c_expr.expr &:= ")) : (";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".mem = NULL, ";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".size = 0)";
end if;
end if;
end if;
end func;
const proc: process_str_substr_slice (in reference: stri,
in reference: start, in reference: length, in string: slice_name,
inout expr_type: c_expr) is func
begin
c_expr.temp_decls &:= "struct striStruct ";
c_expr.temp_decls &:= slice_name;
c_expr.temp_decls &:= ";\n";
if inlineFunctions then
incr(countInlinedFunctions);
process_inline_str_substr(stri, start, length, slice_name, c_expr);
else
c_expr.expr &:= "strSubstrSlice(";
getAnyParamToExpr(stri, c_expr);
c_expr.expr &:= ", ";
process_expr(start, c_expr);
c_expr.expr &:= ", ";
process_expr(length, c_expr);
c_expr.expr &:= ", &";
c_expr.expr &:= slice_name;
c_expr.expr &:= ")";
end if;
end func;
const proc: process (STR_SUBSTR, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var integer: length is 0;
var string: slice_name is "";
begin
if getConstant(params[1], STRIOBJECT, evaluatedParam) and
getValue(evaluatedParam, string) = "" then
incr(countOptimizations);
c_expr.expr &:= "/* \"\"[m len n] */ (";
if string_index_check then
incr(countIndexChecks);
c_expr.expr &:= "idxChk((";
process_expr(params[3], c_expr);
c_expr.expr &:= ")<1||(";
process_expr(params[5], c_expr);
c_expr.expr &:= ")<0)?";
c_expr.expr &:= strRaiseError("INDEX_ERROR");
c_expr.expr &:= ":";
else
incr(countSuppressedIndexChecks);
end if;
c_expr.expr &:= stringLiteral("");
c_expr.expr &:= ")";
elsif getConstant(params[3], INTOBJECT, evaluatedParam) and
getValue(evaluatedParam, integer) = 1 then
incr(countOptimizations);
process_str_head(params[1], params[5], c_expr);
elsif getConstant(params[5], INTOBJECT, evaluatedParam) and
getValue(evaluatedParam, integer) <= 1 then
length := getValue(evaluatedParam, integer);
if length = 0 then
process_str_substr0(params[1], params[3], c_expr);
elsif length = 1 then
process_str_substr1(params[1], params[3], c_expr);
else
incr(countOptimizations);
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
end if;
elsif ccConf.ALLOW_STRITYPE_SLICES and c_expr.demand < REQUIRE_RESULT then
c_expr.expr &:= "(";
incr(c_expr.temp_num);
slice_name := "slice_" & str(c_expr.temp_num);
process_str_substr_slice(params[1], params[3], params[5],
slice_name, c_expr);
c_expr.expr &:= ", &";
c_expr.expr &:= slice_name;
c_expr.expr &:= ")";
else
prepare_stri_result(c_expr);
c_expr.result_expr := "strSubstr(";
getAnyParamToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(params[3], c_expr);
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(params[5], c_expr);
c_expr.result_expr &:= ")";
end if;
end func;
const proc: process_str_substr_fixlen0 (in reference: stri,
in reference: start, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var boolean: stri_is_variable is TRUE;
var integer: stri_length is 0;
var intRange: start_range is intRange.value;
var string: start_name is "";
var boolean: raisesIndexError is FALSE;
begin
incr(countOptimizations);
start_range := getIntRange(start);
if start_range.maxValue < 1 then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
raisesIndexError := TRUE;
elsif getConstant(stri, STRIOBJECT, evaluatedParam) then
stri_is_variable := FALSE;
stri_length := length(getValue(evaluatedParam, string));
if start_range.minValue > stri_length then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
raisesIndexError := TRUE;
end if;
end if;
if not raisesIndexError then
c_expr.expr &:= "/* string[m fixLen 0] */ (";
if string_index_check then
if stri_is_variable or start_range.minValue < 1 or
start_range.maxValue > stri_length then
incr(countIndexChecks);
if start_range.minValue >= 1 then
c_expr.expr &:= "idxChk(";
c_expr.expr &:= "(";
process_expr(start, c_expr);
c_expr.expr &:= ")>";
else
start_name := getParameterAsVariable("intType", "start_", start, c_expr);
c_expr.expr &:= "idxChk(";
if stri_is_variable or stri_length > 1 then
c_expr.expr &:= start_name;
c_expr.expr &:= "<1||(uintType)";
c_expr.expr &:= start_name;
c_expr.expr &:= ">";
else
c_expr.expr &:= "(uintType)";
c_expr.expr &:= start_name;
c_expr.expr &:= "!=";
end if;
end if;
if stri_is_variable then
c_expr.expr &:= "(";
getAnyParamToExpr(stri, c_expr);
c_expr.expr &:= ")->size";
else
c_expr.expr &:= memSizeLiteral(stri_length);
end if;
c_expr.expr &:= ")?";
c_expr.expr &:= strRaiseError("INDEX_ERROR");
c_expr.expr &:= ":";
else
countIndexOptimizations(c_expr);
end if;
else
incr(countSuppressedIndexChecks);
end if;
c_expr.expr &:= stringLiteral("");
c_expr.expr &:= ")";
end if;
end func;
const proc: process_str_substr_fixlen1 (in reference: stri,
in reference: start, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var boolean: stri_is_variable is TRUE;
var string: stri_name is "";
var string: stri_value is "";
var integer: stri_length is 0;
var string: stri_size is "";
var string: start_name is "";
var integer: start_value is 0;
var intRange: start_range is intRange.value;
var boolean: raisesIndexError is FALSE;
var string: logicalOr is "";
var string: striStruct_name is "";
begin
if c_expr.demand < REQUIRE_RESULT then
incr(countOptimizations);
c_expr.expr &:= "(";
if getConstant(stri, STRIOBJECT, evaluatedParam) then
stri_is_variable := FALSE;
stri_value := getValue(evaluatedParam, string);
stri_name := "(" & stringLiteral(stri_value) & ")";
stri_length := length(stri_value);
stri_size := memSizeLiteral(stri_length);
else
stri_name := getParameterAsVariable("const_striType", "stri_", stri, c_expr);
stri_size := stri_name & "->size";
end if;
if getConstant(start, INTOBJECT, evaluatedParam) then
start_value := getValue(evaluatedParam, integer);
if start_value < 1 then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
raisesIndexError := TRUE;
elsif not stri_is_variable and start_value > stri_length then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
raisesIndexError := TRUE;
else
start_name := integerLiteral(start_value);
end if;
else
start_name := getParameterAsVariable("intType", "start_", start, c_expr);
end if;
if not raisesIndexError then
incr(c_expr.temp_num);
striStruct_name := "stri_" & str(c_expr.temp_num);
c_expr.temp_decls &:= "struct striStruct ";
c_expr.temp_decls &:= striStruct_name;
c_expr.temp_decls &:= ";\n";
if string_index_check then
start_range := getIntRange(start);
if stri_is_variable or start_range.minValue < 1 or
start_range.maxValue > stri_length then
incr(countIndexChecks);
c_expr.expr &:= "idxChk(";
if stri_is_variable or stri_length > 1 then
if start_range.minValue < 1 then
c_expr.expr &:= start_name;
c_expr.expr &:= "<1";
logicalOr := "||";
end if;
if stri_is_variable or start_range.maxValue > stri_length then
c_expr.expr &:= logicalOr;
c_expr.expr &:= "(uintType)";
c_expr.expr &:= start_name;
c_expr.expr &:= ">";
c_expr.expr &:= stri_size;
end if;
else
c_expr.expr &:= "(uintType)";
c_expr.expr &:= start_name;
c_expr.expr &:= "!=";
c_expr.expr &:= stri_size;
end if;
c_expr.expr &:= ")?";
c_expr.expr &:= strRaiseError("INDEX_ERROR");
c_expr.expr &:= ":";
else
countIndexOptimizations(c_expr);
end if;
else
incr(countSuppressedIndexChecks);
end if;
c_expr.expr &:= "chrStrMacro(";
c_expr.expr &:= stri_name;
c_expr.expr &:= "->mem[";
c_expr.expr &:= start_name;
c_expr.expr &:= "-1],";
c_expr.expr &:= striStruct_name;
c_expr.expr &:= ")";
end if;
c_expr.expr &:= ")";
else
prepare_stri_result(c_expr);
c_expr.result_expr := "strSubstrFixLen(";
getAnyParamToResultExpr(stri, c_expr);
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(start, c_expr);
c_expr.result_expr &:= ", 1)";
end if;
end func;
const proc: process_inline_str_substr_fixlen (in string: stri,
in reference: start, in reference: length, in string: slice_name,
inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var integer: stri_length is 0;
var boolean: start_is_variable is TRUE;
var string: start_name is "";
var integer: start_value is 0;
var intRange: start_range is intRange.value;
var string: length_name is "";
var integer: length_value is 0;
var boolean: length_is_variable is TRUE;
var intRange: length_range is intRange.value;
var boolean: raisesIndexError is FALSE;
begin
stri_length := length(stri);
if getConstant(start, INTOBJECT, evaluatedParam) then
start_is_variable := FALSE;
start_value := getValue(evaluatedParam, integer);
if start_value < 1 then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
raisesIndexError := TRUE;
elsif start_value > stri_length then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
raisesIndexError := TRUE;
else
start_name := integerLiteral(start_value);
end if;
else
start_name := getTempVariable("intType", "start_", start, c_expr);
end if;
if not raisesIndexError then
if getConstant(length, INTOBJECT, evaluatedParam) then
length_is_variable := FALSE;
length_value := getValue(evaluatedParam, integer);
if length_value < 0 then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
raisesIndexError := TRUE;
elsif length_value > stri_length then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
raisesIndexError := TRUE;
elsif not start_is_variable and
length_value > stri_length - start_value + 1 then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
raisesIndexError := TRUE;
else
length_name := integerLiteral(length_value);
end if;
else
length_name := getParameterAsVariable("intType", "length_", length, c_expr);
end if;
if not raisesIndexError then
if string_index_check then
start_range := getIntRange(start);
length_range := getIntRange(length);
if start_is_variable or length_is_variable then
incr(countIndexChecks);
c_expr.expr &:= "idxChk(";
if start_is_variable then
if length_is_variable then
c_expr.expr &:= start_name;
if stri_length = 1 then
c_expr.expr &:= "!=1||";
if not ccConf.TWOS_COMPLEMENT_INTTYPE then
c_expr.expr &:= length_name;
c_expr.expr &:= "<0||";
end if;
c_expr.expr &:= "(uintType)";
c_expr.expr &:= length_name;
c_expr.expr &:= ">1";
else
c_expr.expr &:= "<1||(uintType)";
c_expr.expr &:= start_name;
c_expr.expr &:= ">";
c_expr.expr &:= memSizeLiteral(stri_length);
c_expr.expr &:= "||";
c_expr.expr &:= length_name;
c_expr.expr &:= "<0||(uintType)";
c_expr.expr &:= start_name;
c_expr.expr &:= "+(uintType)";
c_expr.expr &:= length_name;
c_expr.expr &:= ">";
c_expr.expr &:= memSizeLiteral(succ(stri_length));
end if;
else
c_expr.expr &:= start_name;
if length_value = stri_length then
c_expr.expr &:= "!=1";
else
c_expr.expr &:= "<1||(uintType)";
c_expr.expr &:= start_name;
if length_value > 0 then
c_expr.expr &:= ">";
c_expr.expr &:= memSizeLiteral(succ(stri_length - length_value));
else
c_expr.expr &:= ">";
c_expr.expr &:= memSizeLiteral(stri_length);
end if;
end if;
end if;
else
if not ccConf.TWOS_COMPLEMENT_INTTYPE then
c_expr.expr &:= length_name;
c_expr.expr &:= "<0||";
end if;
c_expr.expr &:= "(uintType)";
c_expr.expr &:= length_name;
c_expr.expr &:= ">";
c_expr.expr &:= memSizeLiteral(succ(stri_length - start_value));
end if;
c_expr.expr &:= ")?";
c_expr.expr &:= intRaiseError("INDEX_ERROR");
c_expr.expr &:= ":";
else
countIndexOptimizations(c_expr);
end if;
else
incr(countSuppressedIndexChecks);
end if;
c_expr.expr &:= "(";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".mem = &(";
c_expr.expr &:= stringLiteral(stri);
c_expr.expr &:= ")->mem[";
if start_is_variable then
c_expr.expr &:= start_name;
c_expr.expr &:= "-1";
else
c_expr.expr &:= integerLiteral(pred(start_value));
end if;
c_expr.expr &:= "], ";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".size = (memSizeType)";
c_expr.expr &:= length_name;
c_expr.expr &:= ")";
end if;
end if;
end func;
const proc: process_inline_str_substr_fixlen (in reference: stri,
in reference: start, in reference: length, in string: slice_name,
inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var string: stri_name is "";
var string: stri_size is "";
var boolean: start_is_variable is TRUE;
var string: start_name is "";
var integer: start_value is 0;
var intRange: start_range is intRange.value;
var string: length_name is "";
var integer: length_value is 0;
var boolean: length_is_variable is TRUE;
var intRange: length_range is intRange.value;
var boolean: raisesIndexError is FALSE;
begin
stri_name := getParameterAsVariable("const_striType", "stri_", stri, c_expr);
stri_size := stri_name & "->size";
if getConstant(start, INTOBJECT, evaluatedParam) then
start_is_variable := FALSE;
start_value := getValue(evaluatedParam, integer);
if start_value < 1 then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
raisesIndexError := TRUE;
else
start_name := integerLiteral(start_value);
end if;
else
start_name := getTempVariable("intType", "start_", start, c_expr);
end if;
if not raisesIndexError then
if getConstant(length, INTOBJECT, evaluatedParam) then
length_is_variable := FALSE;
length_value := getValue(evaluatedParam, integer);
if length_value < 0 then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
raisesIndexError := TRUE;
else
length_name := integerLiteral(length_value);
end if;
else
length_name := getParameterAsVariable("intType", "length_", length, c_expr);
end if;
if not raisesIndexError then
if string_index_check then
start_range := getIntRange(start);
length_range := getIntRange(length);
incr(countIndexChecks);
c_expr.expr &:= "idxChk(";
if start_is_variable then
if start_range.minValue < 1 then
c_expr.expr &:= start_name;
c_expr.expr &:= "<1||";
end if;
end if;
if length_is_variable then
if length_range.minValue <= 0 then
c_expr.expr &:= "(unlikely(";
c_expr.expr &:= length_name;
c_expr.expr &:= "==0)?";
c_expr.expr &:= "(uintType)";
c_expr.expr &:= start_name;
c_expr.expr &:= ">";
c_expr.expr &:= stri_size;
c_expr.expr &:= ":(";
end if;
if length_range.minValue < 0 then
c_expr.expr &:= length_name;
c_expr.expr &:= "<0||";
end if;
end if;
if start_is_variable then
c_expr.expr &:= "(uintType)";
c_expr.expr &:= start_name;
if length_is_variable then
c_expr.expr &:= "+(uintType)";
c_expr.expr &:= length_name;
c_expr.expr &:= "-1>";
c_expr.expr &:= stri_size;
else
if length_value > 1 then
c_expr.expr &:= "+";
c_expr.expr &:= memSizeLiteral(pred(length_value));
end if;
c_expr.expr &:= ">";
c_expr.expr &:= stri_size;
end if;
else
if length_is_variable then
c_expr.expr &:= "(uintType)";
c_expr.expr &:= length_name;
if start_value > 1 then
c_expr.expr &:= "+";
c_expr.expr &:= memSizeLiteral(pred(start_value));
end if;
c_expr.expr &:= ">";
c_expr.expr &:= stri_size;
else
if length_value > 0 then
c_expr.expr &:= memSizeLiteral(pred(bigInteger(start_value) +
bigInteger(length_value)));
else
c_expr.expr &:= "(uintType)";
c_expr.expr &:= start_name;
end if;
c_expr.expr &:= ">";
c_expr.expr &:= stri_size;
end if;
end if;
if length_is_variable and length_range.minValue <= 0 then
c_expr.expr &:= "))";
end if;
c_expr.expr &:= ")?";
c_expr.expr &:= intRaiseError("INDEX_ERROR");
c_expr.expr &:= ":";
else
incr(countSuppressedIndexChecks);
end if;
c_expr.expr &:= "(";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".mem = &";
c_expr.expr &:= stri_name;
c_expr.expr &:= "->mem[";
if start_is_variable then
c_expr.expr &:= start_name;
c_expr.expr &:= "-1";
else
c_expr.expr &:= integerLiteral(pred(start_value));
end if;
c_expr.expr &:= "], ";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".size = (memSizeType)";
c_expr.expr &:= length_name;
c_expr.expr &:= ")";
end if;
end if;
end func;
const proc: process_str_substr_fixlen_slice (in reference: stri,
in reference: start, in reference: length, in string: slice_name,
inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
begin
c_expr.temp_decls &:= "struct striStruct ";
c_expr.temp_decls &:= slice_name;
c_expr.temp_decls &:= ";\n";
if inlineFunctions then
incr(countInlinedFunctions);
if getConstant(stri, STRIOBJECT, evaluatedParam) then
process_inline_str_substr_fixlen(getValue(evaluatedParam, string),
start, length,
slice_name, c_expr);
else
process_inline_str_substr_fixlen(stri, start, length,
slice_name, c_expr);
end if;
else
c_expr.expr &:= "strSubstrFixLenSlice(";
getAnyParamToExpr(stri, c_expr);
c_expr.expr &:= ", ";
process_expr(start, c_expr);
c_expr.expr &:= ", ";
process_expr(length, c_expr);
c_expr.expr &:= ", &";
c_expr.expr &:= slice_name;
c_expr.expr &:= ")";
end if;
end func;
const proc: process (STR_SUBSTR_FIXLEN, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var integer: length is 0;
var string: slice_name is "";
begin
if getConstant(params[1], STRIOBJECT, evaluatedParam) and
getValue(evaluatedParam, string) = "" then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
elsif getConstant(params[5], INTOBJECT, evaluatedParam) and
getValue(evaluatedParam, integer) <= 1 then
length := getValue(evaluatedParam, integer);
if length = 0 then
process_str_substr_fixlen0(params[1], params[3], c_expr);
elsif length = 1 then
process_str_substr_fixlen1(params[1], params[3], c_expr);
else
incr(countOptimizations);
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
end if;
elsif ccConf.ALLOW_STRITYPE_SLICES and c_expr.demand < REQUIRE_RESULT then
c_expr.expr &:= "(";
incr(c_expr.temp_num);
slice_name := "slice_" & str(c_expr.temp_num);
process_str_substr_fixlen_slice(params[1], params[3], params[5],
slice_name, c_expr);
c_expr.expr &:= ", &";
c_expr.expr &:= slice_name;
c_expr.expr &:= ")";
else
prepare_stri_result(c_expr);
c_expr.result_expr := "strSubstrFixLen(";
getAnyParamToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(params[3], c_expr);
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(params[5], c_expr);
c_expr.result_expr &:= ")";
end if;
end func;
const proc: process_inline_str_tail (in reference: stri,
in reference: start, in string: slice_name,
inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var string: stri_name is "";
var string: stri_value is "";
var string: stri_size is "";
var string: start_name is "";
var integer: start_value is 0;
var boolean: start_is_variable is TRUE;
var intRange: start_range is intRange.value;
var boolean: raisesIndexError is FALSE;
begin
if getConstant(stri, STRIOBJECT, evaluatedParam) then
stri_value := getValue(evaluatedParam, string);
stri_name := "(" & stringLiteral(stri_value) & ")";
stri_size := memSizeLiteral(length(stri_value));
else
stri_name := getParameterAsVariable("const_striType", "stri_", stri, c_expr);
stri_size := stri_name & "->size";
end if;
if getConstant(start, INTOBJECT, evaluatedParam) then
start_is_variable := FALSE;
start_value := getValue(evaluatedParam, integer);
if start_value < 1 then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= strRaiseError("INDEX_ERROR");
raisesIndexError := TRUE;
else
start_name := integerLiteral(start_value);
end if;
else
start_name := getTempVariable("intType", "start_", start, c_expr);
end if;
if not raisesIndexError then
if start_is_variable then
if string_index_check then
start_range := getIntRange(start);
if start_range.minValue < 1 then
incr(countIndexChecks);
c_expr.expr &:= "idxChk(";
c_expr.expr &:= start_name;
c_expr.expr &:= "<1";
c_expr.expr &:= ")?";
c_expr.expr &:= intRaiseError("INDEX_ERROR");
c_expr.expr &:= ":0, ";
else
countIndexOptimizations(c_expr);
end if;
else
incr(countSuppressedIndexChecks);
end if;
end if;
c_expr.expr &:= slice_name;
c_expr.expr &:= ".mem = &";
c_expr.expr &:= stri_name;
c_expr.expr &:= "->mem[";
if start_is_variable then
c_expr.expr &:= start_name;
c_expr.expr &:= "-1";
else
c_expr.expr &:= integerLiteral(pred(start_value));
end if;
c_expr.expr &:= "], (uintType)";
c_expr.expr &:= start_name;
c_expr.expr &:= "<=";
c_expr.expr &:= stri_size;
c_expr.expr &:= " && ";
c_expr.expr &:= stri_size;
c_expr.expr &:= ">=1 ?";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".size = ";
c_expr.expr &:= stri_size;
c_expr.expr &:= " - (memSizeType)";
c_expr.expr &:= start_name;
c_expr.expr &:= " + 1 : (";
c_expr.expr &:= slice_name;
c_expr.expr &:= ".size = 0)";
end if;
end func;
const proc: process (STR_TAIL, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var string: slice_name is "";
begin
if getConstant(params[1], STRIOBJECT, evaluatedParam) and
getValue(evaluatedParam, string) = "" then
incr(countOptimizations);
c_expr.expr &:= "/* \"\"[n .. ] */ (";
if string_index_check then
incr(countIndexChecks);
c_expr.expr &:= "idxChk((";
process_expr(params[3], c_expr);
c_expr.expr &:= ")<1)?";
c_expr.expr &:= strRaiseError("INDEX_ERROR");
c_expr.expr &:= ":";
else
incr(countSuppressedIndexChecks);
end if;
c_expr.expr &:= stringLiteral("");
c_expr.expr &:= ")";
elsif ccConf.ALLOW_STRITYPE_SLICES and c_expr.demand < ASSIGN_RESULT then
c_expr.expr &:= "(";
incr(c_expr.temp_num);
slice_name := "slice_" & str(c_expr.temp_num);
c_expr.temp_decls &:= "struct striStruct ";
c_expr.temp_decls &:= slice_name;
c_expr.temp_decls &:= ";\n";
if inlineFunctions then
incr(countInlinedFunctions);
process_inline_str_tail(params[1], params[3], slice_name, c_expr);
else
c_expr.expr &:= "strTailSlice(";
getAnyParamToExpr(params[1], c_expr);
c_expr.expr &:= ", ";
process_expr(params[3], c_expr);
c_expr.expr &:= ", &";
c_expr.expr &:= slice_name;
c_expr.expr &:= ")";
end if;
c_expr.expr &:= ", &";
c_expr.expr &:= slice_name;
c_expr.expr &:= ")";
else
prepare_stri_result(c_expr);
c_expr.result_expr := "strTail(";
getAnyParamToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(params[3], c_expr);
c_expr.result_expr &:= ")";
end if;
end func;
const proc: process (STR_TO_UTF8, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
prepare_stri_result(c_expr);
c_expr.result_expr := "strToUtf8(";
getAnyParamToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ")";
end func;
const proc: process (STR_TRIM, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
prepare_stri_result(c_expr);
c_expr.result_expr := "strTrim(";
getAnyParamToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ")";
end func;
const proc: process (STR_UP, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var expr_type: c_param1 is expr_type.value;
begin
prepare_stri_result(c_expr);
prepareAnyParamTemporarys(params[1], c_param1, c_expr);
if c_param1.result_expr <> "" then
c_expr.result_expr := "strUpTemp(";
c_expr.result_expr &:= c_param1.result_expr;
else
c_expr.result_expr := "strUp(";
c_expr.result_expr &:= c_param1.expr;
end if;
c_expr.result_expr &:= ")";
end func;
const proc: process (STR_VALUE, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
prepare_stri_result(c_expr);
c_expr.result_expr := "strValue(";
getStdParamToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ")";
end func;