const ACTION: ARR_APPEND is action "ARR_APPEND";
const ACTION: ARR_ARRLIT is action "ARR_ARRLIT";
const ACTION: ARR_ARRLIT2 is action "ARR_ARRLIT2";
const ACTION: ARR_BASELIT is action "ARR_BASELIT";
const ACTION: ARR_BASELIT2 is action "ARR_BASELIT2";
const ACTION: ARR_CAT is action "ARR_CAT";
const ACTION: ARR_CONV is action "ARR_CONV";
const ACTION: ARR_CPY is action "ARR_CPY";
const ACTION: ARR_CREATE is action "ARR_CREATE";
const ACTION: ARR_DESTR is action "ARR_DESTR";
const ACTION: ARR_EXTEND is action "ARR_EXTEND";
const ACTION: ARR_GEN is action "ARR_GEN";
const ACTION: ARR_HEAD is action "ARR_HEAD";
const ACTION: ARR_IDX is action "ARR_IDX";
const ACTION: ARR_INSERT is action "ARR_INSERT";
const ACTION: ARR_INSERT_ARRAY is action "ARR_INSERT_ARRAY";
const ACTION: ARR_LNG is action "ARR_LNG";
const ACTION: ARR_MAXIDX is action "ARR_MAXIDX";
const ACTION: ARR_MINIDX is action "ARR_MINIDX";
const ACTION: ARR_PUSH is action "ARR_PUSH";
const ACTION: ARR_RANGE is action "ARR_RANGE";
const ACTION: ARR_REMOVE is action "ARR_REMOVE";
const ACTION: ARR_REMOVE_ARRAY is action "ARR_REMOVE_ARRAY";
const ACTION: ARR_SORT is action "ARR_SORT";
const ACTION: ARR_SORT_REVERSE is action "ARR_SORT_REVERSE";
const ACTION: ARR_SUBARR is action "ARR_SUBARR";
const ACTION: ARR_TAIL is action "ARR_TAIL";
const ACTION: ARR_TIMES is action "ARR_TIMES";
var boolean_type_hash: times_prototype_declared is boolean_type_hash.EMPTY_HASH;
const proc: arr_prototypes (inout file: c_prog) is func
begin
declareExtern(c_prog, "void arrAppend (arrayType *const, const arrayType);");
declareExtern(c_prog, "arrayType arrArrlit2 (intType, arrayType);");
declareExtern(c_prog, "arrayType arrBaselit (const genericType);");
declareExtern(c_prog, "arrayType arrBaselit2 (intType, const genericType);");
declareExtern(c_prog, "arrayType arrCat (arrayType, const arrayType);");
declareExtern(c_prog, "arrayType arrExtend (arrayType, const genericType);");
declareExtern(c_prog, "void arrFree (arrayType);");
declareExtern(c_prog, "arrayType arrGen (const genericType, const genericType);");
declareExtern(c_prog, "arrayType arrHead (const const_arrayType, intType);");
declareExtern(c_prog, "arrayType arrHeadTemp (arrayType *, intType);");
declareExtern(c_prog, "genericType arrIdxTemp (arrayType *, intType);");
declareExtern(c_prog, "void arrInsert (arrayType *, intType, genericType);");
declareExtern(c_prog, "void arrInsertArray (arrayType *, intType, arrayType);");
declareExtern(c_prog, "void arrInsertArrayTemp (arrayType *, intType, arrayType);");
declareExtern(c_prog, "arrayType arrMalloc (intType, intType);");
declareExtern(c_prog, "void arrPush (arrayType *const, const genericType);");
declareExtern(c_prog, "arrayType arrRange (const const_arrayType, intType, intType);");
declareExtern(c_prog, "arrayType arrRangeTemp (arrayType *, intType, intType);");
declareExtern(c_prog, "arrayType arrRealloc (arrayType, memSizeType, memSizeType);");
declareExtern(c_prog, "genericType arrRemove (arrayType *, intType);");
declareExtern(c_prog, "arrayType arrRemoveArray (arrayType *, intType, intType);");
declareExtern(c_prog, "arrayType arrSort (arrayType, compareType);");
declareExtern(c_prog, "arrayType arrSortReverse (arrayType, compareType);");
declareExtern(c_prog, "arrayType arrSubarr (const const_arrayType, intType, intType);");
declareExtern(c_prog, "arrayType arrSubarrTemp (arrayType *, intType, intType);");
declareExtern(c_prog, "arrayType arrTail (const const_arrayType, intType);");
declareExtern(c_prog, "arrayType arrTailTemp (arrayType *, intType);");
declareExtern(c_prog, "arrayType arrTimes (intType, intType, const genericType);");
end func;
const proc: declare_times_prototype (in type: arrayType,
inout expr_type: c_expr) is func
local
var type: elementType is void;
begin
if arrayType not in times_prototype_declared then
elementType := array_element[arrayType];
process_create_declaration(elementType, c_expr);
c_expr.expr &:= "static arrayType times_";
c_expr.expr &:= str(typeNumber(arrayType));
c_expr.expr &:= " (intType, const ";
if useConstPrefix(elementType) then
c_expr.expr &:= "const_";
end if;
c_expr.expr &:= type_name(elementType);
c_expr.expr &:= ");\n\n";
times_prototype_declared @:= [arrayType] TRUE;
end if;
end func;
const proc: process_arr_append (in reference: param1, in reference: param3,
inout expr_type: c_expr) is func
local
var expr_type: c_param1 is expr_type.value;
var expr_type: c_param3 is expr_type.value;
begin
process_expr(param1, c_param1);
c_param3.temp_num := c_param1.temp_num;
getTemporaryToResultExpr(param3, c_param3);
incr(c_param3.temp_num);
if has_temp_values(c_param3) then
c_expr.expr &:= "{\n";
appendWithDiagnostic(c_param1.temp_decls, c_expr);
appendWithDiagnostic(c_param3.temp_decls, c_expr);
appendWithDiagnostic(c_param1.temp_assigns, c_expr);
appendWithDiagnostic(c_param3.temp_assigns, c_expr);
end if;
setDiagnosticLine(c_expr);
c_expr.expr &:= "arrAppend(&(";
c_expr.expr &:= c_param1.expr;
c_expr.expr &:= "), ";
c_expr.expr &:= c_param3.result_expr;
c_expr.expr &:= ");\n";
if has_temp_values(c_param3) then
appendWithDiagnostic(c_param1.temp_frees, c_expr);
appendWithDiagnostic(c_param3.temp_frees, c_expr);
c_expr.expr &:= "}\n";
end if;
end func;
const proc: process (ARR_APPEND, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
process_arr_append(params[1], params[3], c_expr);
end func;
const proc: process (ARR_ARRLIT, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: anArray is NIL;
var expr_type: c_param is expr_type.value;
begin
if isConstant(params[3]) then
anArray := evaluate(prog, params[3]);
if category(anArray) = ARRAYOBJECT then
if anArray not in const_table then
const_table @:= [anArray] length(const_table);
end if;
c_expr.expr &:= "arr[";
c_expr.expr &:= str(const_table[anArray]);
c_expr.expr &:= "]";
end if;
else
prepareAnyParamTemporarys(params[3], c_param, c_expr);
if c_param.result_expr <> "" then
prepare_typed_result(getExprResultType(params[3]), c_expr);
c_expr.result_expr := "/*arrArrlit()*/";
c_expr.result_expr &:= c_param.result_expr;
else
c_expr.expr &:= "/*arrArrlit()*/";
c_expr.expr &:= c_param.expr;
end if;
end if;
end func;
const proc: process (ARR_ARRLIT2, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
prepare_typed_result(getExprResultType(params[4]), c_expr);
c_expr.result_expr := "arrArrlit2(";
getStdParamToResultExpr(params[2], c_expr);
c_expr.result_expr &:= ", ";
getTemporaryToResultExpr(params[4], c_expr);
c_expr.result_expr &:= ")";
end func;
const proc: process (ARR_BASELIT, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
if resultType(getType(function)) not in array_element then
array_element @:= [resultType(getType(function))] getType(params[3]);
end if;
prepare_typed_result(resultType(getType(function)), c_expr);
c_expr.result_expr := "arrBaselit((genericType)(";
getGenericTemporaryToResultExpr(params[3], c_expr);
c_expr.result_expr &:= "))";
end func;
const proc: process (ARR_BASELIT2, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
if resultType(getType(function)) not in array_element then
array_element @:= [resultType(getType(function))] getType(params[4]);
end if;
prepare_typed_result(resultType(getType(function)), c_expr);
c_expr.result_expr := "arrBaselit2(";
getStdParamToResultExpr(params[2], c_expr);
c_expr.result_expr &:= ", (genericType)(";
getGenericTemporaryToResultExpr(params[4], c_expr);
c_expr.result_expr &:= "))";
end func;
const proc: process (ARR_CAT, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
prepare_typed_result(getExprResultType(params[1]), c_expr);
c_expr.result_expr := "arrCat(";
getTemporaryToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ", ";
getTemporaryToResultExpr(params[3], c_expr);
c_expr.result_expr &:= ")";
end func;
const proc: process (ARR_CONV, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var expr_type: c_param is expr_type.value;
begin
prepareAnyParamTemporarys(params[3], c_param, c_expr);
if c_param.result_expr <> "" then
prepare_typed_result(getExprResultType(params[3]), c_expr);
c_expr.result_expr := "/*arrConv()*/";
c_expr.result_expr &:= c_param.result_expr;
else
c_expr.expr &:= "/*arrConv()*/";
c_expr.expr &:= c_param.expr;
end if;
end func;
const func boolean: isIntArrayOfZeros (in reference: arr) is func
result
var boolean: isIntArrayOfZeros is FALSE;
local
var type: arrayType is void;
var type: elementType is void;
var ref_list: arrayList is ref_list.EMPTY;
var reference: element is NIL;
var integer: elementValue is 0;
begin
arrayType := getExprResultType(arr);
elementType := array_element[arrayType];
if elementType in typeCategory and typeCategory[elementType] = INTOBJECT then
arrayList := arrayToList(arr);
isIntArrayOfZeros := TRUE;
for element range arrayList until not isIntArrayOfZeros do
elementValue := getValue(element, integer);
if elementValue <> 0 then
isIntArrayOfZeros := FALSE;
end if;
end for;
end if;
end func;
const proc: process_arr_cpy_times_optimization (in reference: dest,
in reference: factor, 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 intRange: factorRange is intRange.value;
var string: factorName is "";
begin
writeln("process_arr_cpy_times_optimization A " <& c_expr.currentFile <& "(" <& c_expr.currentLine <& ")");
statement.temp_num := c_expr.temp_num;
prepareAnyParamTemporarys(dest, c_param1, statement);
statement.expr &:= "(";
factorName := getParameterAsVariable("intType", "factor_", factor, statement);
if function_range_check then
factorRange := getIntRange(factor);
if factorRange.minValue < 0 then
statement.expr &:= "(rngChk((";
statement.expr &:= factorName;
statement.expr &:= ") < 0)?";
statement.expr &:= intRaiseError("RANGE_ERROR");
statement.expr &:= ":0),\n";
else
countRangeOptimizations(statement);
end if;
else
incr(countNoRangeChecks);
end if;
if isNormalVariable(dest) then
statement.temp_decls &:= "memSizeType size_a = (uintType)((";
statement.temp_decls &:= c_param1.expr;
statement.temp_decls &:= ")->max_position - (";
statement.temp_decls &:= c_param1.expr;
statement.temp_decls &:= ")->min_position + 1);\n";
statement.expr &:= "(size_a != (uintType)(";
statement.expr &:= factorName;
statement.expr &:= ")?";
statement.expr &:= c_param1.expr;
statement.expr &:= "=(arrayType)(arrRealloc(";
statement.expr &:= c_param1.expr;
statement.expr &:= ", size_a, ";
statement.expr &:= factorName;
statement.expr &:= ")):0),\n";
statement.expr &:= "memset((";
statement.expr &:= c_param1.expr;
statement.expr &:= ")->arr, 0, ";
statement.expr &:= factorName;
statement.expr &:= " * sizeof(rtlObjectType)),\n";
statement.expr &:= "(";
statement.expr &:= c_param1.expr;
statement.expr &:= ")->min_position = 1,\n";
statement.expr &:= "(";
statement.expr &:= c_param1.expr;
statement.expr &:= ")->max_position = ";
else
statement.temp_decls &:= "arrayType *array_ptr=&(";
statement.temp_decls &:= c_param1.expr;
statement.temp_decls &:= ");\n";
statement.temp_decls &:= "memSizeType size_a = (uintType)((*array_ptr)->max_position - (*array_ptr)->min_position + 1);\n";
statement.expr &:= "(size_a != (uintType)(";
statement.expr &:= factorName;
statement.expr &:= ")?\n";
statement.expr &:= "*array_ptr=(arrayType)(arrRealloc(*array_ptr, size_a, ";
statement.expr &:= factorName;
statement.expr &:= ")):0),\n";
statement.expr &:= "memset((*array_ptr)->arr, 0, ";
statement.expr &:= factorName;
statement.expr &:= " * sizeof(rtlObjectType)),\n";
statement.expr &:= "(*array_ptr)->min_position = 1,\n";
statement.expr &:= "(*array_ptr)->max_position = ";
end if;
statement.expr &:= factorName;
statement.expr &:= ");\n";
doLocalDeclsOfStatement(statement, c_expr);
end func;
const proc: process_arr_cpy_times_optimization (in reference: dest,
in integer: minIdx, in reference: maxIdx, inout expr_type: c_expr) is func
local
var type: arrayType is void;
var expr_type: statement is expr_type.value;
var expr_type: c_param1 is expr_type.value;
var intRange: maxIdxRange is intRange.value;
var string: maxIdxName is "";
var string: factorName is "";
begin
writeln("process_arr_cpy_times_optimization B " <& c_expr.currentFile <& "(" <& c_expr.currentLine <& "): " <& minIdx);
arrayType := getExprResultType(dest);
statement.temp_num := c_expr.temp_num;
prepareAnyParamTemporarys(dest, c_param1, statement);
statement.expr &:= "(";
maxIdxName := getParameterAsVariable("intType", "maxIdx_", maxIdx, statement);
factorName := defineTempVariable("intType", "factor_", statement);
statement.expr &:= factorName;
statement.expr &:= "=";
statement.expr &:= maxIdxName;
if minIdx > 1 then
statement.expr &:= "- ";
statement.expr &:= integerLiteral(pred(minIdx));
elsif minIdx <= succ(integer.first) then
statement.expr &:= "- ";
statement.expr &:= integerLiteral(minIdx);
statement.expr &:= ";\n";
statement.expr &:= factorName;
statement.expr &:= "++";
elsif minIdx < 1 then
statement.expr &:= "+ ";
statement.expr &:= integerLiteral(succ(-minIdx));
end if;
statement.expr &:= ", ";
if function_range_check then
maxIdxRange := getIntRange(maxIdx);
if maxIdxRange.maxValue < pred(minIdx) then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
statement.expr &:= intRaiseError("RANGE_ERROR");
statement.expr &:= ",\n";
elsif maxIdxRange.minValue < pred(minIdx) then
statement.expr &:= "(rngChk((";
statement.expr &:= factorName;
statement.expr &:= ") < 0)?";
statement.expr &:= intRaiseError("RANGE_ERROR");
statement.expr &:= ":0),\n";
else
countRangeOptimizations(statement);
end if;
else
incr(countNoRangeChecks);
end if;
if isNormalVariable(dest) then
statement.expr &:= "(";
statement.expr &:= c_param1.expr;
statement.expr &:= ")->max_position != ";
statement.expr &:= maxIdxName;
statement.expr &:= "?\n(";
process_destr_declaration(arrayType, global_c_expr);
statement.expr &:= "destr_";
statement.expr &:= str(typeNumber(arrayType));
statement.expr &:= "(";
statement.expr &:= c_param1.expr;
statement.expr &:= "),";
statement.expr &:= c_param1.expr;
statement.expr &:= "=arrMalloc(";
statement.expr &:= integerLiteral(minIdx);
statement.expr &:= ", ";
statement.expr &:= maxIdxName;
statement.expr &:= ")):0,\nmemset((";
statement.expr &:= c_param1.expr;
statement.expr &:= ")->arr, 0, ";
statement.expr &:= factorName;
statement.expr &:= " * sizeof(rtlObjectType)));\n";
else
statement.temp_decls &:= "arrayType *array_ptr=&(";
statement.temp_decls &:= c_param1.expr;
statement.temp_decls &:= ");\n";
statement.expr &:= "(*array_ptr)->max_position != ";
statement.expr &:= maxIdxName;
statement.expr &:= "?\n(";
process_destr_declaration(arrayType, global_c_expr);
statement.expr &:= "destr_";
statement.expr &:= str(typeNumber(arrayType));
statement.expr &:= "(*array_ptr),*array_ptr=arrMalloc(";
statement.expr &:= integerLiteral(minIdx);
statement.expr &:= ", ";
statement.expr &:= maxIdxName;
statement.expr &:= ")):0,\nmemset((*array_ptr)->arr, 0, ";
statement.expr &:= factorName;
statement.expr &:= " * sizeof(rtlObjectType)));\n";
end if;
doLocalDeclsOfStatement(statement, c_expr);
end func;
const proc: process_arr_cpy_array_of_zeros (in reference: dest,
in integer: minPosition, in integer: maxPosition, inout expr_type: c_expr) is func
local
var integer: arraySize is 0;
var type: arrayType is void;
var expr_type: statement is expr_type.value;
var expr_type: c_param1 is expr_type.value;
begin
arraySize := succ(maxPosition - minPosition);
statement.temp_num := c_expr.temp_num;
prepareAnyParamTemporarys(dest, c_param1, statement);
statement.expr &:= "(";
arrayType := getExprResultType(dest);
if isNormalVariable(dest) then
if arrayType not in array_minIdx or arrayType not in array_maxIdx or
minPosition <> array_minIdx[arrayType] and
maxPosition <> array_maxIdx[arrayType] then
statement.temp_decls &:= "memSizeType size_a = (uintType)((";
statement.temp_decls &:= c_param1.expr;
statement.temp_decls &:= ")->max_position - (";
statement.temp_decls &:= c_param1.expr;
statement.temp_decls &:= ")->min_position + 1);\n";
statement.expr &:= "(size_a != (uintType)(";
statement.expr &:= integerLiteral(arraySize);
statement.expr &:= ")?";
statement.expr &:= c_param1.expr;
statement.expr &:= "=(arrayType)(arrRealloc(";
statement.expr &:= c_param1.expr;
statement.expr &:= ", size_a, ";
statement.expr &:= integerLiteral(arraySize);
statement.expr &:= ")):0),\n";
statement.expr &:= "memset((";
statement.expr &:= c_param1.expr;
statement.expr &:= ")->arr, 0, ";
statement.expr &:= integerLiteral(arraySize);
statement.expr &:= " * sizeof(rtlObjectType)),\n";
statement.expr &:= "(";
statement.expr &:= c_param1.expr;
statement.expr &:= ")->min_position = ";
statement.expr &:= integerLiteral(minPosition);
statement.expr &:= ",\n";
statement.expr &:= "(";
statement.expr &:= c_param1.expr;
statement.expr &:= ")->max_position = ";
statement.expr &:= integerLiteral(maxPosition);
else
statement.expr &:= "memset((";
statement.expr &:= c_param1.expr;
statement.expr &:= ")->arr, 0, ";
statement.expr &:= integerLiteral(arraySize);
statement.expr &:= " * sizeof(rtlObjectType))";
end if;
else
statement.temp_decls &:= "arrayType *array_ptr=&(";
statement.temp_decls &:= c_param1.expr;
statement.temp_decls &:= ");\n";
if arrayType not in array_minIdx or arrayType not in array_maxIdx or
minPosition <> array_minIdx[arrayType] and
maxPosition <> array_maxIdx[arrayType] then
statement.temp_decls &:= "memSizeType size_a = (uintType)((*array_ptr)->max_position - (*array_ptr)->min_position + 1);\n";
statement.expr &:= "(size_a != (uintType)(";
statement.expr &:= integerLiteral(arraySize);
statement.expr &:= ")?\n";
statement.expr &:= "*array_ptr=(arrayType)(arrRealloc(*array_ptr, size_a, ";
statement.expr &:= integerLiteral(arraySize);
statement.expr &:= ")):0),\n";
statement.expr &:= "memset((*array_ptr)->arr, 0, ";
statement.expr &:= integerLiteral(arraySize);
statement.expr &:= " * sizeof(rtlObjectType)),\n";
statement.expr &:= "(*array_ptr)->min_position = ";
statement.expr &:= integerLiteral(minPosition);
statement.expr &:= ",\n";
statement.expr &:= "(*array_ptr)->max_position = ";
statement.expr &:= integerLiteral(maxPosition);
else
statement.expr &:= "memset((*array_ptr)->arr, 0, ";
statement.expr &:= integerLiteral(arraySize);
statement.expr &:= " * sizeof(rtlObjectType))";
end if;
end if;
statement.expr &:= ");\n";
doLocalDeclsOfStatement(statement, c_expr);
end func;
const func boolean: isFixedMinIdxTimes (in reference: aParam) is func
result
var boolean: isFixedMinIdxTimes is FALSE;
local
var type: arrayType is void;
var reference: timesBody is NIL;
var reference: timesExpression is NIL;
begin
arrayType := getExprResultType(aParam);
if arrayType in array_minIdx and
category(aParam) = CALLOBJECT and
length(getValue(aParam, ref_list)) >= 4 and
str(getActionParameter(aParam, 2)) = "times" and
category(getValue(aParam, ref_list)[1]) = BLOCKOBJECT then
timesBody := body(getValue(aParam, ref_list)[1]);
if isActionExpression(timesBody, "ARR_ARRLIT2") then
timesExpression := getActionParameter(timesBody, 4);
if isActionExpression(timesExpression, "ARR_TIMES") then
isFixedMinIdxTimes := TRUE;
end if;
end if;
end if;
end func;
const proc: two_dimensional_times_optimization (in reference: dest,
in integer: minIdx1, in reference: maxIdx1, in integer: minIdx2, in reference: maxIdx2,
inout expr_type: c_expr) is func
local
var type: arrayType is void;
var string: maxIdx1Name is "";
var string: maxIdx2Name is "";
var string: resultName is "";
var expr_type: statement is expr_type.value;
var expr_type: c_param1 is expr_type.value;
begin
incr(countOptimizations);
arrayType := getExprResultType(dest);
writeln("two_dimensional_times_optimization " <& c_expr.currentFile <& "(" <& c_expr.currentLine <& "):" <& minIdx1 <& " " <& minIdx2);
statement.temp_num := c_expr.temp_num;
prepareAnyParamTemporarys(dest, c_param1, statement);
maxIdx1Name := defineTempVariable("intType", "maxIdx1_", statement);
if isNormalVariable(maxIdx2) then
maxIdx2Name := normalVariable(maxIdx2, statement);
else
maxIdx2Name := defineTempVariable("intType", "maxIdx2_", statement);
end if;
statement.expr &:= maxIdx1Name;
statement.expr &:= "=(";
process_expr(maxIdx1, statement);
statement.expr &:= ");\n";
if not isNormalVariable(maxIdx2) then
statement.expr &:= maxIdx2Name;
statement.expr &:= "=(";
process_expr(maxIdx2, statement);
statement.expr &:= ");\n";
end if;
if isNormalVariable(dest) then
resultName := "(" & c_param1.expr & ")";
else
statement.temp_decls &:= "arrayType *array_ptr=&(";
statement.temp_decls &:= c_param1.expr;
statement.temp_decls &:= ");\n";
resultName := "(*array_ptr)";
end if;
process_destr_declaration(arrayType, global_c_expr);
process_destr_call(arrayType, resultName, statement.expr);
statement.expr &:= resultName;
statement.expr &:= "=arrMalloc(";
statement.expr &:= integerLiteral(minIdx1);
statement.expr &:= ", ";
statement.expr &:= maxIdx1Name;
statement.expr &:= ");\n";
if minIdx1 > 1 then
statement.expr &:= maxIdx1Name;
statement.expr &:= "-= ";
statement.expr &:= integerLiteral(pred(minIdx1));
statement.expr &:= ";\n";
elsif minIdx1 <= succ(integer.first) then
statement.expr &:= maxIdx1Name;
statement.expr &:= "-= ";
statement.expr &:= integerLiteral(minIdx1);
statement.expr &:= ";\n";
statement.expr &:= maxIdx1Name;
statement.expr &:= "++;\n";
elsif minIdx1 < 1 then
statement.expr &:= maxIdx1Name;
statement.expr &:= "+= ";
statement.expr &:= integerLiteral(succ(-minIdx1));
statement.expr &:= ";\n";
end if;
statement.expr &:= "while (";
statement.expr &:= maxIdx1Name;
statement.expr &:= "!=0) {\n";
statement.expr &:= maxIdx1Name;
statement.expr &:= "--;\n";
statement.expr &:= resultName;
statement.expr &:= "->arr[";
statement.expr &:= maxIdx1Name;
statement.expr &:= "].value.arrayValue=arrTimes(";
statement.expr &:= integerLiteral(minIdx2);
statement.expr &:= ", ";
statement.expr &:= maxIdx2Name;
statement.expr &:= ", 0);\n";
statement.expr &:= "}\n";
doLocalDeclsOfStatement(statement, c_expr);
end func;
const proc: process (ARR_CPY, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var type: arrayType is void;
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
arrayType := getExprResultType(params[1]);
if isActionExpression(params[3], "ARR_CAT") and
getActionParameter(params[3], 1) = params[1] then
process_arr_append(params[1], getActionParameter(params[3], 3), c_expr);
elsif inlineFunctions and
isActionExpression(params[3], "ARR_TIMES") and
getConstant(getActionParameter(params[3], 3), INTOBJECT, evaluatedParam) and
getValue(evaluatedParam, integer) = 0 then
process_arr_cpy_times_optimization(params[1],
getActionParameter(params[3], 1), c_expr);
elsif inlineFunctions and
getConstant(params[3], ARRAYOBJECT, evaluatedParam) and
isIntArrayOfZeros(evaluatedParam) then
process_arr_cpy_array_of_zeros(params[1],
arrayMinIdx(evaluatedParam), arrayMaxIdx(evaluatedParam), c_expr);
elsif isFixedMinIdxTimes(params[3]) and
isFixedMinIdxTimes(getActionParameter(params[3], 3)) and
getConstant(getActionParameter(getActionParameter(params[3], 3), 3), INTOBJECT, evaluatedParam) and
getValue(evaluatedParam, integer) = 0 then
two_dimensional_times_optimization(params[1],
array_minIdx[arrayType], getActionParameter(params[3], 1),
array_minIdx[getExprResultType(getActionParameter(params[3], 3))],
getActionParameter(getActionParameter(params[3], 3), 1), c_expr);
else
if isFixedMinIdxTimes(params[3]) and
getConstant(getActionParameter(params[3], 3), INTOBJECT, evaluatedParam) and
getValue(evaluatedParam, integer) = 0 then
writeln("process_arr_cpy_times_optimization " <& c_expr.currentFile <& "(" <& c_expr.currentLine <& "): " <& array_minIdx[arrayType]);
end if;
if isFixedMinIdxTimes(params[3]) and
isFixedMinIdxTimes(getActionParameter(params[3], 3)) and
getConstant(getActionParameter(getActionParameter(params[3], 3), 3), INTOBJECT, evaluatedParam) and
getValue(evaluatedParam, integer) = 0 then
writeln("two_dimensional_arr_cpy_times " <& c_expr.currentFile <& "(" <& c_expr.currentLine <& "):" <& array_minIdx[arrayType] <& " " <& array_minIdx[getExprResultType(getActionParameter(params[3], 3))]);
end if;
statement.temp_num := c_expr.temp_num;
prepareAnyParamTemporarys(params[1], c_param1, statement);
c_param3.demand := ASSIGN_RESULT;
prepareAnyParamTemporarys(params[3], c_param3, statement);
if c_param3.result_expr <> "" then
statement.temp_decls &:= "arrayType new_array;\n";
statement.expr &:= "new_array=";
statement.expr &:= c_param3.result_expr;
statement.expr &:= ";\n";
process_destr_declaration(arrayType, global_c_expr);
if isNormalVariable(params[1]) then
process_destr_call(arrayType, c_param1.expr, statement.expr);
statement.expr &:= c_param1.expr;
statement.expr &:= "=new_array;\n";
else
statement.temp_decls &:= "arrayType *array_ptr=&(";
statement.temp_decls &:= c_param1.expr;
statement.temp_decls &:= ");\n";
process_destr_call(arrayType, "*array_ptr", statement.expr);
statement.expr &:= "*array_ptr=new_array;\n";
end if;
else
process_cpy_declaration(arrayType, global_c_expr);
process_cpy_call(arrayType, c_param1.expr, c_param3.expr,
statement.expr);
statement.expr &:= ";\n";
end if;
doLocalDeclsOfStatement(statement, c_expr);
end if;
end func;
const proc: process (ARR_CREATE, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var type: param_type is void;
begin
param_type := getExprResultType(params[3]);
typeCategory @:= [param_type] ARRAYOBJECT;
process_create_declaration(param_type, global_c_expr);
process_expr(params[1], c_expr);
c_expr.expr &:= "=create_";
c_expr.expr &:= str(typeNumber(param_type));
c_expr.expr &:= "(";
process_expr(params[3], c_expr);
c_expr.expr &:= ");\n";
end func;
const proc: process (ARR_DESTR, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var type: param_type is void;
begin
param_type := getExprResultType(params[1]);
process_destr_declaration(param_type, global_c_expr);
c_expr.expr &:= "destr_";
c_expr.expr &:= str(typeNumber(param_type));
c_expr.expr &:= "(";
process_expr(params[1], c_expr);
c_expr.expr &:= ");\n";
end func;
const proc: process (ARR_EXTEND, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
prepare_typed_result(getExprResultType(params[1]), c_expr);
c_expr.result_expr := "arrExtend(";
getTemporaryToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ", (genericType)(";
getGenericTemporaryToResultExpr(params[3], c_expr);
c_expr.result_expr &:= "))";
end func;
const proc: process (ARR_GEN, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
prepare_typed_result(resultType(getType(function)), c_expr);
c_expr.result_expr := "arrGen((genericType)(";
getGenericTemporaryToResultExpr(params[1], c_expr);
c_expr.result_expr &:= "), (genericType)(";
getGenericTemporaryToResultExpr(params[3], c_expr);
c_expr.result_expr &:= "))";
end func;
const proc: process (ARR_HEAD, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var type: param_type is void;
var expr_type: c_param is expr_type.value;
var string: array_name is "";
begin
param_type := getExprResultType(params[1]);
prepare_typed_result(param_type, c_expr);
prepareAnyParamTemporarys(params[1], c_param, c_expr);
if c_param.result_expr <> "" then
c_expr.temp_decls &:= c_param.result_decl;
c_expr.temp_frees &:= c_param.result_free;
c_expr.temp_to_null &:= c_param.result_to_null;
c_expr.result_expr := "(";
c_expr.result_expr &:= c_param.result_intro;
c_expr.result_expr &:= c_param.result_expr;
c_expr.result_expr &:= c_param.result_finish;
c_expr.result_expr &:= ", arrHeadTemp(&(";
c_expr.result_expr &:= c_param.result_name;
c_expr.result_expr &:= "), ";
getStdParamToResultExpr(params[4], c_expr);
c_expr.result_expr &:= "))";
elsif valueIsAtHeap(array_element[param_type]) then
incr(c_expr.temp_num);
array_name := "tmp_" & str(c_expr.temp_num);
c_expr.temp_decls &:= "arrayType ";
c_expr.temp_decls &:= array_name;
c_expr.temp_decls &:= "=NULL;\n";
c_expr.temp_frees &:= "if (";
c_expr.temp_frees &:= array_name;
c_expr.temp_frees &:= " != NULL) {arrFree(";
c_expr.temp_frees &:= array_name;
c_expr.temp_frees &:= ");}\n";
c_expr.temp_to_null &:= array_name;
c_expr.temp_to_null &:= "=NULL;\n";
c_expr.result_expr := "(";
c_expr.result_expr &:= array_name;
c_expr.result_expr &:= "=arrHead(";
c_expr.result_expr &:= c_param.expr;
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(params[4], c_expr);
c_expr.result_expr &:= "), ";
typeCategory @:= [param_type] ARRAYOBJECT;
process_create_declaration(param_type, global_c_expr);
process_create_call(param_type, array_name, c_expr.result_expr);
c_expr.result_expr &:= ")";
else
c_expr.result_expr := "arrHead(";
c_expr.result_expr &:= c_param.expr;
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(params[4], c_expr);
c_expr.result_expr &:= ")";
end if;
end func;
const proc: process_const_arr_idx (in reference: function, in reference: anArray,
in reference: index, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var integer: index_value is 0;
var intRange: indexRange is intRange.value;
var string: index_name is "";
begin
incr(countOptimizations);
if anArray not in const_table then
const_table @:= [anArray] length(const_table);
end if;
if getConstant(index, INTOBJECT, evaluatedParam) then
index_value := getValue(evaluatedParam, integer);
if index_value < arrayMinIdx(anArray) or index_value > arrayMaxIdx(anArray) then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= "(";
c_expr.expr &:= type_name(resultType(getType(function)));
c_expr.expr &:= ")(raiseError(INDEX_ERROR), 0)";
else
c_expr.expr &:= "arr[";
c_expr.expr &:= str(const_table[anArray]);
c_expr.expr &:= "]->arr[";
c_expr.expr &:= str(index_value - arrayMinIdx(anArray));
c_expr.expr &:= "]";
c_expr.expr &:= select_value_from_rtlObjectStruct(resultType(getType(function)));
end if;
else
indexRange := getIntRange(index);
if indexRange.maxValue < arrayMinIdx(anArray) or
indexRange.minValue > arrayMaxIdx(anArray) then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= "(";
c_expr.expr &:= type_name(resultType(getType(function)));
c_expr.expr &:= ")(raiseError(INDEX_ERROR), 0)";
else
c_expr.expr &:= "arr[";
c_expr.expr &:= str(const_table[anArray]);
c_expr.expr &:= "]->arr[";
if array_index_check then
if indexRange.minValue < arrayMinIdx(anArray) or
indexRange.maxValue > arrayMaxIdx(anArray) 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 &:= "=(";
process_expr(index, c_expr);
c_expr.expr &:= ")";
if arrayMinIdx(anArray) <> 0 then
if ccConf.TWOS_COMPLEMENT_INTTYPE then
c_expr.expr &:= "- (uintType) ";
else
c_expr.expr &:= "- ";
end if;
c_expr.expr &:= integerLiteral(arrayMinIdx(anArray));
end if;
c_expr.expr &:= ", idxChk(";
if not ccConf.TWOS_COMPLEMENT_INTTYPE then
c_expr.expr &:= index_name;
c_expr.expr &:= "<0 || ";
end if;
c_expr.expr &:= index_name;
c_expr.expr &:= ">=";
c_expr.expr &:= integerLiteral(arrayLength(anArray));
c_expr.expr &:= ") ? ";
c_expr.expr &:= intRaiseError("INDEX_ERROR");
c_expr.expr &:= " : ";
c_expr.expr &:= index_name;
c_expr.expr &:= ")";
else
countIndexOptimizations(c_expr);
c_expr.expr &:= "(";
process_expr(index, c_expr);
c_expr.expr &:= ")";
if arrayMinIdx(anArray) <> 0 then
c_expr.expr &:= "- ";
c_expr.expr &:= integerLiteral(arrayMinIdx(anArray));
end if;
end if;
else
incr(countSuppressedIndexChecks);
c_expr.expr &:= "(";
process_expr(index, c_expr);
c_expr.expr &:= ")";
if arrayMinIdx(anArray) <> 0 then
c_expr.expr &:= "- ";
c_expr.expr &:= integerLiteral(arrayMinIdx(anArray));
end if;
end if;
c_expr.expr &:= "]";
c_expr.expr &:= select_value_from_rtlObjectStruct(resultType(getType(function)));
end if;
end if;
end func;
const proc: process_const_arr_idx (in reference: function, in reference: param1,
in integer: index, inout expr_type: c_expr) is func
local
var expr_type: c_param is expr_type.value;
var string: array_name is "";
var type: arrayType is void;
var string: result_name is "";
begin
prepareAnyParamTemporarys(param1, c_param, c_expr);
if c_param.result_expr <> "" then
incr(c_expr.temp_num);
result_name := "help_" & str(c_expr.temp_num);
c_expr.temp_decls &:= "rtlObjectType ";
c_expr.temp_decls &:= result_name;
c_expr.temp_decls &:= ";\n";
c_expr.temp_decls &:= c_param.result_decl;
c_expr.temp_frees &:= c_param.result_free;
c_expr.temp_to_null &:= c_param.result_to_null;
if resultType(getType(function)) in typeCategory and
typeCategory[resultType(getType(function))] in destrNecessary then
prepare_typed_result(resultType(getType(function)), c_expr);
c_expr.result_expr &:= "(";
c_expr.result_expr &:= c_param.result_intro;
c_expr.result_expr &:= c_param.result_expr;
c_expr.result_expr &:= c_param.result_finish;
c_expr.result_expr &:= ", ";
c_expr.result_expr &:= result_name;
c_expr.result_expr &:= ".value.genericValue=arrIdxTemp(&(";
c_expr.result_expr &:= c_param.result_name;
c_expr.result_expr &:= "), ";
c_expr.result_expr &:= integerLiteral(index);
c_expr.result_expr &:= "), ";
c_expr.result_expr &:= result_name;
c_expr.result_expr &:= select_value_from_rtlObjectStruct(resultType(getType(function)));
c_expr.result_expr &:= ")";
else
c_expr.expr &:= "(";
c_expr.expr &:= c_param.result_intro;
c_expr.expr &:= c_param.result_expr;
c_expr.expr &:= c_param.result_finish;
c_expr.expr &:= ", ";
c_expr.expr &:= result_name;
c_expr.expr &:= ".value.genericValue=arrIdxTemp(&(";
c_expr.expr &:= c_param.result_name;
c_expr.expr &:= "), ";
c_expr.expr &:= integerLiteral(index);
c_expr.expr &:= "), ";
c_expr.expr &:= result_name;
c_expr.expr &:= select_value_from_rtlObjectStruct(resultType(getType(function)));
c_expr.expr &:= ")";
end if;
else
incr(countOptimizations);
if isNormalVariable(param1) then
array_name := "(" & c_param.expr & ")";
else
incr(c_expr.temp_num);
array_name := "tmp_" & str(c_expr.temp_num);
if not isVarfunc(getType(function)) then
c_expr.temp_decls &:= "const_";
end if;
c_expr.temp_decls &:= "arrayType ";
c_expr.temp_decls &:= array_name;
c_expr.temp_decls &:= ";\n";
c_expr.expr &:= "(*(";
c_expr.expr &:= array_name;
c_expr.expr &:= "=";
c_expr.expr &:= c_param.expr;
c_expr.expr &:= ", &";
end if;
c_expr.expr &:= array_name;
c_expr.expr &:= "->arr[";
arrayType := getExprResultType(param1);
if array_index_check then
if arrayType in array_minIdx and arrayType in array_maxIdx then
if index < array_minIdx[arrayType] or
index > array_maxIdx[arrayType] then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= intRaiseError("INDEX_ERROR");
else
countIndexOptimizations(c_expr);
c_expr.expr &:= integerLiteral(index - array_minIdx[arrayType]);
end if;
elsif arrayType in array_minIdx and index < array_minIdx[arrayType] then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= intRaiseError("INDEX_ERROR");
else
incr(countIndexChecks);
c_expr.expr &:= "(idxChk(";
if arrayType not in array_minIdx then
c_expr.expr &:= integerLiteral(index);
c_expr.expr &:= "<";
c_expr.expr &:= array_name;
c_expr.expr &:= "->min_position || ";
end if;
c_expr.expr &:= integerLiteral(index);
c_expr.expr &:= ">";
c_expr.expr &:= array_name;
c_expr.expr &:= "->max_position) ? ";
c_expr.expr &:= intRaiseError("INDEX_ERROR");
c_expr.expr &:= " : ";
if arrayType in array_minIdx then
c_expr.expr &:= integerLiteral(index - array_minIdx[arrayType]);
else
c_expr.expr &:= integerLiteral(index);
c_expr.expr &:= "-";
c_expr.expr &:= array_name;
c_expr.expr &:= "->min_position";
end if;
c_expr.expr &:= ")";
end if;
else
incr(countSuppressedIndexChecks);
if arrayType in array_minIdx then
c_expr.expr &:= integerLiteral(index - array_minIdx[arrayType]);
else
c_expr.expr &:= integerLiteral(index);
c_expr.expr &:= "-";
c_expr.expr &:= array_name;
c_expr.expr &:= "->min_position";
end if;
end if;
c_expr.expr &:= "]";
c_expr.expr &:= select_value_from_rtlObjectStruct(resultType(getType(function)));
if not isNormalVariable(param1) then
c_expr.expr &:= "))";
end if;
end if;
end func;
const proc: process_fixlen_array_index (in reference: index,
in intRange: indexRange, in integer: minIndex, in integer: maxIndex,
inout expr_type: c_expr) is func
local
var string: index_name is "";
begin
if indexRange.maxValue < minIndex or
indexRange.minValue > maxIndex then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= intRaiseError("INDEX_ERROR");
elsif indexRange.minValue >= minIndex and
indexRange.maxValue <= maxIndex then
countIndexOptimizations(c_expr);
c_expr.expr &:= "(";
process_expr(index, c_expr);
c_expr.expr &:= ")";
if minIndex <> 0 then
c_expr.expr &:= "- ";
c_expr.expr &:= integerLiteral(minIndex);
end if;
else
incr(countIndexChecks);
if ccConf.TWOS_COMPLEMENT_INTTYPE then
index_name := getTempVariable("uintType", "idx_", "", c_expr);
c_expr.expr &:= "(";
c_expr.expr &:= index_name;
c_expr.expr &:= " = (uintType)(";
process_expr(index, c_expr);
c_expr.expr &:= ")";
if minIndex <> 0 then
c_expr.expr &:= "-(uintType)";
c_expr.expr &:= integerLiteral(minIndex);
end if;
c_expr.expr &:= ",idxChk(";
c_expr.expr &:= index_name;
c_expr.expr &:= " >= (uintType)";
c_expr.expr &:= integerLiteral(succ(maxIndex - minIndex));
c_expr.expr &:= ") ? ";
c_expr.expr &:= intRaiseError("INDEX_ERROR");
c_expr.expr &:= " : ";
c_expr.expr &:= index_name;
c_expr.expr &:= ")";
else
index_name := getParameterAsVariable("intType", "idx_", index, c_expr);
c_expr.expr &:= "(idxChk(";
c_expr.expr &:= index_name;
c_expr.expr &:= " < ";
c_expr.expr &:= integerLiteral(minIndex);
c_expr.expr &:= " || ";
c_expr.expr &:= index_name;
c_expr.expr &:= " > ";
c_expr.expr &:= integerLiteral(maxIndex);
c_expr.expr &:= ") ? ";
c_expr.expr &:= intRaiseError("INDEX_ERROR");
c_expr.expr &:= " : ";
c_expr.expr &:= index_name;
if minIndex <> 0 then
c_expr.expr &:= "- ";
c_expr.expr &:= integerLiteral(minIndex);
end if;
c_expr.expr &:= ")";
end if;
end if;
end func;
const proc: process_base_array_index (in string: array_name,
in reference: index, in intRange: indexRange, in integer: minIndex,
inout expr_type: c_expr) is func
local
var string: index_name is "";
begin
if indexRange.maxValue < minIndex then
warning(DOES_RAISE, "INDEX_ERROR", c_expr);
c_expr.expr &:= intRaiseError("INDEX_ERROR");
else
incr(countIndexChecks);
index_name := getParameterAsVariable("intType", "idx_", index, c_expr);
c_expr.expr &:= "(idxChk(";
if ccConf.TWOS_COMPLEMENT_INTTYPE and
indexRange.minValue < minIndex and
minIndex = 0 then
c_expr.expr &:= "(uintType)";
c_expr.expr &:= index_name;
c_expr.expr &:= " > (uintType)(";
c_expr.expr &:= array_name;
c_expr.expr &:= "->max_position)";
else
if indexRange.minValue < minIndex then
c_expr.expr &:= index_name;
c_expr.expr &:= " < ";
c_expr.expr &:= integerLiteral(minIndex);
c_expr.expr &:= " || ";
end if;
c_expr.expr &:= index_name;
c_expr.expr &:= " > ";
c_expr.expr &:= array_name;
c_expr.expr &:= "->max_position";
end if;
c_expr.expr &:= ") ? ";
c_expr.expr &:= intRaiseError("INDEX_ERROR");
c_expr.expr &:= " : ";
c_expr.expr &:= index_name;
if minIndex <> 0 then
c_expr.expr &:= "- ";
c_expr.expr &:= integerLiteral(minIndex);
end if;
c_expr.expr &:= ")";
end if;
end func;
const proc: process (ARR_IDX, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var expr_type: c_param is expr_type.value;
var string: array_name is "";
var type: arrayType is void;
var intRange: indexRange is intRange.value;
var string: index_name is "";
var string: result_name is "";
begin
if getType(params[1]) not in array_element then
array_element @:= [getType(params[1])] resultType(getType(function));
end if;
if getConstant(params[1], ARRAYOBJECT, evaluatedParam) then
process_const_arr_idx(function, evaluatedParam, params[3], c_expr);
elsif getConstant(params[3], INTOBJECT, evaluatedParam) then
process_const_arr_idx(function, params[1], getValue(evaluatedParam, integer), c_expr);
else
prepareAnyParamTemporarys(params[1], c_param, c_expr);
if c_param.result_expr <> "" then
incr(c_expr.temp_num);
result_name := "help_" & str(c_expr.temp_num);
c_expr.temp_decls &:= "rtlObjectType ";
c_expr.temp_decls &:= result_name;
c_expr.temp_decls &:= ";\n";
c_expr.temp_decls &:= c_param.result_decl;
c_expr.temp_frees &:= c_param.result_free;
c_expr.temp_to_null &:= c_param.result_to_null;
if resultType(getType(function)) in typeCategory and
typeCategory[resultType(getType(function))] in destrNecessary then
prepare_typed_result(resultType(getType(function)), c_expr);
c_expr.result_expr &:= "(";
c_expr.result_expr &:= c_param.result_intro;
c_expr.result_expr &:= c_param.result_expr;
c_expr.result_expr &:= c_param.result_finish;
c_expr.result_expr &:= ", ";
c_expr.result_expr &:= result_name;
c_expr.result_expr &:= ".value.genericValue=arrIdxTemp(&(";
c_expr.result_expr &:= c_param.result_name;
c_expr.result_expr &:= "), ";
getAnyParamToResultExpr(params[3], c_expr);
c_expr.result_expr &:= "), ";
c_expr.result_expr &:= result_name;
c_expr.result_expr &:= select_value_from_rtlObjectStruct(resultType(getType(function)));
c_expr.result_expr &:= ")";
else
c_expr.expr &:= "(";
c_expr.expr &:= c_param.result_intro;
c_expr.expr &:= c_param.result_expr;
c_expr.expr &:= c_param.result_finish;
c_expr.expr &:= ", ";
c_expr.expr &:= result_name;
c_expr.expr &:= ".value.genericValue=arrIdxTemp(&(";
c_expr.expr &:= c_param.result_name;
c_expr.expr &:= "), ";
process_expr(params[3], c_expr);
c_expr.expr &:= "), ";
c_expr.expr &:= result_name;
c_expr.expr &:= select_value_from_rtlObjectStruct(resultType(getType(function)));
c_expr.expr &:= ")";
end if;
else
if isNormalVariable(params[1]) then
array_name := "(" & c_param.expr & ")";
else
incr(c_expr.temp_num);
array_name := "tmp_" & str(c_expr.temp_num);
if not isVarfunc(getType(function)) then
c_expr.temp_decls &:= "const_";
end if;
c_expr.temp_decls &:= "arrayType ";
c_expr.temp_decls &:= array_name;
c_expr.temp_decls &:= ";\n";
c_expr.expr &:= "(*(";
c_expr.expr &:= array_name;
c_expr.expr &:= "=";
c_expr.expr &:= c_param.expr;
c_expr.expr &:= ", &";
end if;
c_expr.expr &:= array_name;
c_expr.expr &:= "->arr[";
arrayType := getExprResultType(params[1]);
if array_index_check then
indexRange := getIntRange(params[3]);
if arrayType in array_minIdx and arrayType in array_maxIdx then
process_fixlen_array_index(params[3], indexRange,
array_minIdx[arrayType], array_maxIdx[arrayType], c_expr);
elsif arrayType in array_minIdx then
process_base_array_index(array_name, params[3], indexRange,
array_minIdx[arrayType], c_expr);
else
incr(countIndexChecks);
if ccConf.TWOS_COMPLEMENT_INTTYPE then
index_name := getTempVariable("uintType", "idx_", "", c_expr);
c_expr.expr &:= "(";
c_expr.expr &:= index_name;
c_expr.expr &:= " = (uintType)(";
process_expr(params[3], c_expr);
c_expr.expr &:= ")-(uintType)(";
c_expr.expr &:= array_name;
c_expr.expr &:= "->min_position),idxChk(";
c_expr.expr &:= index_name;
c_expr.expr &:= " >= (uintType)(";
c_expr.expr &:= array_name;
c_expr.expr &:= "->max_position) - (uintType)(";
c_expr.expr &:= array_name;
c_expr.expr &:= "->min_position) + (uintType)1) ? ";
c_expr.expr &:= intRaiseError("INDEX_ERROR");
c_expr.expr &:= " : ";
c_expr.expr &:= index_name;
c_expr.expr &:= ")";
else
index_name := getParameterAsVariable("intType", "idx_", params[3], c_expr);
c_expr.expr &:= "(idxChk(";
c_expr.expr &:= index_name;
c_expr.expr &:= " < ";
c_expr.expr &:= array_name;
c_expr.expr &:= "->min_position || ";
c_expr.expr &:= index_name;
c_expr.expr &:= " > ";
c_expr.expr &:= array_name;
c_expr.expr &:= "->max_position) ? ";
c_expr.expr &:= intRaiseError("INDEX_ERROR");
c_expr.expr &:= " : ";
c_expr.expr &:= index_name;
c_expr.expr &:= "-";
c_expr.expr &:= array_name;
c_expr.expr &:= "->min_position)";
end if;
end if;
else
incr(countSuppressedIndexChecks);
c_expr.expr &:= "(";
process_expr(params[3], c_expr);
c_expr.expr &:= ")- ";
if arrayType in array_minIdx then
c_expr.expr &:= integerLiteral(array_minIdx[arrayType]);
else
c_expr.expr &:= array_name;
c_expr.expr &:= "->min_position";
end if;
end if;
c_expr.expr &:= "]";
c_expr.expr &:= select_value_from_rtlObjectStruct(resultType(getType(function)));
if not isNormalVariable(params[1]) then
c_expr.expr &:= "))";
end if;
end if;
end if;
end func;
const proc: process (ARR_INSERT, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var type: array_type is void;
var type: element_type is void;
var expr_type: statement is expr_type.value;
var reference: evaluatedParam is NIL;
var string: array_name is "";
var string: position_name is "";
begin
array_type := getExprResultType(params[1]);
element_type := getExprResultType(params[3]);
if array_type not in array_element then
array_element @:= [array_type] element_type;
end if;
if valueIsAtHeap(element_type) then
if array_index_check then
incr(countIndexChecks);
incr(statement.temp_num);
if getConstant(params[2], INTOBJECT, evaluatedParam) then
position_name := integerLiteral(getValue(evaluatedParam, integer));
else
position_name := "pos_" & str(statement.temp_num);
statement.temp_decls &:= "intType ";
statement.temp_decls &:= position_name;
statement.temp_decls &:= ";";
statement.expr &:= position_name;
statement.expr &:= " = ";
process_expr(params[2], statement);
statement.expr &:= ";\n";
end if;
array_name := getParameterAsReference(type_name(array_type),
"arr_", params[1], statement);
statement.expr &:= "if (idxChk(";
statement.expr &:= position_name;
statement.expr &:= " < ";
statement.expr &:= array_name;
statement.expr &:= "->min_position || ";
statement.expr &:= position_name;
statement.expr &:= " > ";
statement.expr &:= array_name;
statement.expr &:= "->max_position + 1)) {\n";
statement.expr &:= raiseError("INDEX_ERROR");
statement.expr &:= "} else {\n";
statement.expr &:= "arrInsert(&(";
statement.expr &:= array_name;
statement.expr &:= "), ";
statement.expr &:= position_name;
statement.expr &:= ", (genericType)(";
getCreatedValueAsGeneric(params[3], statement);
statement.expr &:= "));\n";
statement.expr &:= "}\n";
doLocalDeclsOfStatement(statement, c_expr);
else
setDiagnosticLine(c_expr);
c_expr.expr &:= "arrInsert(&(";
process_expr(params[1], c_expr);
c_expr.expr &:= "), ";
process_expr(params[2], c_expr);
c_expr.expr &:= ", (genericType)(";
getCreatedValueAsGeneric(params[3], c_expr);
c_expr.expr &:= "));\n";
end if;
else
setDiagnosticLine(c_expr);
c_expr.expr &:= "arrInsert(&(";
process_expr(params[1], c_expr);
c_expr.expr &:= "), ";
process_expr(params[2], c_expr);
c_expr.expr &:= ", ";
getGenericValue(params[3], c_expr);
c_expr.expr &:= ");\n";
end if;
end func;
const proc: process (ARR_INSERT_ARRAY, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var type: param3_type is void;
var expr_type: statement is expr_type.value;
begin
param3_type := getExprResultType(params[3]);
if valueIsAtHeap(array_element[param3_type]) then
statement.expr &:= "arrInsertArrayTemp(&(";
process_expr(params[1], statement);
statement.expr &:= "), ";
process_expr(params[2], statement);
statement.expr &:= ", ";
getTemporaryToExpr(params[3], statement);
statement.expr &:= ");\n";
else
statement.expr &:= "arrInsertArray(&(";
process_expr(params[1], statement);
statement.expr &:= "), ";
process_expr(params[2], statement);
statement.expr &:= ", ";
getAnyParamToExpr(params[3], statement);
statement.expr &:= ");\n";
end if;
doLocalDeclsOfStatement(statement, c_expr);
end func;
const proc: process (ARR_LNG, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var string: array_name is "";
begin
if getConstant(params[1], ARRAYOBJECT, evaluatedParam) then
incr(countOptimizations);
c_expr.expr &:= str(arrayMaxIdx(evaluatedParam) - arrayMinIdx(evaluatedParam) + 1);
if evaluatedParam in const_table then
c_expr.expr &:= " /* length(arr[";
c_expr.expr &:= str(const_table[evaluatedParam]);
c_expr.expr &:= "]) */";
else
c_expr.expr &:= " /* length(array) */";
end if;
else
c_expr.expr &:= "(";
array_name := getParameterAsVariable("const_arrayType", "tmp_", params[1], c_expr);
c_expr.expr &:= array_name;
c_expr.expr &:= "->max_position - ";
c_expr.expr &:= array_name;
c_expr.expr &:= "->min_position + 1)";
end if;
end func;
const proc: process (ARR_MAXIDX, 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], ARRAYOBJECT, evaluatedParam) then
incr(countOptimizations);
c_expr.expr &:= str(arrayMaxIdx(evaluatedParam));
if evaluatedParam in const_table then
c_expr.expr &:= " /* maxIdx(arr[";
c_expr.expr &:= str(const_table[evaluatedParam]);
c_expr.expr &:= "]) */";
else
c_expr.expr &:= " /* maxIdx(array) */";
end if;
else
c_expr.expr &:= "(";
getAnyParamToExpr(params[1], c_expr);
c_expr.expr &:= ")->max_position";
end if;
end func;
const proc: process (ARR_MINIDX, 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], ARRAYOBJECT, evaluatedParam) then
incr(countOptimizations);
c_expr.expr &:= str(arrayMinIdx(evaluatedParam));
if evaluatedParam in const_table then
c_expr.expr &:= " /* minIdx(arr[";
c_expr.expr &:= str(const_table[evaluatedParam]);
c_expr.expr &:= "]) */";
else
c_expr.expr &:= " /* minIdx(array) */";
end if;
else
c_expr.expr &:= "(";
getAnyParamToExpr(params[1], c_expr);
c_expr.expr &:= ")->min_position";
end if;
end func;
const proc: process (ARR_PUSH, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var expr_type: c_param1 is expr_type.value;
var expr_type: c_param3 is expr_type.value;
begin
if getType(params[1]) not in array_element then
array_element @:= [getType(params[1])] getType(params[3]);
end if;
process_expr(params[1], c_param1);
c_param3.temp_num := c_param1.temp_num;
getGenericTemporaryToResultExpr(params[3], c_param3);
incr(c_param3.temp_num);
if has_temp_values(c_param3) then
c_expr.expr &:= "{\n";
appendWithDiagnostic(c_param1.temp_decls, c_expr);
appendWithDiagnostic(c_param3.temp_decls, c_expr);
appendWithDiagnostic(c_param1.temp_assigns, c_expr);
appendWithDiagnostic(c_param3.temp_assigns, c_expr);
end if;
setDiagnosticLine(c_expr);
c_expr.expr &:= "arrPush(&(";
c_expr.expr &:= c_param1.expr;
c_expr.expr &:= "), (genericType)(";
c_expr.expr &:= c_param3.result_expr;
c_expr.expr &:= "));\n";
if has_temp_values(c_param3) then
appendWithDiagnostic(c_param1.temp_frees, c_expr);
appendWithDiagnostic(c_param3.temp_frees, c_expr);
c_expr.expr &:= "}\n";
end if;
end func;
const proc: process (ARR_RANGE, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var type: param_type is void;
var expr_type: c_param is expr_type.value;
var string: array_name is "";
begin
param_type := getExprResultType(params[1]);
prepare_typed_result(param_type, c_expr);
prepareAnyParamTemporarys(params[1], c_param, c_expr);
if c_param.result_expr <> "" then
c_expr.temp_decls &:= c_param.result_decl;
c_expr.temp_frees &:= c_param.result_free;
c_expr.temp_to_null &:= c_param.result_to_null;
c_expr.result_expr := "(";
c_expr.result_expr &:= c_param.result_intro;
c_expr.result_expr &:= c_param.result_expr;
c_expr.result_expr &:= c_param.result_finish;
c_expr.result_expr &:= ", arrRangeTemp(&(";
c_expr.result_expr &:= c_param.result_name;
c_expr.result_expr &:= "), ";
getStdParamToResultExpr(params[3], c_expr);
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(params[5], c_expr);
c_expr.result_expr &:= "))";
elsif valueIsAtHeap(array_element[param_type]) then
incr(c_expr.temp_num);
array_name := "tmp_" & str(c_expr.temp_num);
c_expr.temp_decls &:= "arrayType ";
c_expr.temp_decls &:= array_name;
c_expr.temp_decls &:= "=NULL;\n";
c_expr.temp_frees &:= "if (";
c_expr.temp_frees &:= array_name;
c_expr.temp_frees &:= " != NULL) {arrFree(";
c_expr.temp_frees &:= array_name;
c_expr.temp_frees &:= ");}\n";
c_expr.temp_to_null &:= array_name;
c_expr.temp_to_null &:= "=NULL;\n";
c_expr.result_expr := "(";
c_expr.result_expr &:= array_name;
c_expr.result_expr &:= "=arrRange(";
c_expr.result_expr &:= c_param.expr;
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(params[3], c_expr);
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(params[5], c_expr);
c_expr.result_expr &:= "), ";
typeCategory @:= [param_type] ARRAYOBJECT;
process_create_declaration(param_type, global_c_expr);
process_create_call(param_type, array_name, c_expr.result_expr);
c_expr.result_expr &:= ")";
else
c_expr.result_expr := "arrRange(";
c_expr.result_expr &:= c_param.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 (ARR_REMOVE, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var type: proc_type is void;
var type: result_type is void;
var string: temp_name is "";
begin
proc_type := getType(function);
result_type := resultType(proc_type);
if valueIsAtHeap(result_type) then
prepare_typed_result(result_type, c_expr);
temp_name := beginCastGenericToResultExpr(result_type, c_expr);
c_expr.result_expr &:= "arrRemove(&(";
getStdParamToResultExpr(params[1], c_expr);
c_expr.result_expr &:= "), ";
getStdParamToResultExpr(params[2], c_expr);
c_expr.result_expr &:= ")";
endCastGenericToResultExpr(result_type, temp_name, c_expr);
else
temp_name := beginCastGeneric(result_type, c_expr);
c_expr.expr &:= "arrRemove(&(";
process_expr(params[1], c_expr);
c_expr.expr &:= "), ";
process_expr(params[2], c_expr);
c_expr.expr &:= ")";
endCastGeneric(result_type, temp_name, c_expr);
end if;
end func;
const proc: process (ARR_REMOVE_ARRAY, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var type: param_type is void;
begin
param_type := getExprResultType(params[1]);
prepare_typed_result(param_type, c_expr);
c_expr.result_expr := "arrRemoveArray(&(";
getStdParamToResultExpr(params[1], c_expr);
c_expr.result_expr &:= "), ";
getStdParamToResultExpr(params[2], c_expr);
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(params[3], c_expr);
c_expr.result_expr &:= ")";
end func;
const proc: process (ARR_SORT, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
declare_func_pointer_if_necessary(params[2], global_c_expr);
prepare_typed_result(getExprResultType(params[1]), c_expr);
c_expr.result_expr := "arrSort(";
getTemporaryToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ", (compareType)(";
getStdParamToResultExpr(params[2], c_expr);
c_expr.result_expr &:= "))";
end func;
const proc: process (ARR_SORT_REVERSE, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
begin
declare_func_pointer_if_necessary(params[2], global_c_expr);
prepare_typed_result(getExprResultType(params[1]), c_expr);
c_expr.result_expr := "arrSortReverse(";
getTemporaryToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ", (compareType)(";
getStdParamToResultExpr(params[2], c_expr);
c_expr.result_expr &:= "))";
end func;
const proc: process (ARR_SUBARR, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var type: param_type is void;
var expr_type: c_param is expr_type.value;
var string: array_name is "";
begin
param_type := getExprResultType(params[1]);
prepare_typed_result(param_type, c_expr);
prepareAnyParamTemporarys(params[1], c_param, c_expr);
if c_param.result_expr <> "" then
c_expr.temp_decls &:= c_param.result_decl;
c_expr.temp_frees &:= c_param.result_free;
c_expr.temp_to_null &:= c_param.result_to_null;
c_expr.result_expr := "(";
c_expr.result_expr &:= c_param.result_intro;
c_expr.result_expr &:= c_param.result_expr;
c_expr.result_expr &:= c_param.result_finish;
c_expr.result_expr &:= ", arrSubarrTemp(&(";
c_expr.result_expr &:= c_param.result_name;
c_expr.result_expr &:= "), ";
getStdParamToResultExpr(params[3], c_expr);
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(params[5], c_expr);
c_expr.result_expr &:= "))";
elsif valueIsAtHeap(array_element[param_type]) then
incr(c_expr.temp_num);
array_name := "tmp_" & str(c_expr.temp_num);
c_expr.temp_decls &:= "arrayType ";
c_expr.temp_decls &:= array_name;
c_expr.temp_decls &:= "=NULL;\n";
c_expr.temp_frees &:= "if (";
c_expr.temp_frees &:= array_name;
c_expr.temp_frees &:= " != NULL) {arrFree(";
c_expr.temp_frees &:= array_name;
c_expr.temp_frees &:= ");}\n";
c_expr.temp_to_null &:= array_name;
c_expr.temp_to_null &:= "=NULL;\n";
c_expr.result_expr := "(";
c_expr.result_expr &:= array_name;
c_expr.result_expr &:= "=arrSubarr(";
c_expr.result_expr &:= c_param.expr;
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(params[3], c_expr);
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(params[5], c_expr);
c_expr.result_expr &:= "), ";
typeCategory @:= [param_type] ARRAYOBJECT;
process_create_declaration(param_type, global_c_expr);
process_create_call(param_type, array_name, c_expr.result_expr);
c_expr.result_expr &:= ")";
else
c_expr.result_expr := "arrSubarr(";
c_expr.result_expr &:= c_param.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 (ARR_TAIL, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var type: param_type is void;
var expr_type: c_param is expr_type.value;
var string: array_name is "";
begin
param_type := getExprResultType(params[1]);
prepare_typed_result(param_type, c_expr);
prepareAnyParamTemporarys(params[1], c_param, c_expr);
if c_param.result_expr <> "" then
c_expr.temp_decls &:= c_param.result_decl;
c_expr.temp_frees &:= c_param.result_free;
c_expr.temp_to_null &:= c_param.result_to_null;
c_expr.result_expr := "(";
c_expr.result_expr &:= c_param.result_intro;
c_expr.result_expr &:= c_param.result_expr;
c_expr.result_expr &:= c_param.result_finish;
c_expr.result_expr &:= ", arrTailTemp(&(";
c_expr.result_expr &:= c_param.result_name;
c_expr.result_expr &:= "), ";
getStdParamToResultExpr(params[3], c_expr);
c_expr.result_expr &:= "))";
elsif valueIsAtHeap(array_element[param_type]) then
incr(c_expr.temp_num);
array_name := "tmp_" & str(c_expr.temp_num);
c_expr.temp_decls &:= "arrayType ";
c_expr.temp_decls &:= array_name;
c_expr.temp_decls &:= "=NULL;\n";
c_expr.temp_frees &:= "if (";
c_expr.temp_frees &:= array_name;
c_expr.temp_frees &:= " != NULL) {arrFree(";
c_expr.temp_frees &:= array_name;
c_expr.temp_frees &:= ");}\n";
c_expr.temp_to_null &:= array_name;
c_expr.temp_to_null &:= "=NULL;\n";
c_expr.result_expr := "(";
c_expr.result_expr &:= array_name;
c_expr.result_expr &:= "=arrTail(";
c_expr.result_expr &:= c_param.expr;
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(params[3], c_expr);
c_expr.result_expr &:= "), ";
typeCategory @:= [param_type] ARRAYOBJECT;
process_create_declaration(param_type, global_c_expr);
process_create_call(param_type, array_name, c_expr.result_expr);
c_expr.result_expr &:= ")";
else
c_expr.result_expr := "arrTail(";
c_expr.result_expr &:= c_param.expr;
c_expr.result_expr &:= ", ";
getStdParamToResultExpr(params[3], c_expr);
c_expr.result_expr &:= ")";
end if;
end func;
const proc: two_dimensional_times_optimization (in type: result_type,
in reference: factor1, in reference: factor2, inout expr_type: c_expr) is func
local
var string: factor1Name is "";
var string: factor2Name is "";
var string: resultName is "";
begin
incr(countOptimizations);
prepare_typed_result(result_type, c_expr);
c_expr.result_expr := "({";
factor1Name := defineTempVariable("intType", "factor1_", c_expr);
factor2Name := getParameterInResultStatement("intType",
"factor2_", factor2, c_expr);
resultName := defineTempVariable("arrayType", "times_res_", c_expr);
c_expr.result_expr &:= factor1Name;
c_expr.result_expr &:= "=(";
getStdParamToResultExpr(factor1, c_expr);
c_expr.result_expr &:= ");\n";
c_expr.result_expr &:= resultName;
c_expr.result_expr &:= "=arrMalloc(1, ";
c_expr.result_expr &:= factor1Name;
c_expr.result_expr &:= ");\n";
c_expr.result_expr &:= "while (";
c_expr.result_expr &:= factor1Name;
c_expr.result_expr &:= "!=0) {\n";
c_expr.result_expr &:= factor1Name;
c_expr.result_expr &:= "--;\n";
c_expr.result_expr &:= resultName;
c_expr.result_expr &:= "->arr[";
c_expr.result_expr &:= factor1Name;
c_expr.result_expr &:= "].value.arrayValue=arrTimes(1, ";
c_expr.result_expr &:= factor2Name;
c_expr.result_expr &:= ", 0);\n";
c_expr.result_expr &:= "}\n";
c_expr.result_expr &:= resultName;
c_expr.result_expr &:= ";})";
end func;
const proc: process (ARR_TIMES, in reference: function,
in ref_list: params, inout expr_type: c_expr) is func
local
var reference: evaluatedParam is NIL;
var type: result_type is void;
var type: element_type is void;
begin
result_type := resultType(getType(function));
typeCategory @:= [result_type] ARRAYOBJECT;
if getConstant(params[1], INTOBJECT, evaluatedParam) and
getValue(evaluatedParam, integer) = 0 then
incr(countOptimizations);
prepare_typed_result(result_type, c_expr);
c_expr.result_expr := "arrMalloc(1, 0)";
elsif inlineFunctions and ccConf.STMT_BLOCK_IN_PARENTHESES_OK and
isActionExpression(params[3], "ARR_TIMES") and
getConstant(getActionParameter(params[3], 3), INTOBJECT, evaluatedParam) and
getValue(evaluatedParam, integer) = 0 then
two_dimensional_times_optimization(result_type, params[1],
getActionParameter(params[3], 1), c_expr);
else
element_type := getType(formalParams(function)[3]);
if element_type in typeCategory and
typeCategory[element_type] in simpleValueType then
incr(countOptimizations);
prepare_typed_result(result_type, c_expr);
c_expr.result_expr := "arrTimes(1, ";
getStdParamToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ", ";
getGenericValueToResultExpr(params[3], c_expr);
c_expr.result_expr &:= ")";
else
declare_times_prototype(result_type, global_c_expr);
prepare_typed_result(result_type, c_expr);
c_expr.result_expr := "times_";
c_expr.result_expr &:= str(typeNumber(result_type));
c_expr.result_expr &:= "(";
getStdParamToResultExpr(params[1], c_expr);
c_expr.result_expr &:= ", ";
getAnyParamToResultExpr(params[3], c_expr);
c_expr.result_expr &:= ")";
end if;
end if;
end func;